yarn build

This commit is contained in:
smilerz
2021-11-21 11:11:51 -06:00
parent 6cffee57fe
commit d3d4c210c1
6 changed files with 5585 additions and 6151 deletions

View File

@ -48,8 +48,7 @@ from cookbook.models import (Automation, BookmarkletImport, CookLog, Food, FoodI
from cookbook.provider.dropbox import Dropbox
from cookbook.provider.local import Local
from cookbook.provider.nextcloud import Nextcloud
from cookbook.schemas import (FilterSchema, QueryOnlySchema, QueryParam, QueryParamAutoSchema,
RecipeSchema, TreeSchema)
from cookbook.schemas import FilterSchema, QueryParam, QueryParamAutoSchema, TreeSchema
from cookbook.serializer import (AutomationSerializer, BookmarkletImportSerializer,
CookLogSerializer, FoodInheritFieldSerializer, FoodSerializer,
FoodShoppingUpdateSerializer, ImportLogSerializer,

View File

@ -84,14 +84,4 @@
"@vue/cli-plugin-pwa/workbox-webpack-plugin": "^5.1.3",
"coa": "2.0.2"
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
],
"resolutions": {
"@vue/cli-plugin-pwa/workbox-webpack-plugin": "^5.1.3",
"coa": "2.0.2"
}
}

View File

