diff --git a/vue/src/apps/ModelListView/ModelListView.vue b/vue/src/apps/ModelListView/ModelListView.vue index 1d90667d..1449acbc 100644 --- a/vue/src/apps/ModelListView/ModelListView.vue +++ b/vue/src/apps/ModelListView/ModelListView.vue @@ -242,26 +242,6 @@ export default { let results = result.data?.results ?? result.data if (results?.length) { - // let secondaryRequest = undefined; - // if (this['items_' + column]?.length < getConfig(this.this_model, this.Actions.LIST).config.pageSize.default * (params.page - 1)) { - // // the item list is smaller than it should be based on the site the user is own - // // this happens when an item is deleted (or merged) - // // to prevent issues insert the last item of the previous search page before loading the new results - // params.page = params.page - 1 - // secondaryRequest = this.genericAPI(this.this_model, this.Actions.LIST, params).then((result) => { - // let prev_page_results = result.data?.results ?? result.data - // if (prev_page_results?.length) { - // results = [prev_page_results[prev_page_results.length]].concat(results) - // - // this['items_' + column] = this['items_' + column].concat(results) //TODO duplicate code, find some elegant workaround - // this[column + '_counts']['current'] = getConfig(this.this_model, this.Actions.LIST).config.pageSize.default * (params.page - 1) + results.length - // this[column + '_counts']['max'] = result.data?.count ?? 0 - // } - // }) - // } else { - // - // } - this["items_" + column] = this["items_" + column].concat(results) this[column + "_counts"]["current"] = getConfig(this.this_model, this.Actions.LIST).config.pageSize.default * (params.page - 1) + results.length this[column + "_counts"]["max"] = result.data?.count ?? 0 @@ -280,11 +260,32 @@ export default { return this.genericAPI(this.this_model, this.Actions.FETCH, { id: id }) }, saveThis: function (item) { - // look for and destroy any existing cards to prevent duplicates in the GET case of get_or_create - // then place all new items at the top of the list - could sort instead - this.items_left = [item].concat(this.destroyCard(item?.id, this.items_left)) - // this creates a deep copy to make sure that columns stay independent - this.items_right = [{ ...item }].concat(this.destroyCard(item?.id, this.items_right)) + if (!item?.id) { + // if there is no item id assume it's a new item + this.genericAPI(this.this_model, this.Actions.CREATE, item) + .then((result) => { + // look for and destroy any existing cards to prevent duplicates in the GET case of get_or_create + // then place all new items at the top of the list - could sort instead + this.items_left = [result.data].concat(this.destroyCard(result?.data?.id, this.items_left)) + // this creates a deep copy to make sure that columns stay independent + this.items_right = [{ ...result.data }].concat(this.destroyCard(result?.data?.id, this.items_right)) + StandardToasts.makeStandardToast(StandardToasts.SUCCESS_CREATE) + }) + .catch((err) => { + console.log(err) + StandardToasts.makeStandardToast(StandardToasts.FAIL_CREATE) + }) + } else { + this.genericAPI(this.this_model, this.Actions.UPDATE, item) + .then((result) => { + this.refreshThis(item.id) + StandardToasts.makeStandardToast(StandardToasts.SUCCESS_UPDATE) + }) + .catch((err) => { + console.log(err, err.response) + StandardToasts.makeStandardToast(StandardToasts.FAIL_UPDATE) + }) + } }, // this currently assumes shopping is only applicable on FOOD model addShopping: function (food) { diff --git a/vue/src/components/Modals/LookupInput.vue b/vue/src/components/Modals/LookupInput.vue index 66a9863e..7f41954c 100644 --- a/vue/src/components/Modals/LookupInput.vue +++ b/vue/src/components/Modals/LookupInput.vue @@ -44,7 +44,7 @@ export default { return undefined }, }, - class_list: {type: String, default: "mb-3"}, + class_list: { type: String, default: "mb-3" }, show_label: { type: Boolean, default: true }, clear: { type: Number }, }, @@ -71,6 +71,9 @@ export default { return this.form?.multiple || this.form?.ordered || false }, initialSelection() { + if (!this.new_value) { + return + } let this_value = this.new_value let arrayValues = undefined // multiselect is expect to get an array of objects - make sure it gets one diff --git a/vue/src/utils/utils.js b/vue/src/utils/utils.js index 1d4e47bb..5d332ee5 100644 --- a/vue/src/utils/utils.js +++ b/vue/src/utils/utils.js @@ -508,32 +508,48 @@ const specialCases = { // delete, update or change all of the category/relations let id = result.id let existing_categories = result.category_to_supermarket - let updated_categories = options.category_to_supermarket + let updated_categories = options.category_to_supermarket.map((x) => { + return { + ...x, + category: { + id: x?.category?.id ?? x.id, + name: x?.category?.name ?? x.name, + }, + id: x?.category_to_supermarket__id, + order: x?.order ?? x?.category_to_supermarket__order, + } + }) let promises = [] // if the 'category.name' key does not exist on the updated_categories, the categories were not updated - if (updated_categories?.[0]?.category?.name) { - // list of category relationship ids that are not part of the updated supermarket - let removed_categories = existing_categories.filter((x) => !updated_categories.map((x) => x.category.id).includes(x.category.id)) - let added_categories = updated_categories.filter((x) => !existing_categories.map((x) => x.category.id).includes(x.category.id)) - let changed_categories = updated_categories.filter((x) => existing_categories.map((x) => x.category.id).includes(x.category.id)) - removed_categories.forEach((x) => { - promises.push(GenericAPI(Models.SHOPPING_CATEGORY_RELATION, Actions.DELETE, { id: x.id })) - }) - let item = { supermarket: id } - added_categories.forEach((x) => { - item.order = x.order - item.category = { id: x.category.id, name: x.category.name } - promises.push(GenericAPI(Models.SHOPPING_CATEGORY_RELATION, Actions.CREATE, item)) - }) - changed_categories.forEach((x) => { - item.id = x?.id ?? existing_categories.find((y) => y.category.id === x.category.id).id - item.order = x.order - item.category = { id: x.category.id, name: x.category.name } - promises.push(GenericAPI(Models.SHOPPING_CATEGORY_RELATION, Actions.UPDATE, item)) - }) - } + // list of category relationship ids that are not part of the updated supermarket + let removed_categories = existing_categories.filter((x) => !updated_categories.map((x) => x.category.id).includes(x.category.id)) + let added_categories = updated_categories.filter((x) => !existing_categories.map((x) => x.category.id).includes(x.category.id)) + let changed_categories = updated_categories.filter((x) => existing_categories.map((x) => x.category.id).includes(x.category.id)) + let order = Math.max(...existing_categories.map((x) => x?.order ?? 0), ...updated_categories.map((x) => x?.order ?? 0), 0) + 1 + + removed_categories.forEach((x) => { + promises.push(GenericAPI(Models.SHOPPING_CATEGORY_RELATION, Actions.DELETE, { id: x.id })) + }) + let item = { supermarket: id } + added_categories.forEach((x) => { + item.order = x?.order ?? order + if (!x?.order) { + order = order + 1 + } + item.category = { id: x.category.id, name: x.category.name } + promises.push(GenericAPI(Models.SHOPPING_CATEGORY_RELATION, Actions.CREATE, item)) + }) + changed_categories.forEach((x) => { + item.id = x?.id ?? existing_categories.find((y) => y.category.id === x.category.id).id + item.order = x?.order ?? order + if (!x?.order) { + order = order + 1 + } + item.category = { id: x.category.id, name: x.category.name } + promises.push(GenericAPI(Models.SHOPPING_CATEGORY_RELATION, Actions.UPDATE, item)) + }) return Promise.all(promises).then(() => { // finally get and return the Supermarket which everything downstream is expecting