Merge remote-tracking branch 'upstream/feature/custom_filters' into feature/custom_filters

This commit is contained in:
smilerz
2022-02-13 14:14:28 -06:00
44 changed files with 2509 additions and 2331 deletions

View File

@ -56,14 +56,6 @@
<button id="id_settings_button" class="btn btn-primary btn-block text-uppercase"><i class="fas fa-cog fa-lg m-1"></i></button>
</div>
</div>
<div v-if="ui.enable_expert" class="row justify-content-end small">
<div class="col-auto">
<b-button class="my-0" variant="link" size="sm" @click="ui.expert_mode = !ui.expert_mode">
<div v-if="!expertMode">{{ $t("expert_mode") }}</div>
<div v-if="expertMode">{{ $t("simple_mode") }}</div>
</b-button>
</div>
</div>
<b-popover target="id_settings_button" triggers="click" placement="bottom">
<b-tabs content-class="mt-1 text-nowrap" small>
@ -93,7 +85,7 @@
</div>
</div>
</b-tab>
<b-tab :title="$t('fields')" :title-link-class="['mx-0']" v-if="ui.enable_expert">
<b-tab :title="$t('fields')" :title-link-class="['mx-0']">
<b-form-group v-bind:label="$t('show_keywords')" label-for="popover-show_keywords" label-cols="8" class="mb-1">
<b-form-checkbox switch v-model="ui.show_keywords" id="popover-show_keywords" size="sm"></b-form-checkbox>
</b-form-group>
@ -106,19 +98,19 @@
<b-form-group v-bind:label="$t('show_rating')" label-for="popover-show_rating" label-cols="8" class="mb-1">
<b-form-checkbox switch v-model="ui.show_rating" id="popover-show_rating" size="sm"></b-form-checkbox>
</b-form-group>
<b-form-group v-if="ui.enable_expert" v-bind:label="$t('show_units')" label-for="popover-show_units" label-cols="8" class="mb-1">
<b-form-group v-bind:label="$t('show_units')" label-for="popover-show_units" label-cols="8" class="mb-1">
<b-form-checkbox switch v-model="ui.show_units" id="popover-show_units" size="sm"></b-form-checkbox>
</b-form-group>
<b-form-group v-if="ui.enable_expert" v-bind:label="$t('show_filters')" label-for="popover-show_filters" label-cols="8" class="mb-1">
<b-form-group v-bind:label="$t('show_filters')" label-for="popover-show_filters" label-cols="8" class="mb-1">
<b-form-checkbox switch v-model="ui.show_filters" id="popover-show_filters" size="sm"></b-form-checkbox>
</b-form-group>
<b-form-group v-if="ui.enable_expert" v-bind:label="$t('show_sortby')" label-for="popover-show_sortby" label-cols="8" class="mb-1">
<b-form-group v-bind:label="$t('show_sortby')" label-for="popover-show_sortby" label-cols="8" class="mb-1">
<b-form-checkbox switch v-model="ui.show_sortby" id="popover-show_sortby" size="sm"></b-form-checkbox>
</b-form-group>
<b-form-group v-if="ui.enable_expert" v-bind:label="$t('times_cooked')" label-for="popover-show_sortby" label-cols="8" class="mb-1">
<b-form-group v-bind:label="$t('times_cooked')" label-for="popover-show_sortby" label-cols="8" class="mb-1">
<b-form-checkbox switch v-model="ui.show_timescooked" id="popover-show_cooked" size="sm"></b-form-checkbox>
</b-form-group>
<b-form-group v-if="ui.enable_expert" v-bind:label="$t('make_now')" label-for="popover-show_sortby" label-cols="8" class="mb-1">
<b-form-group v-bind:label="$t('make_now')" label-for="popover-show_sortby" label-cols="8" class="mb-1">
<b-form-checkbox switch v-model="ui.show_makenow" id="popover-show_makenow" size="sm"></b-form-checkbox>
</b-form-group>
<b-form-group v-if="ui.enable_expert" v-bind:label="$t('last_cooked')" label-for="popover-show_sortby" label-cols="8" class="mb-1">
@ -142,9 +134,6 @@
<b-form-group v-bind:label="$t('tree_select')" label-for="popover-input-treeselect" label-cols="8" class="mb-1">
<b-form-checkbox switch v-model="ui.tree_select" id="popover-input-treeselect" size="sm"></b-form-checkbox>
</b-form-group>
<b-form-group v-bind:label="$t('enable_expert')" label-for="popover-input-expert" label-cols="8" class="mb-1">
<b-form-checkbox switch v-model="ui.enable_expert" id="popover-input-expert" size="sm"></b-form-checkbox>
</b-form-group>
<b-form-group v-if="debug" v-bind:label="$t('sql_debug')" label-for="popover-input-sqldebug" label-cols="8" class="mb-1">
<b-form-checkbox switch v-model="ui.sql_debug" id="popover-input-sqldebug" size="sm"></b-form-checkbox>
</b-form-group>
@ -481,11 +470,109 @@
</b-input-group>
</div>
</div>
<div v-if="ui.enable_expert && searchFiltered(false)" class="row justify-content-end small">
<!-- Buttons -->
<div class="row justify-content-end small">
<div class="col-auto">
<b-button class="my-0" variant="link" size="sm" @click="saveSearch">
<div>{{ $t("save_filter") }}</div>
<b-button class="my-0" variant="link" size="sm" @click="search.explain_visible = !search.explain_visible">
<div v-if="!search.explain_visible">
<i class="far fa-eye"></i>
{{ $t("explain") }}
</div>
<div v-else><i class="far fa-eye-slash"></i> {{ $t("explain") }}</div>
</b-button>
<b-button class="my-0" variant="link" size="sm" @click="search.expert_mode = !search.expert_mode">
<div v-if="!expertMode">
<i class="fas fa-circle"></i>
{{ $t("expert_mode") }}
</div>
<div v-if="expertMode">
<i class="far fa-circle"></i>
{{ $t("simple_mode") }}
</div>
</b-button>
<b-button class="my-0" variant="link" size="sm" @click="saveSearch">
<div><i class="far fa-save"></i> {{ $t("save_filter") }}</div>
</b-button>
</div>
</div>
<div class="row" v-if="search.explain_visible">
<div class="col-auto p-3">
<!-- Explain Div -->
<div>
Return all recipes that are matched
<span v-if="search.search_input">
by <i>{{ search.search_input }}</i> <br />
</span>
<span v-else> without any search term <br /> </span>
<!-- TODO sentence connection depending if filters exist -->
<span v-if="search.search_internal"> and are <span class="text-success">internal</span> <br /></span>
<span v-for="k in search.search_keywords" v-bind:key="k.id">
<template v-if="k.items.length > 0">
and
<b v-if="k.not">don't</b>
contain
<b v-if="k.operator">any</b><b v-else>all</b> of the following <span class="text-success">keywords</span>:
<i>{{ k.items.flatMap((x) => x.name).join(", ") }}</i>
<br />
</template>
</span>
<span v-for="k in search.search_foods" v-bind:key="k.id">
<template v-if="k.items.length > 0">
and
<b v-if="k.not">don't</b>
contain
<b v-if="k.operator">any</b><b v-else>all</b> of the following <span class="text-success">foods</span>:
<i>{{ k.items.flatMap((x) => x.name).join(", ") }}</i>
<br />
</template>
</span>
<span v-for="k in search.search_books" v-bind:key="k.id">
<template v-if="k.items.length > 0">
and
<b v-if="k.not">don't</b>
contain
<b v-if="k.operator">any</b><b v-else>all</b> of the following <span class="text-success">books</span>:
<i>{{ k.items.flatMap((x) => x.name).join(", ") }}</i>
<br />
</template>
</span>
<span v-if="search.makenow"> and you can <span class="text-success">make right now</span> (based on the on hand flag) <br /></span>
<span v-if="search.search_units.length > 0">
and contain <b v-if="search.search_units_or">any</b><b v-else>all</b> of the following <span class="text-success">units</span>:
<i>{{ search.search_units.flatMap((x) => x.name).join(", ") }}</i
><br />
</span>
<span v-if="search.search_rating !== undefined">
and have a <span class="text-success">rating</span> <template v-if="search.search_rating_gte">greater than</template><template v-else> less than</template> or
equal to {{ search.search_rating }}<br />
</span>
<span v-if="search.lastcooked !== undefined">
and have been <span class="text-success">last cooked</span> <template v-if="search.lastcooked_gte"> after</template><template v-else> before</template>
<i>{{ search.lastcooked }}</i
><br />
</span>
<span v-if="search.timescooked !== undefined">
and have <span class="text-success">been cooked</span> <template v-if="search.timescooked_gte"> at least</template><template v-else> less than</template> or
equal to<i>{{ search.timescooked }}</i> times <br />
</span>
<span v-if="search.sort_order.length > 0">
<span class="text-success">order</span> by
<i>{{ search.sort_order.flatMap((x) => x.text).join(", ") }}</i>
<br />
</span>
</div>
</div>
</div>
</div>
@ -504,7 +591,7 @@
refreshData(false)
"
>
{{ o.text }}
<span>{{ o.text }}</span>
</b-dropdown-item>
</div>
</b-dropdown>
@ -578,6 +665,7 @@ export default {
search: {
advanced_search_visible: false,
explain_visible: false,
search_input: "",
search_internal: false,
search_keywords: [
@ -599,9 +687,9 @@ export default {
{ items: [], operator: true, not: false },
],
search_units: [],
search_units_or: true,
search_rating: undefined,
search_rating_gte: true,
search_units_or: true,
search_filter: undefined,
timescooked: undefined,
timescooked_gte: true,
@ -733,24 +821,24 @@ export default {
let sort_order = []
let x = 1
const field = [
[this.$t("search_rank"), "score"],
[this.$t("Name"), "name"],
[this.$t("last_cooked"), "cookedon"],
[this.$t("Rating"), "rating"],
[this.$t("times_cooked"), "favorite"],
[this.$t("date_created"), "created_at"],
[this.$t("date_viewed"), "lastviewed"],
[this.$t("search_rank"), "score", "1-9", "9-1"],
[this.$t("Name"), "name", "A-z", "Z-a"],
[this.$t("last_cooked"), "cookedon", "↑", "↓"],
[this.$t("Rating"), "rating", "1-5", "5-1"],
[this.$t("times_cooked"), "favorite", "*-x", "x-*"],
[this.$t("date_created"), "created_at", "↑", "↓"],
[this.$t("date_viewed"), "lastviewed", "↑", "↓"],
]
field.forEach((f) => {
sort_order.push(
{
id: x,
text: `${f[0]} `,
text: `${f[0]} (${f[2]})`,
value: f[1],
},
{
id: x + 1,
text: `${f[0]} `,
text: `${f[0]} (${f[3]})`,
value: `-${f[1]}`,
}
)
@ -1054,7 +1142,7 @@ export default {
...this.addFields("keywords"),
...this.addFields("foods"),
...this.addFields("books"),
units: this.search.search_units,
units: this.search.search_units.flatMap((x) => x.id),
query: this.search.search_input,
rating: rating,
internal: this.search.search_internal,
@ -1128,6 +1216,11 @@ export default {
},
saveSearch: function () {
let filtername = window.prompt(this.$t("save_filter"), this.$t("filter_name"))
if (filtername === null || filtername.trim() === "") {
return
}
let search = this.buildParams(false)
;["page", "pageSize"].forEach((key) => {
delete search[key]
@ -1175,10 +1268,12 @@ export default {
height: 44px;
line-height: 22px;
}
.multiselect__tags {
border-radius: 0px !important;
line-height: 22px;
}
/* copied from vue-multiselect */
.vue-treeselect__placeholder {
font-weight: 400;
@ -1188,6 +1283,7 @@ export default {
margin-bottom: 10px;
padding-top: 2px;
}
/* copied from vue-multiselect */
.vue-treeselect__control-arrow-container {
width: 30px;