@ -87,29 +87,25 @@ export default {
}
},
computed: {
filteredBooks: function() {
filteredBooks: function () {
return this.cookbooks.filter((book) => {
return book.name.toLowerCase().includes(this.search.toLowerCase())
})
},
},
createNew: function () {
let apiClient = new ApiApiFactory()
apiClient.createRecipeBook({name: this.$t('New_Cookbook'), description: '', icon: '', shared: []}).then(result => {
let new_book = result.data
mounted() {
this.refreshData()
this.$i18n.locale = window.CUSTOM_LOCALE
},
methods: {
refreshData: function() {
refreshData: function () {
let apiClient = new ApiApiFactory()
apiClient.listRecipeBooks().then((result) => {
this.cookbooks = result.data
})
},
openBook: function(book) {
openBook: function (book) {
if (book === this.current_book) {
this.current_book = undefined
this.recipes = []
@ -124,11 +120,11 @@ export default {
this.loading = false
})
},
createNew: function() {
createNew: function () {
let apiClient = new ApiApiFactory()
apiClient
.createRecipeBook({ name: "New Book", description: "", icon: "", shared: [] })
.createRecipeBook({ name: this.$t("New_Cookbook"), description: "", icon: "", shared: [] })
.then((result) => {
let new_book = result.data
this.refreshData()
@ -141,7 +137,7 @@ export default {
},
directives: {
hover: {
inserted: function(el) {
inserted: function (el) {
el.addEventListener("mouseenter", () => {
el.classList.add("shadow")
})

View File

@ -5,29 +5,45 @@
<div class="row">
<div class="col-12 calender-parent">
<calendar-view
:show-date="showDate" :enable-date-selection="true" class="theme-default"
:show-date="showDate"
:enable-date-selection="true"
class="theme-default"
:items="plan_items"
:display-period-uom="settings.displayPeriodUom"
:period-changed-callback="periodChangedCallback" :enable-drag-drop="true"
:period-changed-callback="periodChangedCallback"
:enable-drag-drop="true"
:item-content-height="item_height"
@click-date="createEntryClick" @drop-on-date="moveEntry"
@click-date="createEntryClick"
@drop-on-date="moveEntry"
:display-period-count="settings.displayPeriodCount"
:starting-day-of-week="settings.startingDayOfWeek"
:display-week-numbers="settings.displayWeekNumbers">
:display-week-numbers="settings.displayWeekNumbers"
>
<template #item="{ value, weekStartDate, top }">
<meal-plan-card :value="value" :week-start-date="weekStartDate" :top="top" :detailed="detailed_items"
:item_height="item_height" @dragstart="dragged_item = value" @click-item="entryClick"
@open-context-menu="openContextMenu"/>
<meal-plan-card
:value="value"
:week-start-date="weekStartDate"
:top="top"
:detailed="detailed_items"
:item_height="item_height"
@dragstart="dragged_item = value"
@click-item="entryClick"
@open-context-menu="openContextMenu"
/>
</template>
<template #header="{ headerProps }">
<meal-plan-calender-header ref="header"
<meal-plan-calender-header
ref="header"
:header-props="headerProps"
@input="setShowDate" @delete-dragged="deleteEntry(dragged_item)"
@input="setShowDate"
@delete-dragged="deleteEntry(dragged_item)"
@create-new="createEntryClick(new Date())"
@set-starting-day-back="setStartingDay(-1)"
@set-starting-day-forward="setStartingDay(1)" :i-cal-url="iCalUrl"
@set-starting-day-forward="setStartingDay(1)"
:i-cal-url="iCalUrl"
:options="options"
:settings_prop="settings"/>
:settings_prop="settings"
/>
</template>
</calendar-view>
</div>
@ -36,70 +52,6 @@
<b-tab :title="$t('Settings')">
<div class="row mt-3">
<div class="col-12 col-md-3 calender-options">
<h5>{{ $t('Planner_Settings') }}</h5>
<b-form>
<b-form-group id="UomInput"
:label="$t('Period')"
:description="$t('Plan_Period_To_Show')"
label-for="UomInput">
<b-form-select
id="UomInput"
v-model="settings.displayPeriodUom"
:options="options.displayPeriodUom"
></b-form-select>
</b-form-group>
<b-form-group id="PeriodInput"
:label="$t('Periods')"
:description="$t('Plan_Show_How_Many_Periods')"
label-for="PeriodInput">
<b-form-select
id="PeriodInput"
v-model="settings.displayPeriodCount"
:options="options.displayPeriodCount"
></b-form-select>
</b-form-group>
<b-form-group id="DaysInput"
:label="$t('Starting_Day')"
:description="$t('Starting_Day')"
label-for="DaysInput">
<b-form-select
id="DaysInput"
v-model="settings.startingDayOfWeek"
:options="dayNames"
></b-form-select>
</b-form-group>
<b-form-group id="WeekNumInput"
:label="$t('Week_Numbers')">
<b-form-checkbox v-model="settings.displayWeekNumbers" name="week_num">
{{ $t('Show_Week_Numbers') }}
</b-form-checkbox>
</b-form-group>
</b-form>
</div>
<div class="col-12 col-md-9 col-lg-6">
<h5>{{ $t('Meal_Types') }}</h5>
<div>
<draggable :list="meal_types" group="meal_types"
:empty-insert-threshold="10" handle=".handle" @sort="sortMealTypes()">
<b-card no-body class="mt-1" v-for="(meal_type, index) in meal_types" v-hover :key="meal_type.id">
<b-card-header class="p-4">
<div class="row">
<div class="col-2 handle">
<button type="button" class="btn btn-lg shadow-none"><i class="fas fa-arrows-alt-v "></i>
</button>
</div>
<div class="col-10">
<h5>{{ meal_type.icon }} {{ meal_type.name }}<span class="float-right text-primary"><i
class="fa" v-bind:class="{ 'fa-pen': !meal_type.editing, 'fa-save': meal_type.editing }"
@click="editOrSaveMealType(index)"
aria-hidden="true"></i></span></h5>
</div>
</div>
</div>
</b-tab>
<b-tab :title="$t('Settings')">
<div class="row mt-3">
<div class="col-3 calender-options">
<h5>{{ $t("Planner_Settings") }}</h5>
<b-form>
<b-form-group id="UomInput" :label="$t('Period')" :description="$t('Plan_Period_To_Show')" label-for="UomInput">
@ -118,7 +70,7 @@
</b-form-group>
</b-form>
</div>
<div class="col-9 col-lg-6">
<div class="col-12 col-md-9 col-lg-6">
<h5>{{ $t("Meal_Types") }}</h5>
<div>
<draggable :list="meal_types" group="meal_types" :empty-insert-threshold="10" handle=".handle" @sort="sortMealTypes()">
@ -126,7 +78,7 @@
<b-card-header class="p-4">
<div class="row">
<div class="col-2 handle">
<button type="button" class="btn btn-lg shadow-none"><i class="fas fa-arrows-alt-v "></i></button>
<button type="button" class="btn btn-lg shadow-none"><i class="fas fa-arrows-alt-v"></i></button>
</div>
<div class="col-10">
<h5>
@ -214,7 +166,6 @@
>
<a class="dropdown-item p-2" href="#"><i class="fas fa-shopping-cart"></i> {{ $t("Add_to_Shopping") }}</a>
</ContextMenuItem>
<!-- TODO: Add new shopping Modal -->
<ContextMenuItem
@click="
$refs.menu.close()
@ -262,7 +213,8 @@
</b-sidebar>
</div>
</template>
<div class="row fixed-bottom p-2 b-1 border-top text-center" style="background:rgba(255,255,255,0.6);">
<transition name="slide-fade">
<div class="row fixed-bottom p-2 b-1 border-top text-center" style="background: rgba(255, 255, 255, 0.6)" v-if="current_tab === 0">
<div class="col-md-3 col-6">
<button class="btn btn-block btn-success shadow-none" @click="createEntryClick(new Date())"><i class="fas fa-calendar-plus"></i> {{ $t("Create") }}</button>
</div>
@ -275,32 +227,9 @@
{{ $t("Export_To_ICal") }}
</a>
</div>
</div>
</b-sidebar>
</div>
</template>
<transition name="slide-fade">
<div class="row fixed-bottom p-2 b-1 border-top text-center" style="background:rgba(255,255,255,0.6);"
v-if="current_tab === 0">
<div class="col-md-3 col-6">
<button class="btn btn-block btn-success shadow-none" @click="createEntryClick(new Date())"><i
class="fas fa-calendar-plus"></i> {{ $t('Create') }}
</button>
</div>
<div class="col-md-3 col-6">
<button class="btn btn-block btn-primary shadow-none" v-b-toggle.sidebar-shopping><i
class="fas fa-shopping-cart"></i> {{ $t('Shopping_list') }}
</button>
</div>
<div class="col-md-3 col-6">
<a class="btn btn-block btn-primary shadow-none" :href="iCalUrl"><i class="fas fa-download"></i>
{{ $t('Export_To_ICal') }}
</a>
</div>
<div class="col-md-3 col-6">
<button class="btn btn-block btn-primary shadow-none disabled" v-b-tooltip.focus.top
:title="$t('Coming_Soon')">
{{ $t('Auto_Planner') }}
<button class="btn btn-block btn-primary shadow-none disabled" v-b-tooltip.focus.top :title="$t('Coming_Soon')">
{{ $t("Auto_Planner") }}
</button>
</div>
<div class="col-12 d-flex justify-content-center mt-2 d-block d-md-none">
@ -310,12 +239,8 @@
<b-button v-html="'<'" @click="setStartingDay(-1)"></b-button>
</b-button-group>
<b-button-group class="mx-1">
<b-button @click="setShowDate($refs.header.headerProps.currentPeriod)"><i class="fas fa-home"></i>
</b-button>
<b-form-datepicker
button-only
button-variant="secondary"
></b-form-datepicker>
<b-button @click="setShowDate($refs.header.headerProps.currentPeriod)"><i class="fas fa-home"></i> </b-button>
<b-form-datepicker button-only button-variant="secondary"></b-form-datepicker>
</b-button-group>
<b-button-group class="mx-1">
<b-button v-html="'>'" @click="setStartingDay(1)"></b-button>
@ -366,7 +291,7 @@ export default {
ContextMenuItem,
MealPlanCalenderHeader,
EmojiInput,
draggable
draggable,
},
mixins: [CalendarMathMixin, ApiMixin],
data: function () {
@ -375,20 +300,24 @@ export default {
plan_entries: [],
recipe_viewed: {},
settings: {
displayPeriodUom: 'week',
displayPeriodUom: "week",
displayPeriodCount: 2,
startingDayOfWeek: 1,
displayWeekNumbers: true
displayWeekNumbers: true,
},
dragged_item: null,
current_tab: 0,
meal_types: [],
current_context_menu_item: null,
options: {
displayPeriodUom: [{text: this.$t('Week'), value: 'week'}, {
text: this.$t('Month'),
value: 'month'
}, {text: this.$t('Year'), value: 'year'}],
displayPeriodUom: [
{ text: this.$t("Week"), value: "week" },
{
text: this.$t("Month"),
value: "month",
},
{ text: this.$t("Year"), value: "year" },
],
displayPeriodCount: [1, 2, 3],
entryEditing: {
date: null,
@ -399,23 +328,23 @@ export default {
recipe: null,
servings: 1,
shared: [],
title: '',
title_placeholder: this.$t('Title')
}
title: "",
title_placeholder: this.$t("Title"),
},
},
shopping_list: [],
current_period: null,
entryEditing: {},
edit_modal_show: false,
ical_url: window.ICAL_URL
ical_url: window.ICAL_URL,
}
},
computed: {
modal_title: function () {
if (this.entryEditing.id === -1) {
return this.$t('Create_Meal_Plan_Entry')
return this.$t("Create_Meal_Plan_Entry")
} else {
return this.$t('Edit_Meal_Plan_Entry')
return this.$t("Edit_Meal_Plan_Entry")
}
},
entryEditing_initial_recipe: function () {
@ -440,12 +369,12 @@ export default {
return items
},
detailed_items: function () {
return this.settings.displayPeriodUom === 'week';
return this.settings.displayPeriodUom === "week"
},
dayNames: function () {
let options = []
this.getFormattedWeekdayNames(this.userLocale, "long", 0).forEach((day, index) => {
options.push({text: day, value: index})
options.push({ text: day, value: index })
})
return options
},
@ -453,143 +382,6 @@ export default {
return this.getDefaultBrowserLocale
},
item_height: function () {
if (this.settings.displayPeriodUom === 'week') {
return "10rem"
} else {
return "1.6rem"
}
},
iCalUrl() {
if (this.current_period !== null) {
let start = moment(this.current_period.periodStart).format('YYYY-MM-DD')
let end = moment(this.current_period.periodEnd).format('YYYY-MM-DD')
return this.ical_url.replace(/12345/, start).replace(/6789/, end)
} else {
return ""
}
}
},
mounted() {
this.$nextTick(function () {
if (this.$cookies.isKey(SETTINGS_COOKIE_NAME)) {
this.settings = Object.assign({}, this.settings, this.$cookies.get(SETTINGS_COOKIE_NAME))
}
})
this.$root.$on('change', this.updateEmoji);
this.$i18n.locale = window.CUSTOM_LOCALE
},
watch: {
settings: {
handler() {
this.$cookies.set(SETTINGS_COOKIE_NAME, this.settings, '360d')
},
deep: true
},
},
methods: {
addToShopping(entry) {
if (entry.originalItem.entry.recipe !== null) {
this.shopping_list.push(entry.originalItem.entry)
makeToast(this.$t("Success"), this.$t("Added_To_Shopping_List"), 'success')
} else {
makeToast(this.$t("Failure"), this.$t("Cannot_Add_Notes_To_Shopping"), 'danger')
}
},
saveShoppingList() {
let url = window.SHOPPING_URL
let first = true
for (let se of this.shopping_list) {
if (first) {
url += `?r=[${se.recipe.id},${se.servings}]`
first = false
} else {
url += `&r=[${se.recipe.id},${se.servings}]`
}
}
window.open(url)
},
setStartingDay(days) {
if (this.settings.startingDayOfWeek + days < 0) {
this.settings.startingDayOfWeek = 6
} else if (this.settings.startingDayOfWeek + days > 6) {
this.settings.startingDayOfWeek = 0
} else {
this.settings.startingDayOfWeek = this.settings.startingDayOfWeek + days
}
},
newMealType() {
let apiClient = new ApiApiFactory()
apiClient.createMealType({name: this.$t('Meal_Type')}).then(e => {
this.periodChangedCallback(this.current_period)
}).catch(error => {
StandardToasts.makeStandardToast(StandardToasts.FAIL_UPDATE)
})
this.refreshMealTypes()
},
sortMealTypes() {
this.meal_types.forEach(function (element, index) {
element.order = index
});
let updated = 0
this.meal_types.forEach((meal_type) => {
let apiClient = new ApiApiFactory()
apiClient.updateMealType(meal_type.id, meal_type).then(e => {
if (updated === (this.meal_types.length - 1)) {
this.periodChangedCallback(this.current_period)
} else {
updated++
}
}).catch(error => {
StandardToasts.makeStandardToast(StandardToasts.FAIL_UPDATE)
})
})
},
computed: {
modal_title: function() {
if (this.entryEditing.id === -1) {
return this.$t("Create_Meal_Plan_Entry")
} else {
return this.$t("Edit_Meal_Plan_Entry")
}
},
entryEditing_initial_recipe: function() {
if (this.entryEditing.recipe != null) {
return [this.entryEditing.recipe]
} else {
return []
}
},
entryEditing_initial_meal_type: function() {
if (this.entryEditing.meal_type != null) {
return [this.entryEditing.meal_type]
} else {
return []
}
},
plan_items: function() {
let items = []
this.plan_entries.forEach((entry) => {
items.push(this.buildItem(entry))
})
return items
},
detailed_items: function() {
return this.settings.displayPeriodUom === "week"
},
dayNames: function() {
let options = []
this.getFormattedWeekdayNames(this.userLocale, "long", 0).forEach((day, index) => {
options.push({ text: day, value: index })
})
return options
},
userLocale: function() {
return this.getDefaultBrowserLocale
},
item_height: function() {
if (this.settings.displayPeriodUom === "week") {
return "10rem"
} else {
@ -607,12 +399,13 @@ export default {
},
},
mounted() {
this.$nextTick(function() {
this.$nextTick(function () {
if (this.$cookies.isKey(SETTINGS_COOKIE_NAME)) {
this.settings = Object.assign({}, this.settings, this.$cookies.get(SETTINGS_COOKIE_NAME))
}
})
this.$root.$on("change", this.updateEmoji)
this.$i18n.locale = window.CUSTOM_LOCALE
},
watch: {
settings: {
@ -657,7 +450,7 @@ export default {
let apiClient = new ApiApiFactory()
apiClient
.createMealType({ name: "Mealtype" })
.createMealType({ name: this.$t("Meal_Type") })
.then((e) => {
this.periodChangedCallback(this.current_period)
})
@ -668,7 +461,7 @@ export default {
this.refreshMealTypes()
},
sortMealTypes() {
this.meal_types.forEach(function(element, index) {
this.meal_types.forEach(function (element, index) {
element.order = index
})
let updated = 0
@ -721,7 +514,7 @@ export default {
StandardToasts.makeStandardToast(StandardToasts.FAIL_DELETE)
})
},
updateEmoji: function(field, value) {
updateEmoji: function (field, value) {
this.meal_types.forEach((meal_type) => {
if (meal_type.editing) {
meal_type.icon = value
@ -870,7 +663,7 @@ export default {
},
directives: {
hover: {
inserted: function(el) {
inserted: function (el) {
el.addEventListener("mouseenter", () => {
el.classList.add("shadow")
})
@ -885,14 +678,15 @@ export default {
<style>
.slide-fade-enter-active {
transition: all .3s ease;
transition: all 0.3s ease;
}
.slide-fade-leave-active {
transition: all .1s cubic-bezier(1.0, 0.5, 0.8, 1.0);
transition: all 0.1s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter, .slide-fade-leave-to {
.slide-fade-enter,
.slide-fade-leave-to {
transform: translateY(10px);
opacity: 0;
}

View File

@ -55,71 +55,6 @@
</div>
</div>
</div>
<div class="row">
<div class="col-md-9" style="margin-top: 1vh">
<h3>
<!-- <span><b-button variant="link" size="sm" class="text-dark shadow-none"><i class="fas fa-chevron-down"></i></b-button></span> -->
<model-menu/>
<span>{{ this.this_model.name }}</span>
<span v-if="this_model.name !== 'Step'"><b-button variant="link" @click="startAction({'action':'new'})"><i
class="fas fa-plus-circle fa-2x"></i></b-button></span><!-- TODO add proper field to model config to determine if create should be available or not -->
</h3>
</div>
<div class="col-md-3" style="position: relative; margin-top: 1vh">
<b-form-checkbox v-model="show_split" name="check-button" v-if="paginated"
class="shadow-none"
style="position:relative;top: 50%; transform: translateY(-50%);" switch>
{{ $t('show_split_screen') }}
</b-form-checkbox>
</div>
</div>
<div class="row">
<div class="col" :class="{'col-md-6' : show_split}">
<!-- model isn't paginated and loads in one API call -->
<div v-if="!paginated">
<generic-horizontal-card v-for="i in items_left" v-bind:key="i.id"
:item=i
:model="this_model"
@item-action="startAction($event, 'left')"
@finish-action="finishAction"/>
</div>
<!-- model is paginated and needs managed -->
<generic-infinite-cards v-if="paginated"
:card_counts="left_counts"
:scroll="show_split"
@search="getItems($event, 'left')"
@reset="resetList('left')">
<template v-slot:cards>
<generic-horizontal-card
v-for="i in items_left" v-bind:key="i.id"
:item=i
:model="this_model"
@item-action="startAction($event, 'left')"
@finish-action="finishAction"/>
</template>
</generic-infinite-cards>
</div>
<div class="col col-md-6" v-if="show_split">
<generic-infinite-cards v-if="this_model"
:card_counts="right_counts"
:scroll="show_split"
@search="getItems($event, 'right')"
@reset="resetList('right')">
<template v-slot:cards>
<generic-horizontal-card
v-for="i in items_right" v-bind:key="i.id"
:item=i
:model="this_model"
@item-action="startAction($event, 'right')"
@finish-action="finishAction"/>
</template>
</generic-infinite-cards>
</div>
</div>
</div>
</div>
</template>
@ -129,7 +64,8 @@ import { BootstrapVue } from "bootstrap-vue"
import "bootstrap-vue/dist/bootstrap-vue.css"
import { CardMixin, ApiMixin, getConfig, StandardToasts, getUserPreference, makeToast } from "@/utils/utils"
import { CardMixin, ApiMixin, getConfig } from "@/utils/utils"
import { StandardToasts, ToastMixin } from "@/utils/utils"
import GenericInfiniteCards from "@/components/GenericInfiniteCards"
import GenericHorizontalCard from "@/components/GenericHorizontalCard"
@ -143,18 +79,21 @@ Vue.use(BootstrapVue)
export default {
// TODO ApiGenerator doesn't capture and share error information - would be nice to share error details when available
// or i'm capturing it incorrectly
name: 'ModelListView',
name: "ModelListView",
mixins: [CardMixin, ApiMixin, ToastMixin],
components: {
GenericHorizontalCard, GenericModalForm, GenericInfiniteCards, ModelMenu,
GenericHorizontalCard,
GenericModalForm,
GenericInfiniteCards,
ModelMenu,
},
data() {
return {
// this.Models and this.Actions inherited from ApiMixin
items_left: [],
items_right: [],
right_counts: {'max': 9999, 'current': 0},
left_counts: {'max': 9999, 'current': 0},
right_counts: { max: 9999, current: 0 },
left_counts: { max: 9999, current: 0 },
this_model: undefined,
model_menu: undefined,
this_action: undefined,
@ -167,125 +106,6 @@ export default {
header_component_name: undefined,
}
},
computed: {
headerComponent() {
// TODO this leads webpack to create one .js file for each component in this folder because at runtime any one of them could be requested
// TODO this is not necessarily bad but maybe there are better options to do this
return () => import(/* webpackChunkName: "header-component" */ `@/components/${this.header_component_name}`)
}
},
mounted() {
// value is passed from lists.py
let model_config = JSON.parse(document.getElementById('model_config').textContent)
this.this_model = this.Models[model_config?.model]
this.this_recipe_param = model_config?.recipe_param
this.paginated = this.this_model?.paginated ?? false
this.header_component_name = this.this_model?.list?.header_component?.name ?? undefined
this.$nextTick(() => {
if (!this.paginated) {
this.getItems({page:1},'left')
}
})
this.$i18n.locale = window.CUSTOM_LOCALE
},
methods: {
// this.genericAPI inherited from ApiMixin
resetList: function (e) {
this['items_' + e] = []
this[e + '_counts'].max = 9999 + Math.random()
this[e + '_counts'].current = 0
},
startAction: function (e, param) {
let source = e?.source ?? {}
let target = e?.target ?? undefined
this.this_item = source
this.this_target = target
switch (e.action) {
case 'delete':
this.this_action = this.Actions.DELETE
this.show_modal = true
break;
case 'new':
this.this_action = this.Actions.CREATE
this.show_modal = true
break;
case 'edit':
this.this_item = e.source
this.this_action = this.Actions.UPDATE
this.show_modal = true
break;
case 'move':
if (target == null) {
this.this_item = e.source
this.this_action = this.Actions.MOVE
this.show_modal = true
} else {
this.moveThis(source.id, target.id)
}
break;
case 'merge':
if (target == null) {
this.this_item = e.source
this.this_action = this.Actions.MERGE
this.show_modal = true
} else {
this.mergeThis(e.source, e.target, false)
}
break;
case 'merge-automate':
if (target == null) {
this.this_item = e.source
this.this_action = this.Actions.MERGE
this.show_modal = true
} else {
this.mergeThis(e.source, e.target, true)
}
break
case 'get-children':
if (source.show_children) {
Vue.set(source, 'show_children', false)
} else {
this.getChildren(param, source)
}
break;
case 'get-recipes':
if (source.show_recipes) {
Vue.set(source, 'show_recipes', false)
} else {
this.getRecipes(param, source)
}
break;
}
},
finishAction: function (e) {
let update = undefined
switch (e?.action) {
case 'save':
this.saveThis(e.form_data)
break;
}
if (e !== 'cancel') {
switch (this.this_action) {
case this.Actions.DELETE:
this.deleteThis(this.this_item.id)
break;
case this.Actions.CREATE:
this.saveThis(e.form_data)
break;
case this.Actions.UPDATE:
update = e.form_data
update.id = this.this_item.id
this.saveThis(update)
break;
case this.Actions.MERGE:
this.mergeThis(this.this_item, e.form_data.target, false)
break;
case this.Actions.MOVE:
this.moveThis(this.this_item.id, e.form_data.target.id)
break;
}
},
computed: {
headerComponent() {
// TODO this leads webpack to create one .js file for each component in this folder because at runtime any one of them could be requested
@ -379,13 +199,6 @@ export default {
this.getRecipes(param, source)
}
break
case "add-shopping":
//TODO: add modal to edit units and amount
this.addShopping(e.source)
break
case "add-onhand":
this.addOnhand(e.source)
break
}
},
finishAction: function (e) {
@ -425,6 +238,26 @@ 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
@ -484,11 +317,11 @@ export default {
.then((result) => {
this.moveUpdateItem(source_id, target_id)
// TODO make standard toast
makeToast(this.$t("Success"), "Succesfully moved resource", "success")
StandardToasts.makeStandardToast(StandardToasts.SUCCESS_MOVE)
})
.catch((err) => {
console.log(err)
StandardToasts.makeStandardToast(StandardToasts.FAIL_MOVE, err?.bodyText)
this.makeToast(this.$t("Error"), err.bodyText, "danger")
})
},
moveUpdateItem: function (source_id, target_id) {
@ -529,7 +362,7 @@ export default {
.catch((err) => {
//TODO error checking not working with OpenAPI methods
console.log("Error", err)
StandardToasts.makeStandardToast(StandardToasts.FAIL_MOVE, err?.bodyText)
this.makeToast(this.$t("Error"), err.bodyText, "danger")
})
if (automate) {
@ -578,7 +411,7 @@ export default {
})
.catch((err) => {
console.log(err)
makeToast(this.$t("Error"), err.bodyText, "danger")
StandardToasts.makeStandardToast(StandardToasts.FAIL_FETCH)
})
},
getRecipes: function (col, item) {
@ -598,7 +431,7 @@ export default {
})
.catch((err) => {
console.log(err)
makeToast(this.$t("Error"), err.bodyText, "danger")
this.makeToast(this.$t("Error"), err.bodyText, "danger")
})
},
refreshThis: function (id) {
@ -613,7 +446,7 @@ export default {
},
clearState: function () {
this.show_modal = false
this.this_action = {}
this.this_action = undefined
this.this_item = undefined
this.this_target = undefined
},

File diff suppressed because it is too large Load Diff