cat editor: add 'add product' dialog

This commit is contained in:
Seth Ladygo
2019-05-17 02:20:20 -07:00
parent d1aca308ba
commit ebd003683e
4 changed files with 251 additions and 13 deletions

View File

@ -0,0 +1,72 @@
<template>
<div class="text-xs-center">
<v-dialog v-model="show" width="250">
<v-card>
<v-card class="subheading font-weight-bold ma-0 pa-0 white--text" color="keen_dark_grey">
<v-card-title class="ma-0 pa-2 pl-3">
Add Materials
<v-spacer></v-spacer>
<v-icon color="white" @click="show = false">clear</v-icon>
</v-card-title>
</v-card>
<v-card-text>
<p>Enter lots of material numbers to add to the catalog</p>
<v-textarea
v-model="text"
autofocus
label="Material numbers"
placeholder="1001234
1001235..."
clearable
></v-textarea>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn small flat @click="show = false">Cancel</v-btn>
<v-spacer></v-spacer>
<v-btn small color="primary" class="black--text" @click="doAdd()">Add</v-btn>
<v-spacer></v-spacer>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
data: () => ({
text: null,
}),
props: {
value: Boolean,
},
computed: {
show: {
get() {
return this.value
},
set(value) {
this.$emit('input', value)
}
},
},
methods: {
...mapActions([
'fetchProducts',
]),
doAdd: function() {
console.log('adding text', this.text)
this.show = false
this.fetchProducts(this.text)
},
},
}
</script>

View File

