From 26a03fc63fee4f1d3cbad7cb017ae4273a82b455 Mon Sep 17 00:00:00 2001 From: Seth Ladygo Date: Sat, 11 May 2019 01:37:27 -0700 Subject: [PATCH] add dragging to catalog contents --- cateditor/src/components/CatalogContents.vue | 297 ++++++++++++++++++- cateditor/src/pages/editor/store/index.js | 163 ++++++++++ cateditor/src/pagination.js | 45 +++ 3 files changed, 490 insertions(+), 15 deletions(-) create mode 100644 cateditor/src/pagination.js diff --git a/cateditor/src/components/CatalogContents.vue b/cateditor/src/components/CatalogContents.vue index d036541..28fb835 100644 --- a/cateditor/src/components/CatalogContents.vue +++ b/cateditor/src/components/CatalogContents.vue @@ -1,41 +1,308 @@ diff --git a/cateditor/src/pages/editor/store/index.js b/cateditor/src/pages/editor/store/index.js index 61c1ea2..a154abb 100644 --- a/cateditor/src/pages/editor/store/index.js +++ b/cateditor/src/pages/editor/store/index.js @@ -1,6 +1,8 @@ import Vue from 'vue' import Vuex from 'vuex' +import arrayMove from 'array-move' import axios from 'axios' +import { paginateModels } from '@/pagination' Vue.use(Vuex) @@ -82,6 +84,77 @@ export const store = new Vuex.Store({ savingCatalog: false, }, getters: { + + // NOTE don't use if you're not doing anything interesting, just use state. + + material: (state) => (id) => { + return state.materials[id] + }, + + sections: state => { + if (state.catalog != null) { + return state.catalog.sections + } else { + return null + } + }, + + section: (state) => (id) => { + if (state.catalog != null) { + return state.catalog.sections.find(s => s.id === id) + } else { + return null + } + }, + + selectedSection: state => { + if (state.catalog != null) { + return state.catalog.sections[0] + } else { + return null + } + }, + + selectedModel: state => { + if (state.catalog != null) { + return state.catalog.sections[0].pages[0][0] + } else { + return null + } + }, + + sectionModels: (state, getters) => (section) => { + // remove pages, return models (blocks) in order + let models = [] + if (section && section.pages) { + for (let page of section.pages) { + for (let model of page) { + if (model.ids && model.ids.length > 0) { + // add extra info from a material + let material = getters.material(model.ids[0]) + if (material) { + model['name'] = material.name + model['model'] = material.model + model['family'] = material.family + } else { + console.log('no material found for id', model.ids[0]) + } + models.push(model) + } + } + } + } + return models + }, + + modelMaterials: (state, getters) => (model) => { + if (model && model.ids && model.ids.length > 0) { + return model.ids.map(id => getters.material(id)) + } + return [] + }, + + /// OLD STUFF // // catalog info // @@ -95,6 +168,14 @@ export const store = new Vuex.Store({ // return state.catalog.sections.find(s => s.id === id) // }, + catalogSections: state => { + if (state.catalog != null) { + return state.catalog.sections + } else { + return null + } + }, + catalogProperty: (state) => (key) => { if (state.catalog != null) { return state.catalog[key] @@ -137,6 +218,23 @@ export const store = new Vuex.Store({ }, }, mutations: { + reorderSection(state, { from, to }) { + if (from === to) return + state.catalog.sections = arrayMove(state.catalog.sections, from, to) + }, + + setSectionPages(state, { section, pages }) { + if (section) { + section.pages = pages + } + }, + + setModelMaterials(state, { model, materials }) { + if (model) { + model.ids = materials.map(m => (typeof m === 'object') ? m.id : m) + } + }, + // SET_CAT_SECTIONS: (state, payload) => { // state.catalog.sections = payload // }, @@ -185,6 +283,71 @@ export const store = new Vuex.Store({ }, actions: { + reorderSection({ commit }, payload) { + commit('reorderSection', payload) + }, + + setSectionPages({ commit }, payload) { + commit('setSectionPages', payload) + }, + + setModelMaterials({ commit }, payload) { + commit('setModelMaterials', payload) + }, + + moveModelToSection({ commit, getters }, { model, oldSection, newSection }) { + // remove model from old section + let oldModels = getters.sectionModels(oldSection) + oldModels = oldModels.filter(m => m.model !== model.model) + let oldPages = paginateModels(oldModels) + commit('setSectionPages', { section: oldSection, pages: oldPages }) + + // add model to new section + let newModels = getters.sectionModels(newSection) + let existingModel = newModels.find(m => m.model === model.model) + if (existingModel) { + // merge + var ids = existingModel.ids + ids.push(...model.ids) + // uniquify + ids = ids.filter((v, i, a) => a.indexOf(v) === i) + existingModel.ids = ids + } else { + // add at end + newModels.push(model) + } + let newPages = paginateModels(newModels) + commit('setSectionPages', { section: newSection, pages: newPages }) + }, + + moveMaterialToSection({ commit, getters }, { material, oldModel, newSection }) { + // ensure material, not just id + if (typeof material === 'string' || typeof material === 'number') { + material = getters.material(material) + } + + // remove material from old model + let mats = oldModel.ids.filter(id => id !== material.id) + commit('setModelMaterials', { model: oldModel, materials: mats }) + + // add material to new section + let newModels = getters.sectionModels(newSection) + let existingModel = newModels.find(m => m.model === material.model) + if (existingModel) { + // merge + var ids = existingModel.ids + ids.push(material.id) + // uniquify + ids = ids.filter((v, i, a) => a.indexOf(v) === i) + existingModel.ids = ids + } else { + // add at end + newModels.push({ ids: [material.id] }) + } + let newPages = paginateModels(newModels) + commit('setSectionPages', { section: newSection, pages: newPages }) + }, + // SET_CAT_SECTIONS: (context, payload) => { // context.commit('SET_CAT_SECTIONS', payload) // }, diff --git a/cateditor/src/pagination.js b/cateditor/src/pagination.js new file mode 100644 index 0000000..784d6c7 --- /dev/null +++ b/cateditor/src/pagination.js @@ -0,0 +1,45 @@ + +export function paginateModels(models) { + for (let model of models) { + // ensure sizes + model.size = modelSize(model) + } + + let pages = [] + let currentSize = 0 + let currentPage = [] + for (let model of models) { + currentSize += model.size + if (currentSize > 3) { + pages.push(currentPage) + currentPage = [model] + currentSize = model.size + } else { + currentPage.push(model) + } + } + if (currentPage.length > 0) { + pages.push(currentPage) + } + + return pages +} + +export function modelSize(model) { + if (!model || !model.ids) return 0 + if (model.ids.length <= 4) return 1 + if (model.ids.length <= 8) return 2 + return 3 +} + +export function sectionModels(section) { + // remove pages, return models (blocks) in order + let models = [] + if (section && section.pages) { + for (let page of section.pages) { + models.push(...page) + } + } + + return models +}