mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-08 15:48:27 -05:00
Merge branch 'develop' into feature/importer_to_vue
# Conflicts: # cookbook/helper/recipe_url_import.py
This commit is contained in:
@@ -1,145 +1,126 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<br/>
|
||||
<div id="app">
|
||||
<br />
|
||||
|
||||
<template v-if="export_info !== undefined">
|
||||
<template v-if="export_info !== undefined">
|
||||
<template v-if="export_info.running">
|
||||
<h5 style="text-align: center">{{ $t("Exporting") }}...</h5>
|
||||
|
||||
<template v-if="export_info.running">
|
||||
<h5 style="text-align: center">{{ $t('Exporting') }}...</h5>
|
||||
<b-progress :max="export_info.total_recipes">
|
||||
<b-progress-bar :value="export_info.exported_recipes" :label="`${export_info.exported_recipes}/${export_info.total_recipes}`"></b-progress-bar>
|
||||
</b-progress>
|
||||
|
||||
<b-progress :max="export_info.total_recipes">
|
||||
<b-progress-bar :value="export_info.exported_recipes" :label="`${export_info.exported_recipes}/${export_info.total_recipes}`"></b-progress-bar>
|
||||
</b-progress>
|
||||
<loading-spinner :size="25"></loading-spinner>
|
||||
</template>
|
||||
|
||||
<loading-spinner :size="25"></loading-spinner>
|
||||
</template>
|
||||
<div class="row">
|
||||
<div class="col col-md-12" v-if="!export_info.running">
|
||||
<span>{{ $t("Export_finished") }}! </span> <a :href="`${resolveDjangoUrl('viewExport')}`">{{ $t("Return to export") }} </a><br /><br />
|
||||
|
||||
<div class="row">
|
||||
<div class="col col-md-12" v-if="!export_info.running">
|
||||
<span>{{ $t('Export_finished') }}! </span> <a :href="`${resolveDjangoUrl('viewExport') }`">{{ $t('Return to export') }} </a><br><br>
|
||||
{{ $t("If download did not start automatically: ") }}
|
||||
|
||||
{{ $t('If download did not start automatically: ') }}
|
||||
|
||||
<template v-if="export_info.expired">
|
||||
<a disabled><del>{{ $t('Download') }}</del></a> ({{ $t('Expired') }})
|
||||
</template>
|
||||
<a v-else :href="`/export-file/${export_id}/`" ref="downloadAnchor" >{{ $t('Download') }}</a>
|
||||
<template v-if="export_info.expired">
|
||||
<a disabled
|
||||
><del>{{ $t("Download") }}</del></a
|
||||
>
|
||||
({{ $t("Expired") }})
|
||||
</template>
|
||||
<a v-else :href="`${resolveDjangoUrl('view_export_file', export_id)}`" ref="downloadAnchor">{{ $t("Download") }}</a>
|
||||
|
||||
<br>
|
||||
{{ $t('The link will remain active for') }}
|
||||
|
||||
<template v-if="export_info.cache_duration > 3600">
|
||||
{{ export_info.cache_duration/3600 }}{{ $t('hr') }}
|
||||
</template>
|
||||
<template v-else-if="export_info.cache_duration > 60">
|
||||
{{ export_info.cache_duration/60 }}{{ $t('min') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ export_info.cache_duration }}{{ $t('sec') }}
|
||||
</template>
|
||||
<br />
|
||||
{{ $t("The link will remain active for") }}
|
||||
|
||||
<template v-if="export_info.cache_duration > 3600"> {{ export_info.cache_duration / 3600 }}{{ $t("hr") }} </template>
|
||||
<template v-else-if="export_info.cache_duration > 60"> {{ export_info.cache_duration / 60 }}{{ $t("min") }} </template>
|
||||
<template v-else> {{ export_info.cache_duration }}{{ $t("sec") }} </template>
|
||||
|
||||
<br>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col col-md-12">
|
||||
<label for="id_textarea">{{ $t('Information') }}</label>
|
||||
<textarea id="id_textarea" ref="output_text" class="form-control" style="height: 50vh"
|
||||
v-html="export_info.msg"
|
||||
disabled></textarea>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<br/>
|
||||
</template>
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div class="row">
|
||||
<div class="col col-md-12">
|
||||
<label for="id_textarea">{{ $t("Information") }}</label>
|
||||
<textarea id="id_textarea" ref="output_text" class="form-control" style="height: 50vh" v-html="export_info.msg" disabled></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<br />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import {BootstrapVue} from 'bootstrap-vue'
|
||||
import Vue from "vue"
|
||||
import { BootstrapVue } from "bootstrap-vue"
|
||||
|
||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||
import "bootstrap-vue/dist/bootstrap-vue.css"
|
||||
|
||||
import {ResolveUrlMixin, makeToast, ToastMixin} from "@/utils/utils";
|
||||
import { ResolveUrlMixin, makeToast, ToastMixin } from "@/utils/utils"
|
||||
|
||||
import LoadingSpinner from "@/components/LoadingSpinner";
|
||||
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||
|
||||
import {ApiApiFactory} from "@/utils/openapi/api.ts";
|
||||
import { ApiApiFactory } from "@/utils/openapi/api.ts"
|
||||
|
||||
Vue.use(BootstrapVue)
|
||||
|
||||
export default {
|
||||
name: 'ExportResponseView',
|
||||
mixins: [
|
||||
ResolveUrlMixin,
|
||||
ToastMixin,
|
||||
],
|
||||
components: {
|
||||
LoadingSpinner
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
export_id: window.EXPORT_ID,
|
||||
export_info: undefined,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.refreshData()
|
||||
this.$i18n.locale = window.CUSTOM_LOCALE
|
||||
|
||||
this.dynamicIntervalTimeout = 250 //initial refresh rate
|
||||
this.run = setTimeout(this.dynamicInterval.bind(this), this.dynamicIntervalTimeout)
|
||||
},
|
||||
methods: {
|
||||
dynamicInterval: function(){
|
||||
|
||||
//update frequently at start but slowdown as it takes longer
|
||||
this.dynamicIntervalTimeout = Math.round(this.dynamicIntervalTimeout*((1+Math.sqrt(5))/2))
|
||||
if(this.dynamicIntervalTimeout > 5000) this.dynamicIntervalTimeout = 5000
|
||||
clearInterval(this.run);
|
||||
this.run = setInterval(this.dynamicInterval.bind(this), this.dynamicIntervalTimeout);
|
||||
|
||||
if ((this.export_id !== null) && window.navigator.onLine && this.export_info.running) {
|
||||
name: "ExportResponseView",
|
||||
mixins: [ResolveUrlMixin, ToastMixin],
|
||||
components: {
|
||||
LoadingSpinner,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
export_id: window.EXPORT_ID,
|
||||
export_info: undefined,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.refreshData()
|
||||
let el = this.$refs.output_text
|
||||
el.scrollTop = el.scrollHeight;
|
||||
this.$i18n.locale = window.CUSTOM_LOCALE
|
||||
|
||||
if(this.export_info.expired)
|
||||
makeToast(this.$t("Error"), this.$t("The download link is expired!"), "danger")
|
||||
}
|
||||
this.dynamicIntervalTimeout = 250 //initial refresh rate
|
||||
this.run = setTimeout(this.dynamicInterval.bind(this), this.dynamicIntervalTimeout)
|
||||
},
|
||||
methods: {
|
||||
dynamicInterval: function () {
|
||||
//update frequently at start but slowdown as it takes longer
|
||||
this.dynamicIntervalTimeout = Math.round(this.dynamicIntervalTimeout * ((1 + Math.sqrt(5)) / 2))
|
||||
if (this.dynamicIntervalTimeout > 5000) this.dynamicIntervalTimeout = 5000
|
||||
clearInterval(this.run)
|
||||
this.run = setInterval(this.dynamicInterval.bind(this), this.dynamicIntervalTimeout)
|
||||
|
||||
startDownload: function(){
|
||||
this.$refs['downloadAnchor'].click()
|
||||
if (this.export_id !== null && window.navigator.onLine && this.export_info.running) {
|
||||
this.refreshData()
|
||||
let el = this.$refs.output_text
|
||||
el.scrollTop = el.scrollHeight
|
||||
|
||||
if (this.export_info.expired) makeToast(this.$t("Error"), this.$t("The download link is expired!"), "danger")
|
||||
}
|
||||
},
|
||||
|
||||
startDownload: function () {
|
||||
this.$refs["downloadAnchor"].click()
|
||||
},
|
||||
|
||||
refreshData: function () {
|
||||
let apiClient = new ApiApiFactory()
|
||||
|
||||
apiClient.retrieveExportLog(this.export_id).then((result) => {
|
||||
this.export_info = result.data
|
||||
this.export_info.expired = !this.export_info.possibly_not_expired
|
||||
|
||||
if (!this.export_info.running)
|
||||
this.$nextTick(() => {
|
||||
this.startDownload()
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
refreshData: function () {
|
||||
let apiClient = new ApiApiFactory()
|
||||
|
||||
apiClient.retrieveExportLog(this.export_id).then(result => {
|
||||
this.export_info = result.data
|
||||
this.export_info.expired = !this.export_info.possibly_not_expired
|
||||
|
||||
if(!this.export_info.running)
|
||||
this.$nextTick(()=>{ this.startDownload(); } )
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
|
||||
</style>
|
||||
<style></style>
|
||||
|
||||
@@ -1,174 +1,180 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<div id="app">
|
||||
<h2>{{ $t("Export") }}</h2>
|
||||
<div class="row">
|
||||
<div class="col col-md-12">
|
||||
<br />
|
||||
<!-- TODO get option dynamicaly -->
|
||||
<select class="form-control" v-model="recipe_app">
|
||||
<option value="DEFAULT">Default</option>
|
||||
<option value="SAFFRON">Saffron</option>
|
||||
<option value="RECIPESAGE">Recipe Sage</option>
|
||||
<option value="PDF">PDF (experimental)</option>
|
||||
</select>
|
||||
|
||||
<h2>{{ $t('Export') }}</h2>
|
||||
<div class="row">
|
||||
<div class="col col-md-12">
|
||||
<br />
|
||||
<b-form-checkbox v-model="export_all" @change="disabled_multiselect = $event" name="check-button" switch style="margin-top: 1vh">
|
||||
{{ $t("All recipes") }}
|
||||
</b-form-checkbox>
|
||||
|
||||
<br/>
|
||||
<!-- TODO get option dynamicaly -->
|
||||
<select class="form-control" v-model="recipe_app">
|
||||
<option value="DEFAULT">Default</option>
|
||||
<option value="SAFFRON">Saffron</option>
|
||||
<option value="RECIPESAGE">Recipe Sage</option>
|
||||
<option value="PDF">PDF (experimental)</option>
|
||||
</select>
|
||||
<!-- <multiselect
|
||||
:searchable="true"
|
||||
:disabled="disabled_multiselect"
|
||||
v-model="recipe_list"
|
||||
:options="recipes"
|
||||
:close-on-select="false"
|
||||
:clear-on-select="true"
|
||||
:hide-selected="true"
|
||||
:preserve-search="true"
|
||||
placeholder="Select Recipes"
|
||||
:taggable="false"
|
||||
label="name"
|
||||
track-by="id"
|
||||
id="id_recipes"
|
||||
:multiple="true"
|
||||
:loading="recipes_loading"
|
||||
@search-change="searchRecipes"
|
||||
>
|
||||
</multiselect> -->
|
||||
<generic-multiselect
|
||||
class="input-group-text m-0 p-0"
|
||||
@change="recipe_list = $event.val"
|
||||
label="name"
|
||||
:model="Models.RECIPE"
|
||||
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
|
||||
v-bind:placeholder="$t('Recipe')"
|
||||
:limit="20"
|
||||
:multiple="true"
|
||||
/>
|
||||
<generic-multiselect
|
||||
@change="filter = $event.val"
|
||||
:model="Models.CUSTOM_FILTER"
|
||||
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
|
||||
:placeholder="$t('Custom Filter')"
|
||||
:multiple="false"
|
||||
:limit="50"
|
||||
/>
|
||||
|
||||
<br/>
|
||||
<b-form-checkbox v-model="export_all" @change="disabled_multiselect=$event" name="check-button" switch style="margin-top: 1vh">
|
||||
{{ $t('All recipes') }}
|
||||
</b-form-checkbox>
|
||||
|
||||
<multiselect
|
||||
:searchable="true"
|
||||
:disabled="disabled_multiselect"
|
||||
v-model="recipe_list"
|
||||
:options="recipes"
|
||||
:close-on-select="false"
|
||||
:clear-on-select="true"
|
||||
:hide-selected="true"
|
||||
:preserve-search="true"
|
||||
placeholder="Select Recipes"
|
||||
:taggable="false"
|
||||
label="name"
|
||||
track-by="id"
|
||||
id="id_recipes"
|
||||
:multiple="true"
|
||||
:loading="recipes_loading"
|
||||
@search-change="searchRecipes">
|
||||
</multiselect>
|
||||
|
||||
<br/>
|
||||
<button @click="exportRecipe()" class="btn btn-primary shadow-none"><i class="fas fa-file-export"></i> {{ $t('Export') }}
|
||||
</button>
|
||||
<br />
|
||||
<button @click="exportRecipe()" class="btn btn-primary shadow-none"><i class="fas fa-file-export"></i> {{ $t("Export") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import {BootstrapVue} from 'bootstrap-vue'
|
||||
import Vue from "vue"
|
||||
import { BootstrapVue } from "bootstrap-vue"
|
||||
|
||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
||||
import "bootstrap-vue/dist/bootstrap-vue.css"
|
||||
|
||||
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||
|
||||
import LoadingSpinner from "@/components/LoadingSpinner";
|
||||
|
||||
import {StandardToasts, makeToast, resolveDjangoUrl} from "@/utils/utils";
|
||||
import Multiselect from "vue-multiselect";
|
||||
import {ApiApiFactory} from "@/utils/openapi/api.ts";
|
||||
import axios from "axios";
|
||||
|
||||
import { StandardToasts, makeToast, resolveDjangoUrl, ApiMixin } from "@/utils/utils"
|
||||
// import Multiselect from "vue-multiselect"
|
||||
import GenericMultiselect from "@/components/GenericMultiselect"
|
||||
import { ApiApiFactory } from "@/utils/openapi/api.ts"
|
||||
import axios from "axios"
|
||||
|
||||
Vue.use(BootstrapVue)
|
||||
|
||||
|
||||
export default {
|
||||
name: 'ExportView',
|
||||
/*mixins: [
|
||||
name: "ExportView",
|
||||
/*mixins: [
|
||||
ResolveUrlMixin,
|
||||
ToastMixin,
|
||||
],*/
|
||||
components: {Multiselect},
|
||||
data() {
|
||||
return {
|
||||
export_id: window.EXPORT_ID,
|
||||
loading: false,
|
||||
disabled_multiselect: false,
|
||||
components: { GenericMultiselect },
|
||||
mixins: [ApiMixin],
|
||||
data() {
|
||||
return {
|
||||
export_id: window.EXPORT_ID,
|
||||
loading: false,
|
||||
disabled_multiselect: false,
|
||||
|
||||
recipe_app: 'DEFAULT',
|
||||
recipe_list: [],
|
||||
recipes_loading: false,
|
||||
recipes: [],
|
||||
export_all: false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if(this.export_id)
|
||||
this.insertRequested()
|
||||
else
|
||||
this.searchRecipes('')
|
||||
},
|
||||
methods: {
|
||||
|
||||
insertRequested: function(){
|
||||
|
||||
let apiFactory = new ApiApiFactory()
|
||||
|
||||
this.recipes_loading = true
|
||||
|
||||
apiFactory.retrieveRecipe(this.export_id).then((response) => {
|
||||
this.recipes_loading = false
|
||||
this.recipe_list.push(response.data)
|
||||
|
||||
}).catch((err) => {
|
||||
console.log(err)
|
||||
StandardToasts.makeStandardToast(StandardToasts.FAIL_FETCH)
|
||||
}).then(e => this.searchRecipes(''))
|
||||
recipe_app: "DEFAULT",
|
||||
recipe_list: [],
|
||||
recipes_loading: false,
|
||||
recipes: [],
|
||||
export_all: false,
|
||||
filter: undefined,
|
||||
}
|
||||
},
|
||||
|
||||
searchRecipes: function (query) {
|
||||
|
||||
let apiFactory = new ApiApiFactory()
|
||||
|
||||
this.recipes_loading = true
|
||||
|
||||
let maxResultLenght = 1000
|
||||
apiFactory.listRecipes(query, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, 1, maxResultLenght).then((response) => {
|
||||
this.recipes = response.data.results;
|
||||
this.recipes_loading = false
|
||||
|
||||
}).catch((err) => {
|
||||
console.log(err)
|
||||
StandardToasts.makeStandardToast(StandardToasts.FAIL_FETCH)
|
||||
})
|
||||
mounted() {
|
||||
if (this.export_id) this.insertRequested()
|
||||
// else this.searchRecipes("")
|
||||
},
|
||||
methods: {
|
||||
insertRequested: function () {
|
||||
let apiFactory = new ApiApiFactory()
|
||||
|
||||
exportRecipe: function () {
|
||||
this.recipes_loading = true
|
||||
|
||||
if (this.recipe_list.length < 1 && this.export_all == false) {
|
||||
makeToast(this.$t("Error"), this.$t("Select at least one recipe"), "danger")
|
||||
return;
|
||||
}
|
||||
apiFactory
|
||||
.retrieveRecipe(this.export_id)
|
||||
.then((response) => {
|
||||
this.recipes_loading = false
|
||||
this.recipe_list.push(response.data)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
StandardToasts.makeStandardToast(StandardToasts.FAIL_FETCH)
|
||||
})
|
||||
// .then((e) => this.searchRecipes(""))
|
||||
},
|
||||
|
||||
this.error = undefined
|
||||
this.loading = true
|
||||
let formData = new FormData();
|
||||
formData.append('type', this.recipe_app);
|
||||
formData.append('all', this.export_all)
|
||||
// searchRecipes: function (query) {
|
||||
// this.recipes_loading = true
|
||||
|
||||
for (var i = 0; i < this.recipe_list.length; i++) {
|
||||
formData.append('recipes', this.recipe_list[i].id);
|
||||
}
|
||||
// this.genericAPI(this.Models.RECIPE, this.Actions.LIST, { query: query })
|
||||
// .then((response) => {
|
||||
// this.recipes = response.data.results
|
||||
// this.recipes_loading = false
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log(err)
|
||||
// StandardToasts.makeStandardToast(StandardToasts.FAIL_FETCH)
|
||||
// })
|
||||
// },
|
||||
|
||||
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
axios.post(resolveDjangoUrl('view_export',), formData).then((response) => {
|
||||
if (response.data['error'] !== undefined){
|
||||
makeToast(this.$t("Error"), response.data['error'],"warning")
|
||||
}else{
|
||||
window.location.href = resolveDjangoUrl('view_export_response', response.data['export_id'])
|
||||
}
|
||||
exportRecipe: function () {
|
||||
if (this.recipe_list.length < 1 && this.export_all == false && this.filter === undefined) {
|
||||
makeToast(this.$t("Error"), this.$t("Select at least one recipe"), "danger")
|
||||
return
|
||||
}
|
||||
|
||||
}).catch((err) => {
|
||||
this.error = err.data
|
||||
this.loading = false
|
||||
console.log(err)
|
||||
makeToast(this.$t("Error"), this.$t("There was an error loading a resource!"), "warning")
|
||||
})
|
||||
this.error = undefined
|
||||
this.loading = true
|
||||
let formData = new FormData()
|
||||
formData.append("type", this.recipe_app)
|
||||
formData.append("all", this.export_all)
|
||||
formData.append("filter", this.filter?.id ?? null)
|
||||
|
||||
for (var i = 0; i < this.recipe_list.length; i++) {
|
||||
formData.append("recipes", this.recipe_list[i].id)
|
||||
}
|
||||
|
||||
axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
axios
|
||||
.post(resolveDjangoUrl("view_export"), formData)
|
||||
.then((response) => {
|
||||
if (response.data["error"] !== undefined) {
|
||||
makeToast(this.$t("Error"), response.data["error"], "warning")
|
||||
} else {
|
||||
window.location.href = resolveDjangoUrl("view_export_response", response.data["export_id"])
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.error = err.data
|
||||
this.loading = false
|
||||
console.log(err)
|
||||
makeToast(this.$t("Error"), this.$t("There was an error loading a resource!"), "warning")
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
|
||||
|
||||
<style>
|
||||
|
||||
|
||||
</style>
|
||||
<style></style>
|
||||
|
||||
@@ -65,8 +65,11 @@
|
||||
:preserve-search="true"
|
||||
:internal-search="false"
|
||||
:limit="options_limit"
|
||||
placeholder="Select Keyword"
|
||||
tag-placeholder="Add Keyword"
|
||||
:placeholder="$t('select_keyword')"
|
||||
:tag-placeholder="$t('add_keyword')"
|
||||
:select-label="$t('Select')"
|
||||
:selected-label="$t('Selected')"
|
||||
:deselect-label="$t('remove_selection')"
|
||||
:taggable="true"
|
||||
@tag="addKeyword"
|
||||
label="label"
|
||||
@@ -76,6 +79,7 @@
|
||||
:loading="keywords_loading"
|
||||
@search-change="searchKeywords"
|
||||
>
|
||||
<template v-slot:noOptions>{{ $t("empty_list") }}</template>
|
||||
</multiselect>
|
||||
</div>
|
||||
</div>
|
||||
@@ -244,8 +248,10 @@
|
||||
:clear-on-select="true"
|
||||
:allow-empty="true"
|
||||
:preserve-search="true"
|
||||
placeholder="Select File"
|
||||
select-label="Select"
|
||||
:placeholder="$t('select_file')"
|
||||
:select-label="$t('Select')"
|
||||
:selected-label="$t('Selected')"
|
||||
:deselect-label="$t('remove_selection')"
|
||||
:id="'id_step_' + step.id + '_file'"
|
||||
label="name"
|
||||
track-by="name"
|
||||
@@ -254,6 +260,7 @@
|
||||
style="flex-grow: 1; flex-shrink: 1; flex-basis: 0"
|
||||
@search-change="searchFiles"
|
||||
>
|
||||
<template v-slot:noOptions>{{ $t("empty_list") }}</template>
|
||||
</multiselect>
|
||||
<b-input-group-append>
|
||||
<b-button
|
||||
@@ -283,14 +290,17 @@
|
||||
:preserve-search="true"
|
||||
:internal-search="false"
|
||||
:limit="options_limit"
|
||||
placeholder="Select Recipe"
|
||||
select-label="Select"
|
||||
:placeholder="$t('select_recipe')"
|
||||
:select-label="$t('Select')"
|
||||
:selected-label="$t('Selected')"
|
||||
:deselect-label="$t('remove_selection')"
|
||||
:id="'id_step_' + step.id + '_recipe'"
|
||||
:custom-label="(opt) => recipes.find((x) => x.id === opt).name"
|
||||
:multiple="false"
|
||||
:loading="recipes_loading"
|
||||
@search-change="searchRecipes"
|
||||
>
|
||||
<template v-slot:noOptions>{{ $t("empty_list") }}</template>
|
||||
</multiselect>
|
||||
</div>
|
||||
</div>
|
||||
@@ -340,9 +350,11 @@
|
||||
:preserve-search="true"
|
||||
:internal-search="false"
|
||||
:limit="options_limit"
|
||||
placeholder="Select Unit"
|
||||
tag-placeholder="Create"
|
||||
select-label="Select"
|
||||
:placeholder="$t('select_unit')"
|
||||
:tag-placeholder="$t('Create')"
|
||||
:select-label="$t('Select')"
|
||||
:selected-label="$t('Selected')"
|
||||
:deselect-label="$t('remove_selection')"
|
||||
:taggable="true"
|
||||
@tag="addUnitType"
|
||||
:id="`unit_${step_index}_${index}`"
|
||||
@@ -352,6 +364,7 @@
|
||||
:loading="units_loading"
|
||||
@search-change="searchUnits"
|
||||
>
|
||||
<template v-slot:noOptions>{{ $t("empty_list") }}</template>
|
||||
</multiselect>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-6 small-padding" v-if="!ingredient.is_header">
|
||||
@@ -367,9 +380,11 @@
|
||||
:preserve-search="true"
|
||||
:internal-search="false"
|
||||
:limit="options_limit"
|
||||
placeholder="Select Food"
|
||||
tag-placeholder="Create"
|
||||
select-label="Select"
|
||||
:placeholder="$t('select_food')"
|
||||
:tag-placeholder="$t('Create')"
|
||||
:select-label="$t('Select')"
|
||||
:selected-label="$t('Selected')"
|
||||
:deselect-label="$t('remove_selection')"
|
||||
:taggable="true"
|
||||
@tag="addFoodType"
|
||||
:id="`ingredient_${step_index}_${index}`"
|
||||
@@ -379,6 +394,7 @@
|
||||
:loading="foods_loading"
|
||||
@search-change="searchFoods"
|
||||
>
|
||||
<template v-slot:noOptions>{{ $t("empty_list") }}</template>
|
||||
</multiselect>
|
||||
</div>
|
||||
<div class="small-padding" v-bind:class="{ 'col-lg-4 col-md-6': !ingredient.is_header, 'col-lg-12 col-md-12': ingredient.is_header }">
|
||||
@@ -804,7 +820,7 @@ export default {
|
||||
no_amount: false,
|
||||
})
|
||||
this.sortIngredients(step)
|
||||
this.$nextTick(() => document.getElementById(`amount_${this.recipe.steps.indexOf(step)}_${step.ingredients.length - 1}`).focus())
|
||||
this.$nextTick(() => document.getElementById(`amount_${this.recipe.steps.indexOf(step)}_${step.ingredients.length - 1}`).select())
|
||||
},
|
||||
removeIngredient: function (step, ingredient) {
|
||||
if (confirm(this.$t("confirm_delete", { object: this.$t("Ingredient") }))) {
|
||||
@@ -985,6 +1001,7 @@ export default {
|
||||
unit: unit,
|
||||
food: { name: result.data.food },
|
||||
note: result.data.note,
|
||||
original_text: ing,
|
||||
})
|
||||
})
|
||||
order++
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -934,6 +934,8 @@ export default {
|
||||
this.ui = Object.assign({}, this.ui, this.$cookies.get(SETTINGS_COOKIE_NAME))
|
||||
}
|
||||
})
|
||||
this.$i18n.locale = window.CUSTOM_LOCALE
|
||||
console.log(window.CUSTOM_LOCALE)
|
||||
},
|
||||
methods: {
|
||||
// this.genericAPI inherited from ApiMixin
|
||||
@@ -1491,7 +1493,7 @@ export default {
|
||||
flex-grow: 1;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
height: 6vh;
|
||||
height: 60vh; /* TODO use proper fill height here to not render list underneath bottom buttons */
|
||||
padding-right: 8px !important;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user