add dragging to catalog contents
This commit is contained in:
@ -1,41 +1,308 @@
|
||||
<template>
|
||||
<v-container fluid grid-list-lg ma-0 pa-1>
|
||||
|
||||
<v-layout row fill-height>
|
||||
<v-btn @click="step = 1">Add products</v-btn>
|
||||
<v-btn @click="step = 3">Auto arrange</v-btn>
|
||||
</v-layout>
|
||||
|
||||
<v-flex xs4>
|
||||
<SectionList/>
|
||||
<v-layout row fill-height>
|
||||
<v-flex xs3>
|
||||
<v-card>
|
||||
<v-toolbar dense>
|
||||
<v-toolbar-title>Sections</v-toolbar-title>
|
||||
</v-toolbar>
|
||||
|
||||
<div id="sections" class="list-group">
|
||||
<v-list-tile
|
||||
v-for="item in sections"
|
||||
:key="item.id"
|
||||
class="v-list__tile list-group-item list-item"
|
||||
v-bind:class="{'selected': selected === item}"
|
||||
>
|
||||
<v-list-tile-content class="section-parent">
|
||||
<v-list-tile-title v-html="item.name"></v-list-tile-title>
|
||||
<v-list-tile-sub-title class="section-drop" :section-id="item.id"></v-list-tile-sub-title>
|
||||
</v-list-tile-content>
|
||||
|
||||
</v-list-tile>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-flex>
|
||||
|
||||
<v-flex xs4>
|
||||
<ProductFamilyList/>
|
||||
<v-flex xs3>
|
||||
<v-card>
|
||||
<v-toolbar dense>
|
||||
<v-toolbar-title>Models</v-toolbar-title>
|
||||
</v-toolbar>
|
||||
|
||||
<div id="models" class="list-group">
|
||||
<div v-for="item in selectedModels" :key="item.model" class="v-list__tile list-item">
|
||||
<v-list-tile-title v-html="item.name"></v-list-tile-title>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
</v-flex>
|
||||
|
||||
<v-flex xs4>
|
||||
<MaterialList/>
|
||||
<v-flex xs3>
|
||||
<v-card>
|
||||
<v-toolbar dense>
|
||||
<v-toolbar-title>Materials</v-toolbar-title>
|
||||
</v-toolbar>
|
||||
|
||||
<div id="materials" class="list-group">
|
||||
<div
|
||||
v-for="item in selectedMaterials"
|
||||
:key="item.id"
|
||||
class="v-list__tile list-item"
|
||||
>
|
||||
<v-list-tile-title v-html="item.id"></v-list-tile-title>
|
||||
</div>
|
||||
</div>
|
||||
</v-card>
|
||||
|
||||
</v-flex>
|
||||
|
||||
<v-flex xs3>
|
||||
<RawDisplayer :value="selectedMaterials" title="mats" />
|
||||
</v-flex>
|
||||
|
||||
</v-layout>
|
||||
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SectionList from './SectionList'
|
||||
import ProductFamilyList from './ProductFamilyList'
|
||||
// import ModelList from './ModelList'
|
||||
import MaterialList from './MaterialList'
|
||||
import Sortable from 'sortablejs'
|
||||
import { mapState, mapGetters, mapActions } from 'vuex'
|
||||
import arrayMove from 'array-move'
|
||||
import RawDisplayer from './RawDisplayer'
|
||||
import { paginateModels } from '@/pagination'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SectionList,
|
||||
ProductFamilyList,
|
||||
// ModelList,
|
||||
MaterialList,
|
||||
RawDisplayer,
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
})
|
||||
// NOTE do we need?
|
||||
'placeholderText': 'placeholder',
|
||||
// NOTE do we need?
|
||||
'selected': null,
|
||||
}),
|
||||
computed: {
|
||||
...mapState([
|
||||
'catalog',
|
||||
'materials',
|
||||
]),
|
||||
...mapGetters([
|
||||
'section',
|
||||
'sections',
|
||||
'selectedSection',
|
||||
'selectedModel',
|
||||
'sectionModels',
|
||||
'modelMaterials',
|
||||
'material',
|
||||
]),
|
||||
selectedModels() {
|
||||
let section = this.selectedSection
|
||||
return this.sectionModels(section)
|
||||
},
|
||||
selectedMaterials() {
|
||||
let model = this.selectedModel
|
||||
return this.modelMaterials(model)
|
||||
},
|
||||
},
|
||||
/*
|
||||
watch: {
|
||||
catalog: function(cat) {
|
||||
console.log('catalog changed')
|
||||
addSectionDrops(this)
|
||||
},
|
||||
},
|
||||
*/
|
||||
methods: {
|
||||
reorderModel: function(fromIndex, toIndex) {
|
||||
let models = this.selectedModels
|
||||
arrayMove.mutate(models, fromIndex, toIndex)
|
||||
let pages = paginateModels(models)
|
||||
this.setSectionPages({ section: this.selectedSection, pages: pages })
|
||||
},
|
||||
|
||||
reorderMaterial: function(fromIndex, toIndex) {
|
||||
let mats = this.selectedMaterials
|
||||
arrayMove.mutate(mats, fromIndex, toIndex)
|
||||
this.setModelMaterials({ model: this.selectedModel, materials: mats })
|
||||
},
|
||||
/*
|
||||
groupByModel: function(materials) {
|
||||
let models = []
|
||||
|
||||
for (let mat of materials) {
|
||||
let model = models.length > 0 ? models[models.length - 1] : null
|
||||
|
||||
if (model === null || model.id !== mat.model) {
|
||||
// new model
|
||||
model = { id: mat.model,
|
||||
name: mat.name,
|
||||
materials: [mat.id] }
|
||||
models.push(model)
|
||||
} else {
|
||||
// add to existing
|
||||
model.materials.push(mat.id)
|
||||
}
|
||||
}
|
||||
|
||||
return models
|
||||
},
|
||||
*/
|
||||
...mapActions([
|
||||
'reorderSection',
|
||||
'setSectionPages',
|
||||
'setModelMaterials',
|
||||
'moveModelToSection',
|
||||
'moveMaterialToSection',
|
||||
]),
|
||||
},
|
||||
mounted: function() {
|
||||
let me = this
|
||||
|
||||
// reordering of sections
|
||||
Sortable.create(document.getElementById('sections'), {
|
||||
group: {
|
||||
name: 'sections',
|
||||
},
|
||||
animation: 150,
|
||||
onEnd: function(evt) {
|
||||
me.reorderSection({ from: evt.oldIndex, to: evt.newIndex })
|
||||
},
|
||||
})
|
||||
|
||||
// reordering of models
|
||||
Sortable.create(document.getElementById('models'), {
|
||||
group: {
|
||||
name: 'models',
|
||||
},
|
||||
animation: 150,
|
||||
onStart: function(evt) {
|
||||
addSectionDrops(me)
|
||||
},
|
||||
onEnd: function(evt) {
|
||||
if (evt.from === evt.to) {
|
||||
me.reorderModel(evt.oldIndex, evt.newIndex)
|
||||
} else {
|
||||
// dropped on a section.
|
||||
let models = me.selectedModels
|
||||
let model = models[evt.oldIndex]
|
||||
|
||||
let sectionID = Number(evt.to.getAttribute('section-id'))
|
||||
let newSection = me.section(sectionID)
|
||||
|
||||
if (me.selectedSection.id !== newSection.id) {
|
||||
me.moveModelToSection({ model: model,
|
||||
oldSection: me.selectedSection,
|
||||
newSection: newSection })
|
||||
} else {
|
||||
console.log('not moving to same section')
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
// reordering of materials
|
||||
Sortable.create(document.getElementById('materials'), {
|
||||
group: {
|
||||
name: 'materials',
|
||||
},
|
||||
animation: 150,
|
||||
onStart: function(evt) {
|
||||
addSectionDrops(me)
|
||||
},
|
||||
onEnd: function(evt) {
|
||||
if (evt.from === evt.to) {
|
||||
me.reorderMaterial(evt.oldIndex, evt.newIndex)
|
||||
} else {
|
||||
// dropped on a section.
|
||||
let mats = me.selectedMaterials
|
||||
let mat = mats[evt.oldIndex]
|
||||
|
||||
let sectionID = Number(evt.to.getAttribute('section-id'))
|
||||
let newSection = me.section(sectionID)
|
||||
|
||||
if (me.selectedSection.id !== newSection.id) {
|
||||
me.moveMaterialToSection({ material: mat,
|
||||
oldModel: me.selectedModel,
|
||||
newSection: newSection })
|
||||
} else {
|
||||
console.log('not moving to same section')
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
function addSectionDrops(myvue) {
|
||||
// make sure our section drop targets are set up
|
||||
// after catalog load or section add
|
||||
|
||||
// drop model or material into a section
|
||||
var drops = document.getElementsByClassName('section-drop')
|
||||
for (var i = 0; i < drops.length; ++i) {
|
||||
if (!drops[i].getAttribute('drop-ready')) {
|
||||
drops[i].setAttribute('drop-ready', true)
|
||||
|
||||
Sortable.create(drops[i], {
|
||||
group: {
|
||||
name: 'section-drops',
|
||||
pull: false,
|
||||
put: function(to, from) {
|
||||
// don't allow drop on section where it already lives
|
||||
let oldSectionID = myvue.selectedSection.id
|
||||
let newSectionID = to.el.getAttribute('section-id')
|
||||
if (Number(oldSectionID) === Number(newSectionID)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// allow drop from anything but another section
|
||||
return from.options.group.name !== 'sections'
|
||||
},
|
||||
},
|
||||
animation: 150,
|
||||
// (actual drop is handled in the originating list)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.selected {
|
||||
background-color: purple;
|
||||
}
|
||||
|
||||
.sortable-chosen {
|
||||
color: black;
|
||||
background-color: #fddd04;
|
||||
}
|
||||
|
||||
.sortable-ghost {
|
||||
background-color: #bababa;
|
||||
}
|
||||
|
||||
.section-parent {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.section-drop {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user