various improvements

This commit is contained in:
vabene1111
2025-03-31 16:06:20 +02:00
parent 235c5d6b4a
commit c03e82f094
11 changed files with 81 additions and 84 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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,

View File

@@ -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>

View File

@@ -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')"