@ -2,8 +2,7 @@
<v-container fluid grid-list-lg ma-0 pa-1> <v-container fluid grid-list-lg ma-0 pa-1>
<v-layout row fill-height> <v-layout row fill-height>
<v-btn @click="step = 1">Add products</v-btn> <v-btn @click="showAddProductDialog = true">Add products</v-btn>
<v-btn @click="step = 3">Auto arrange</v-btn>
</v-layout> </v-layout>
<v-layout row fill-height> <v-layout row fill-height>
@ -126,6 +125,8 @@
</v-layout> </v-layout>
<AddProductDialog v-model="showAddProductDialog"/>
</v-container> </v-container>
</template> </template>
@ -136,18 +137,17 @@ import arrayMove from 'array-move'
//import RawDisplayer from './RawDisplayer' //import RawDisplayer from './RawDisplayer'
import { paginateModels } from '@/pagination' import { paginateModels } from '@/pagination'
import DragListHeading from './DragListHeading' import DragListHeading from './DragListHeading'
import AddProductDialog from './AddProductDialog'
export default { export default {
components: { components: {
DragListHeading, DragListHeading,
AddProductDialog,
//RawDisplayer, //RawDisplayer,
}, },
data: () => ({ data: () => ({
// NOTE do we need? showAddProductDialog: false,
'placeholderText': 'placeholder',
// NOTE do we need?
'selected': null,
}), }),
computed: { computed: {
...mapState([ ...mapState([
@ -186,13 +186,23 @@ export default {
this.$store.dispatch('selectModel', id) this.$store.dispatch('selectModel', id)
}, },
sectionModelCount(sectionID) {
let section = this.section(sectionID)
if (section) {
let models = this.sectionModels(section) || []
return models.length
} else {
return 0
}
},
sectionListItemClasses: function(id, hovering) { sectionListItemClasses: function(id, hovering) {
if (id === this.selectedSectionID) { if (id === this.selectedSectionID) {
return 'list-item primary' return 'list-item primary'
} else if (hovering) { } else if (hovering) {
return 'list-item grey lighten-4' return 'list-item grey lighten-4'
} else { } else {
return '' return 'list-item'
} }
}, },
@ -395,6 +405,12 @@ function addSectionDrops(myvue) {
} }
.list-item { .list-item {
//border-bottom: 1px solid #ddd; background-color: white;
border-bottom: 1px solid #ddd;
}
.list-group {
background-color: #f0f0ff;
min-height: 200px;
} }
</style> </style>

View File

@ -2,7 +2,7 @@ import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import arrayMove from 'array-move' import arrayMove from 'array-move'
import axios from 'axios' import axios from 'axios'
import { paginateModels } from '@/pagination' import { paginateModels, sectionTitle, extendModelFromMaterial } from '@/pagination'
Vue.use(Vuex) Vue.use(Vuex)
@ -16,6 +16,7 @@ export const store = new Vuex.Store({
selectedMaterial: null, selectedMaterial: null,
loadingCatalog: false, loadingCatalog: false,
savingCatalog: false, savingCatalog: false,
loadingProducts: false,
}, },
getters: { getters: {
@ -41,6 +42,18 @@ export const store = new Vuex.Store({
} }
}, },
nextSectionID: state => {
if (state.catalog != null) {
let id = 0
for (let section of state.catalog.sections) {
id = Math.max(id, section.id)
}
return id + 1
} else {
return -1
}
},
selectedSection: (state, getters) => { selectedSection: (state, getters) => {
if (state.catalog && state.selectedSectionID) { if (state.catalog && state.selectedSectionID) {
return getters.section(state.selectedSectionID) return getters.section(state.selectedSectionID)
@ -69,9 +82,7 @@ export const store = new Vuex.Store({
// add extra info from a material // add extra info from a material
let material = getters.material(model.ids[0]) let material = getters.material(model.ids[0])
if (material) { if (material) {
model['name'] = material.name model = extendModelFromMaterial(material, model)
model['model'] = material.model
model['family'] = material.family
} else { } else {
console.log('no material found for id', model.ids[0]) console.log('no material found for id', model.ids[0])
} }
@ -152,6 +163,11 @@ export const store = new Vuex.Store({
savingCatalog(state) { savingCatalog(state) {
return state.savingCatalog return state.savingCatalog
}, },
loadingProducts(state) {
return state.loadingProducts
},
}, },
mutations: { mutations: {
// //
@ -170,6 +186,10 @@ export const store = new Vuex.Store({
// manipulation // manipulation
// //
addSection(state, section) {
state.catalog.sections.push(section)
},
reorderSection(state, { from, to }) { reorderSection(state, { from, to }) {
if (from === to) return if (from === to) return
state.catalog.sections = arrayMove(state.catalog.sections, from, to) state.catalog.sections = arrayMove(state.catalog.sections, from, to)
@ -235,6 +255,10 @@ export const store = new Vuex.Store({
state.savingCatalog = value state.savingCatalog = value
}, },
setLoadingProducts(state, value) {
state.loadingProducts = value
},
setCatalogProperty(state, { key, value }) { setCatalogProperty(state, { key, value }) {
console.log('mutation set prop', key, value) console.log('mutation set prop', key, value)
if (state.catalog) { if (state.catalog) {
@ -325,6 +349,73 @@ export const store = new Vuex.Store({
commit('setSectionPages', { section: newSection, pages: newPages }) commit('setSectionPages', { section: newSection, pages: newPages })
}, },
addMaterialToCatalog({ commit, getters, state }, material) {
if (!state.catalog) {
console.log('no catalog to add materials to')
return
}
// ensure material, not just id
if (typeof material === 'string' || typeof material === 'number') {
material = getters.material(material)
}
let foundSection = null
let foundModels = null
// look for an existing model in all our sections.
// add to first one found.
for (let section of state.catalog.sections) {
let models = getters.sectionModels(section)
let existingModel = models.find(m => m.model === material.model)
console.log('section', section.id, 'existing model search', existingModel)
if (existingModel) {
// prevent duplicates here, but also allow adding the same
// id again to a catalog. put in a new section so it can be
// placed elsewhere?
let existingMaterial = existingModel.ids.find(m => m.id === material.id)
console.log('model', existingModel.model, 'existing material', existingMaterial)
if (!existingMaterial) {
existingModel.ids.push(material.id)
foundSection = section
foundModels = models
} else {
console.log('skip duplicate')
}
break
}
}
if (!foundSection) {
// see if we match a section, add a new model at the end
let title = sectionTitle(material)
for (let section of state.catalog.sections) {
if (title === section.name) {
let newModel = extendModelFromMaterial(material)
let models = getters.sectionModels(section)
models.push(newModel)
foundSection = section
break
}
}
}
// still nothing, add into a new section
if (!foundSection) {
let title = sectionTitle(material)
let newModel = extendModelFromMaterial(material)
foundModels = [newModel]
foundSection = {
'id': getters.nextSectionID,
'name': title,
}
commit('addSection', foundSection)
}
let pages = paginateModels(foundModels)
commit('setSectionPages', { section: foundSection, pages: pages })
},
// SET_CAT_SECTIONS: (context, payload) => { // SET_CAT_SECTIONS: (context, payload) => {
// context.commit('SET_CAT_SECTIONS', payload) // context.commit('SET_CAT_SECTIONS', payload)
// }, // },
@ -356,6 +447,32 @@ export const store = new Vuex.Store({
commit('setCatalog', {}) commit('setCatalog', {})
}, },
async fetchProducts({ commit, dispatch }, text) {
commit('setLoadingProducts', true)
axios.post('/api/v1/products/search', text)
.then(function(response) {
commit('setLoadingProducts', false)
if (response.data && response.data.missing) {
// TODO display these somehow
console.log('missing ids:', response.data.missing)
}
if (response.data && response.data.found) {
console.log('found prods:', response.data.found)
commit('addMaterialsToLibrary', response.data.found)
for (let material of response.data.found) {
dispatch('addMaterialToCatalog', material)
}
}
})
.catch(function(error) {
commit('setLoadingProducts', false)
// TODO set saving error property
console.error('error searching for prods: ', error)
})
},
async loadCatalog({ commit }, id) { async loadCatalog({ commit }, id) {
try { try {
commit('setLoadingCatalog', true) commit('setLoadingCatalog', true)

View File

@ -43,3 +43,36 @@ export function sectionModels(section) {
return models return models
} }
export function sectionTitle(material) {
// "Trailhead (Men)"
if (material) {
return `${material.category} (${material.gender})`
} else {
return '(unknown)'
}
}
// add properties from the material to the model,
// creating it if necessary.
export function extendModelFromMaterial(material, model = {}) {
if (material) {
if (!model['name']) {
// don't overwrite possibly overridden value
model['name'] = material.name
}
model['model'] = material.model
model['family'] = material.family
model['gender'] = material.gender
model['category'] = material.category
// make sure the material id is in the list
let ids = model['ids'] || []
if (!ids.includes(material.id)) {
ids.push(material.id)
model['ids'] = ids
}
}
return model
}