meal plan refactor progress

- added paginated loading
- tab panes
- default meal type selection
- image placeholder
- drang and drop delete area
This commit is contained in:
Kaibu
2021-09-30 02:33:40 +02:00
parent bbe20d9656
commit b61512da77
17 changed files with 365 additions and 170 deletions

View File

@ -38,12 +38,24 @@ export default {
},
props: {
placeholder: {type: String, default: undefined},
model: {type: Object, default () {return {}}},
model: {
type: Object, default() {
return {}
}
},
label: {type: String, default: 'name'},
parent_variable: {type: String, default: undefined},
limit: {type: Number, default: 10,},
sticky_options: {type:Array, default(){return []}},
initial_selection: {type:Array, default(){return []}},
sticky_options: {
type: Array, default() {
return []
}
},
initial_selection: {
type: Array, default() {
return []
}
},
multiple: {type: Boolean, default: true},
allow_create: {type: Boolean, default: false}, // TODO: this will create option to add new drop-downs
create_placeholder: {type: String, default: 'You Forgot to Add a Tag Placeholder'},
@ -72,17 +84,33 @@ export default {
}
this.genericAPI(this.model, this.Actions.LIST, options).then((result) => {
this.objects = this.sticky_options.concat(result.data?.results ?? result.data)
if (this.selected_objects.length === 0 && this.initial_selection.length === 0 && this.objects.length > 0) {
this.objects.forEach((item) => {
if ("default" in item) {
if (item.default) {
if(this.multiple) {
this.selected_objects = [item]
} else {
this.selected_objects = item
}
this.selectionChanged()
}
}
})
}
})
},
selectionChanged: function () {
this.$emit('change', {var: this.parent_variable, val: this.selected_objects})
},
addNew(e) {
this.$emit('new', e)
// could refactor as Promise - seems unecessary
setTimeout(() => { this.search(''); }, 750);
setTimeout(() => {
this.search('');
}, 750);
}
}
}

View File

@ -0,0 +1,143 @@
<template>
<div class="cv-header">
<div class="cv-header-nav">
<button
:disabled="!headerProps.previousYear"
class="previousYear"
aria-label="Previous Year"
@click.prevent="onInput(headerProps.previousYear)"
>
{{ previousYearLabel }}
</button>
<button
:disabled="!headerProps.previousPeriod"
class="previousPeriod"
aria-label="Previous Period"
@click.prevent="onInput(headerProps.previousPeriod)"
v-html="previousPeriodLabel"
/>
<button
class="currentPeriod"
aria-label="Current Period"
@click.prevent="onInput(headerProps.currentPeriod)"
>
{{ headerProps.currentPeriodLabel }}
</button>
<button
:disabled="!headerProps.nextPeriod"
class="nextPeriod"
aria-label="Next Period"
@click.prevent="onInput(headerProps.nextPeriod)"
>
{{ nextPeriodLabel }}
</button>
<button
:disabled="!headerProps.nextYear"
class="nextYear"
aria-label="Next Year"
@click.prevent="onInput(headerProps.nextYear)">
{{ nextYearLabel }}
</button>
</div>
<div class="periodLabel">
<slot name="label">{{ headerProps.periodLabel }}</slot>
</div>
<div class="actionArea d-none d-sm-flex">
<span class="delete-area text-danger p-1 mr-2" @drop.prevent="onDeleteDrop($event)"
@dragenter.prevent="onDeleteDragEnter($event)" @dragleave.prevent="onDeleteDragLeave($event)" @dragover.prevent="onDeleteDragEnter"><i
class="fas fa-trash"></i> {{ $t('DragHereToDelete') }}</span>
</div>
</div>
</template>
<script>
export default {
name: "MealPlanCalenderHeader",
props: {
headerProps: {
type: Object,
required: true,
},
previousYearLabel: {type: String, default: "<<"},
previousPeriodLabel: {type: String, default: "<"},
nextPeriodLabel: {type: String, default: ">"},
nextYearLabel: {type: String, default: ">>"},
},
methods: {
onInput(d) {
this.$emit("input", d)
},
onDeleteDragEnter(e) {
e.currentTarget.classList.add("draghover")
},
onDeleteDragLeave(e) {
e.currentTarget.classList.remove("draghover")
},
onDeleteDrop(e) {
e.currentTarget.classList.remove("draghover")
this.$emit("delete-dragged")
},
},
}
</script>
<style>
.cv-header {
display: flex;
flex: 0 1 auto;
flex-flow: row nowrap;
align-items: center;
min-height: 2.5em;
border-width: 1px 1px 0 1px;
}
.cv-header .periodLabel {
display: flex;
flex: 1 1 auto;
flex-flow: row nowrap;
min-height: 1.5em;
line-height: 1;
font-size: 1.5em;
}
.cv-header .actionArea {
display: flex;
flex: 1 1 auto;
flex-flow: row nowrap;
min-height: 1.5em;
line-height: 1;
font-size: 1.5em;
}
.delete-area {
border-style: dotted;
margin-left: auto;
order: 2;
user-select: none
}
.delete-area.draghover {
box-shadow: inset 0 0 0.1em 0.1em #A7240E !important;
}
.cv-header,
.cv-header button {
border-style: solid;
border-color: #ddd;
}
.cv-header-nav,
.cv-header .periodLabel {
margin: 0.1em 0.6em;
}
.cv-header-nav button,
.cv-header .periodLabel {
padding: 0.4em 0.6em;
}
.cv-header button {
box-sizing: border-box;
line-height: 1em;
font-size: 1em;
border-width: 1px;
}
</style>

View File

@ -5,7 +5,7 @@
@click="onClickItem(value, $event)"
:aria-grabbed="value == currentDragItem"
:class="value.classes" :title="title"
@contextmenu.prevent="$parent.$parent.$refs.menu.open($event, value)">
@contextmenu.prevent="$emit('open-context-menu', $event, value)">
<div class="card-header p-1 text-center text-primary border-bottom-0" v-if="detailed"
:style="`background-color: ${background_color}`">
<span class="font-light text-center" v-if="entry.entry.meal_type.icon != null">{{
@ -20,7 +20,7 @@
<div class="dropdown b-dropdown position-static btn-group">
<button aria-haspopup="true" aria-expanded="false" type="button"
class="btn dropdown-toggle btn-link text-decoration-none text-body pr-1 dropdown-toggle-no-caret"
@click.stop="$parent.$parent.$refs.menu.open($event, value)"><i class="fas fa-ellipsis-v fa-lg"></i>
@click.stop="$emit('open-context-menu', $event, value)"><i class="fas fa-ellipsis-v fa-lg"></i>
</button>
</div>
</div>
@ -31,6 +31,7 @@
<span class="font-light">{{ title }}</span>
</div>
<b-img fluid class="card-img-bottom" :src="entry.entry.recipe.image" v-if="hasRecipe && detailed"></b-img>
<b-img fluid class="card-img-bottom" :src="image_placeholder" v-if="detailed && ((!hasRecipe && entry.entry.note === '') || (hasRecipe && entry.entry.recipe.image === null))"></b-img>
<div class="card-body p-1" v-if="detailed && entry.entry.recipe == null"
:style="`background-color: ${background_color}`">
<p>{{ entry.entry.note }}</p>
@ -63,7 +64,8 @@ export default {
data: function () {
return {
dateSelectionOrigin: null,
currentDragItem: null
currentDragItem: null,
image_placeholder: window.IMAGE_PLACEHOLDER
}
},
computed: {