mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
various improvements
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<component :is="compiled_instructions" :ingredient_factor="ingredient_factor" :instructions_html="instructions_html"></component>
|
||||
<!-- <div v-html="instructions_html"></div>-->
|
||||
<!-- <div v-html="instructions_html"></div>-->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -31,7 +31,8 @@ export default defineComponent({
|
||||
ingredient_factor: {type: Number, required: true},
|
||||
},
|
||||
components: {ScalableNumber,},
|
||||
template: `<div>${this.instructions_html}</div>`
|
||||
template: `
|
||||
<div>${this.instructions_html}</div>`
|
||||
}))
|
||||
}
|
||||
},
|
||||
@@ -41,3 +42,14 @@ export default defineComponent({
|
||||
})
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
/**
|
||||
vuetify removes all margins and paddings which break layout, re-add them by reverting vuetify change
|
||||
*/
|
||||
p, ol, ul, li {
|
||||
padding: revert;
|
||||
margin: revert;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<v-col cols="12" md="6" v-if="step.ingredients.length > 0">
|
||||
<ingredients-table v-model="step.ingredients" :ingredient-factor="ingredientFactor"></ingredients-table>
|
||||
</v-col>
|
||||
<v-col cols="12" md="6">
|
||||
<v-col cols="12" md="6" class="markdown-body">
|
||||
<instructions :instructions_html="step.instructionsMarkdown" :ingredient_factor="ingredientFactor" v-if="step.instructionsMarkdown != undefined"></instructions>
|
||||
<!-- sub recipes dont have a correct schema, thus they use different variable naming -->
|
||||
<instructions :instructions_html="step.instructions_markdown" :ingredient_factor="ingredientFactor" v-else></instructions>
|
||||
|
||||
@@ -55,15 +55,15 @@
|
||||
<v-row v-for="(ingredient, index) in step.ingredients" dense>
|
||||
<v-col cols="2" v-if="!ingredient.isHeader">
|
||||
<v-text-field :id="`id_input_amount_${step.id}_${index}`" :label="$t('Amount')" type="number" v-model="ingredient.amount" density="compact"
|
||||
hide-details>
|
||||
hide-details v-if="!ingredient.noAmount">
|
||||
|
||||
<template #prepend>
|
||||
<v-icon icon="$dragHandle" class="drag-handle cursor-grab"></v-icon>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="3" v-if="!ingredient.isHeader">
|
||||
<model-select model="Unit" v-model="ingredient.unit" density="compact" allow-create hide-details></model-select>
|
||||
<v-col cols="3" v-if="!ingredient.isHeader ">
|
||||
<model-select model="Unit" v-model="ingredient.unit" density="compact" allow-create hide-details v-if="!ingredient.noAmount"></model-select>
|
||||
</v-col>
|
||||
<v-col cols="3" v-if="!ingredient.isHeader">
|
||||
<model-select model="Food" v-model="ingredient.food" density="compact" allow-create hide-details></model-select>
|
||||
@@ -84,6 +84,9 @@
|
||||
<v-list-item link>
|
||||
<v-switch v-model="step.ingredients[index].isHeader" :label="$t('Headline')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item link>
|
||||
<v-switch v-model="step.ingredients[index].noAmount" :label="$t('Disable_Amount')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item @click="editingIngredientIndex = index; dialogIngredientSorter = true" prepend-icon="fa-solid fa-sort">{{
|
||||
$t('Move')
|
||||
}}
|
||||
@@ -120,7 +123,7 @@
|
||||
</v-col>
|
||||
<v-col cols="12">
|
||||
<v-label>{{ $t('Instructions') }}</v-label>
|
||||
<v-alert @click="dialogMarkdownEditor = true" class="mt-2 cursor-pointer" min-height="52px">
|
||||
<v-alert @click="dialogMarkdownEditor = true" class="mt-2 cursor-pointer" min-height="52px" v-if="mobile">
|
||||
<template v-if="step.instruction != '' && step.instruction != null">
|
||||
{{ step.instruction }}
|
||||
</template>
|
||||
@@ -128,6 +131,11 @@
|
||||
<i> {{ $t('InstructionsEditHelp') }} </i>
|
||||
</template>
|
||||
</v-alert>
|
||||
<template v-else>
|
||||
<p>
|
||||
<step-markdown-editor class="h-100" v-model="step"></step-markdown-editor>
|
||||
</p>
|
||||
</template>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
@@ -352,7 +360,11 @@ function handleIngredientNoteTab(event: KeyboardEvent, index: number) {
|
||||
* insert a new ingredient and focus its first input
|
||||
*/
|
||||
function insertAndFocusIngredient() {
|
||||
let ingredient = {} as Ingredient
|
||||
let ingredient = {
|
||||
amount: 0,
|
||||
unit: null,
|
||||
food: null,
|
||||
} as Ingredient
|
||||
|
||||
if (defaultUnit.value != null) {
|
||||
ingredient.unit = defaultUnit.value
|
||||
|
||||
@@ -2,23 +2,23 @@
|
||||
<mavon-editor v-model="step.instruction" :autofocus="false"
|
||||
style="z-index: auto" :id="'id_instruction_' + step.id"
|
||||
:language="'en'"
|
||||
:toolbars="md_editor_toolbars" :defaultOpen="'edit'">
|
||||
:toolbars="md_editor_toolbars" :defaultOpen="'edit'" ref="markdownEditor">
|
||||
<template #left-toolbar-after>
|
||||
<span class="op-icon-divider"></span>
|
||||
<button
|
||||
type="button"
|
||||
@click="step.instruction+= ' {{ scale(100) }}'"
|
||||
@click="insertTextAtPosition('{{ scale(100) }} ')"
|
||||
class="op-icon fas fa-calculator"
|
||||
aria-hidden="true"
|
||||
:title="$t('ScalableNumber')"
|
||||
></button>
|
||||
<button class="op-icon fa-solid fa-code">
|
||||
<button class="op-icon fa-solid fa-code" v-if="templates.length > 0" type="button">
|
||||
<v-menu activator="parent">
|
||||
<v-list density="compact">
|
||||
|
||||
<v-list-subheader>{{$t('Ingredients')}}</v-list-subheader>
|
||||
<v-list-item
|
||||
v-for="template in templates"
|
||||
@click="step.instruction+= template.template"
|
||||
@click="insertTextAtPosition(template.template + ' ')"
|
||||
>
|
||||
<ingredient-string :ingredient="template.ingredient"></ingredient-string>
|
||||
</v-list-item>
|
||||
@@ -34,9 +34,11 @@
|
||||
import {Ingredient, Step} from "@/openapi";
|
||||
import 'mavon-editor/dist/css/index.css'
|
||||
import IngredientString from "@/components/display/IngredientString.vue";
|
||||
import {computed} from "vue";
|
||||
import {computed, nextTick, useTemplateRef} from "vue";
|
||||
import editor from "mavon-editor";
|
||||
|
||||
const step = defineModel<Step>({required: true})
|
||||
const markdownEditor = useTemplateRef('markdownEditor')
|
||||
|
||||
type IngredientTemplate = {
|
||||
name: string,
|
||||
@@ -58,6 +60,24 @@ const templates = computed(() => {
|
||||
return templateList
|
||||
})
|
||||
|
||||
/**
|
||||
* insert the given text at the caret position into the text
|
||||
* @param text
|
||||
*/
|
||||
function insertTextAtPosition(text: string){
|
||||
let textarea = markdownEditor.value.getTextareaDom()
|
||||
let position = textarea.selectionStart
|
||||
if (step.value.instruction){
|
||||
step.value.instruction = step.value.instruction.slice(0, position) + text + step.value.instruction.slice(position)
|
||||
|
||||
nextTick(() => {
|
||||
textarea.focus()
|
||||
textarea.selectionStart = position + text.length
|
||||
textarea.selectionEnd = position + text.length
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const md_editor_toolbars = {
|
||||
bold: true,
|
||||
italic: true,
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
<v-btn color="delete" prepend-icon="$delete" v-if="isUpdate && !modelClass.model.disableDelete" :disabled="loading">{{ $t('Delete') }}
|
||||
<delete-confirm-dialog :object-name="objectName" :model-name="$t(modelClass.model.localizationKey)" @delete="emit('delete')"></delete-confirm-dialog>
|
||||
</v-btn>
|
||||
<v-btn color="save" prepend-icon="$create" @click="emit('save')" v-if="!isUpdate && !modelClass.model.disableCreate" :disabled="loading">{{ $t('Create') }}</v-btn>
|
||||
<v-btn color="save" prepend-icon="$save" @click="emit('save')" v-if="isUpdate && !modelClass.model.disableUpdate" :disabled="loading">{{ $t('Save') }}</v-btn>
|
||||
<v-btn color="save" prepend-icon="$create" @click="emit('save')" v-if="!isUpdate && !modelClass.model.disableCreate" :loading="loading">{{ $t('Create') }}</v-btn>
|
||||
<v-btn color="save" prepend-icon="$save" @click="emit('save')" v-if="isUpdate && !modelClass.model.disableUpdate" :loading="loading"> {{ $t('Save') }}</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" md="6">
|
||||
<v-file-upload v-model="file" @update:modelValue="updateUserFileName"
|
||||
<v-file-upload v-model="file"
|
||||
:title="(mobile) ? $t('Select_File') : $t('DragToUpload')"
|
||||
:browse-text="$t('Select_File')"
|
||||
:divider-text="$t('or')"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<v-card>
|
||||
<v-card-text class="pt-2 pb-2">
|
||||
<v-btn variant="flat" @click="router.go(-1)" prepend-icon="fa-solid fa-arrow-left">{{ $t('Back') }}</v-btn>
|
||||
<v-btn variant="flat" @click="router.push({name : 'RecipeViewPage', params: {id: props.id}})" class="float-right" prepend-icon="fa-solid fa-eye" v-if="props.id && model.toLowerCase() == 'recipe'">{{$t('View')}}</v-btn>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
@@ -21,7 +22,7 @@
|
||||
|
||||
import {useRouter} from "vue-router";
|
||||
import {EditorSupportedModels, getGenericModelFromString} from "@/types/Models";
|
||||
import {defineAsyncComponent, onMounted, PropType, shallowRef} from "vue";
|
||||
import {defineAsyncComponent, onMounted, PropType, shallowRef, watch} from "vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const {t} = useI18n()
|
||||
@@ -35,6 +36,13 @@ const editorComponent = shallowRef(defineAsyncComponent(() => import(`@/componen
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
//TODO quick hack for some edge cases, move to proper reinitialization of all model editors should this case occur (currently only recipe editor create new via navigation btn)
|
||||
watch(() => props.id, (newValue, oldValue) => {
|
||||
if(newValue != oldValue){
|
||||
location.reload()
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* after creation open object with correct URL in edit mode
|
||||
* @param obj obj that was created
|
||||
|
||||
@@ -1,27 +1,16 @@
|
||||
<template>
|
||||
<v-container>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-text-field v-model="dateTest1" label="Test 1 - text field type date" type="date"></v-text-field>
|
||||
<p>Test P1</p>
|
||||
<p>Test 2P</p>
|
||||
<ol>
|
||||
<li>Test 1</li>
|
||||
<li>Test 2</li>
|
||||
<li>Test 3</li>
|
||||
</ol>
|
||||
<p>Text Bla Bla3</p>
|
||||
</v-col>
|
||||
<v-col>
|
||||
{{ dateTest1 }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-date-input v-model="dateTest2" label="Test 2 - date input"></v-date-input>
|
||||
</v-col>
|
||||
<v-col> {{ dateTest2 }}</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-date-input v-model="dateTest3" label="Test 3 - date input with routeQueryModel"></v-date-input>
|
||||
</v-col>
|
||||
<v-col> {{ dateTest3 }}</v-col>
|
||||
</v-row>
|
||||
|
||||
|
||||
@@ -36,50 +25,6 @@ import {useRouteQuery} from "@vueuse/router";
|
||||
import {DateTime} from "luxon";
|
||||
|
||||
|
||||
const dateTest1 = ref(null)
|
||||
const dateTest2 = ref(null)
|
||||
|
||||
const dateTest3 = useRouteQuery('cookedonGte', null, {
|
||||
transform: {
|
||||
get: (value: string | null | Date) => {
|
||||
|
||||
if (value == null) {
|
||||
console.log('get null')
|
||||
return null
|
||||
} else {
|
||||
console.log('get', new Date(value), (new Date(value)).getMonth())
|
||||
return new Date(value)
|
||||
}
|
||||
},
|
||||
set: value => {
|
||||
|
||||
if (value == null) {
|
||||
console.log('-- set null')
|
||||
return null
|
||||
} else {
|
||||
console.log('-- set', DateTime.fromJSDate(new Date(value)).toISODate())
|
||||
return DateTime.fromJSDate(new Date(value)).toISODate()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const typeOfDateTest1 = computed(() => {
|
||||
return dateTest1 instanceof Date
|
||||
})
|
||||
|
||||
const typeOfDateTest2 = computed(() => {
|
||||
return dateTest2 instanceof Date
|
||||
})
|
||||
|
||||
watch(dateTest1, () => {
|
||||
console.log(dateTest1.value, dateTest1.value.getMonth())
|
||||
})
|
||||
|
||||
watch(dateTest2, () => {
|
||||
console.log(dateTest2.value, dateTest2.value.getMonth())
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user