mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-11-12 06:52:32 -05:00
chore: Add Stricter Frontend Formatting (#6262)
This commit is contained in:
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -59,8 +59,11 @@
|
|||||||
"netlify.toml": "runtime.txt",
|
"netlify.toml": "runtime.txt",
|
||||||
"README.md": "LICENSE, SECURITY.md"
|
"README.md": "LICENSE, SECURITY.md"
|
||||||
},
|
},
|
||||||
|
"[typescript]": {
|
||||||
|
"editor.formatOnSave": true
|
||||||
|
},
|
||||||
"[vue]": {
|
"[vue]": {
|
||||||
"editor.formatOnSave": false
|
"editor.formatOnSave": true
|
||||||
},
|
},
|
||||||
"[python]": {
|
"[python]": {
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import subprocess
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -105,12 +106,16 @@ def main():
|
|||||||
# Flatten list of lists
|
# Flatten list of lists
|
||||||
all_children = [item for sublist in all_children for item in sublist]
|
all_children = [item for sublist in all_children for item in sublist]
|
||||||
|
|
||||||
|
out_path = GENERATED / "__init__.py"
|
||||||
render_python_template(
|
render_python_template(
|
||||||
TEMPLATE,
|
TEMPLATE,
|
||||||
GENERATED / "__init__.py",
|
out_path,
|
||||||
{"children": all_children},
|
{"children": all_children},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
subprocess.run(["poetry", "run", "ruff", "check", str(out_path), "--fix"])
|
||||||
|
subprocess.run(["poetry", "run", "ruff", "format", str(out_path)])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
from utils import PROJECT_DIR, log, render_python_template
|
from utils import PROJECT_DIR, log, render_python_template
|
||||||
@@ -84,16 +85,23 @@ def find_modules(root: pathlib.Path) -> list[Modules]:
|
|||||||
return modules
|
return modules
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main() -> None:
|
||||||
modules = find_modules(SCHEMA_PATH)
|
modules = find_modules(SCHEMA_PATH)
|
||||||
|
|
||||||
|
template_paths: list[pathlib.Path] = []
|
||||||
for module in modules:
|
for module in modules:
|
||||||
log.debug(f"Module: {module.directory.name}")
|
log.debug(f"Module: {module.directory.name}")
|
||||||
for file in module.files:
|
for file in module.files:
|
||||||
log.debug(f" File: {file.import_path}")
|
log.debug(f" File: {file.import_path}")
|
||||||
log.debug(f" Classes: [{', '.join(file.classes)}]")
|
log.debug(f" Classes: [{', '.join(file.classes)}]")
|
||||||
|
|
||||||
render_python_template(template, module.directory / "__init__.py", {"module": module})
|
template_path = module.directory / "__init__.py"
|
||||||
|
template_paths.append(template_path)
|
||||||
|
render_python_template(template, template_path, {"module": module})
|
||||||
|
|
||||||
|
path_args = (str(p) for p in template_paths)
|
||||||
|
subprocess.run(["poetry", "run", "ruff", "check", *path_args, "--fix"])
|
||||||
|
subprocess.run(["poetry", "run", "ruff", "format", *path_args])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
@@ -189,6 +190,7 @@ def generate_typescript_types() -> None: # noqa: C901
|
|||||||
skipped_dirs: list[Path] = []
|
skipped_dirs: list[Path] = []
|
||||||
failed_modules: list[Path] = []
|
failed_modules: list[Path] = []
|
||||||
|
|
||||||
|
out_paths: list[Path] = []
|
||||||
for module in schema_path.iterdir():
|
for module in schema_path.iterdir():
|
||||||
if module.is_dir() and module.stem in ignore_dirs:
|
if module.is_dir() and module.stem in ignore_dirs:
|
||||||
skipped_dirs.append(module)
|
skipped_dirs.append(module)
|
||||||
@@ -205,10 +207,18 @@ def generate_typescript_types() -> None: # noqa: C901
|
|||||||
path_as_module = path_to_module(module)
|
path_as_module = path_to_module(module)
|
||||||
generate_typescript_defs(path_as_module, str(out_path), exclude=("MealieModel")) # type: ignore
|
generate_typescript_defs(path_as_module, str(out_path), exclude=("MealieModel")) # type: ignore
|
||||||
clean_output_file(out_path)
|
clean_output_file(out_path)
|
||||||
|
out_paths.append(out_path)
|
||||||
except Exception:
|
except Exception:
|
||||||
failed_modules.append(module)
|
failed_modules.append(module)
|
||||||
log.exception(f"Module Error: {module}")
|
log.exception(f"Module Error: {module}")
|
||||||
|
|
||||||
|
# Run ESLint --fix on the files to clean up any formatting issues
|
||||||
|
subprocess.run(
|
||||||
|
["yarn", "lint", "--fix", *(str(path) for path in out_paths)],
|
||||||
|
check=True,
|
||||||
|
cwd=PROJECT_DIR / "frontend",
|
||||||
|
)
|
||||||
|
|
||||||
log.debug("\n📁 Skipped Directories:")
|
log.debug("\n📁 Skipped Directories:")
|
||||||
for skipped_dir in skipped_dirs:
|
for skipped_dir in skipped_dirs:
|
||||||
log.debug(f" 📁 {skipped_dir.name}")
|
log.debug(f" 📁 {skipped_dir.name}")
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import logging
|
import logging
|
||||||
import subprocess
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -23,11 +22,6 @@ def render_python_template(template_file: Path | str, dest: Path, data: dict):
|
|||||||
|
|
||||||
dest.write_text(text)
|
dest.write_text(text)
|
||||||
|
|
||||||
# lint/format file with Ruff
|
|
||||||
log.info(f"Formatting {dest}")
|
|
||||||
subprocess.run(["poetry", "run", "ruff", "check", str(dest), "--fix"])
|
|
||||||
subprocess.run(["poetry", "run", "ruff", "format", str(dest)])
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class CodeSlicer:
|
class CodeSlicer:
|
||||||
@@ -37,7 +31,7 @@ class CodeSlicer:
|
|||||||
indentation: str | None
|
indentation: str | None
|
||||||
text: list[str]
|
text: list[str]
|
||||||
|
|
||||||
_next_line = None
|
_next_line: int | None = None
|
||||||
|
|
||||||
def purge_lines(self) -> None:
|
def purge_lines(self) -> None:
|
||||||
start = self.start + 1
|
start = self.start + 1
|
||||||
|
|||||||
@@ -5,8 +5,14 @@
|
|||||||
density="compact"
|
density="compact"
|
||||||
elevation="0"
|
elevation="0"
|
||||||
>
|
>
|
||||||
<BaseDialog v-model="deleteDialog" :title="$t('recipe.delete-recipe')" color="error"
|
<BaseDialog
|
||||||
:icon="$globals.icons.alertCircle" can-confirm @confirm="emitDelete()">
|
v-model="deleteDialog"
|
||||||
|
:title="$t('recipe.delete-recipe')"
|
||||||
|
color="error"
|
||||||
|
:icon="$globals.icons.alertCircle"
|
||||||
|
can-confirm
|
||||||
|
@confirm="emitDelete()"
|
||||||
|
>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
{{ $t("recipe.delete-confirmation") }}
|
{{ $t("recipe.delete-confirmation") }}
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
@@ -15,7 +21,14 @@
|
|||||||
<v-spacer />
|
<v-spacer />
|
||||||
<div v-if="!open" class="custom-btn-group ma-1">
|
<div v-if="!open" class="custom-btn-group ma-1">
|
||||||
<RecipeFavoriteBadge v-if="loggedIn" color="info" button-style :recipe-id="recipe.id!" show-always />
|
<RecipeFavoriteBadge v-if="loggedIn" color="info" button-style :recipe-id="recipe.id!" show-always />
|
||||||
<RecipeTimelineBadge v-if="loggedIn" class="ml-1" color="info" button-style :slug="recipe.slug" :recipe-name="recipe.name!" />
|
<RecipeTimelineBadge
|
||||||
|
v-if="loggedIn"
|
||||||
|
class="ml-1"
|
||||||
|
color="info"
|
||||||
|
button-style
|
||||||
|
:slug="recipe.slug"
|
||||||
|
:recipe-name="recipe.name!"
|
||||||
|
/>
|
||||||
<div v-if="loggedIn">
|
<div v-if="loggedIn">
|
||||||
<v-tooltip v-if="canEdit" location="bottom" color="info">
|
<v-tooltip v-if="canEdit" location="bottom" color="info">
|
||||||
<template #activator="{ props: tooltipProps }">
|
<template #activator="{ props: tooltipProps }">
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<BaseDialog v-model="dialog" :title="$t('data-pages.manage-aliases')" :icon="$globals.icons.edit"
|
<BaseDialog
|
||||||
:submit-icon="$globals.icons.check" :submit-text="$t('general.confirm')" can-submit @submit="saveAliases"
|
v-model="dialog"
|
||||||
@cancel="$emit('cancel')">
|
:title="$t('data-pages.manage-aliases')"
|
||||||
|
:icon="$globals.icons.edit"
|
||||||
|
:submit-icon="$globals.icons.check"
|
||||||
|
:submit-text="$t('general.confirm')"
|
||||||
|
can-submit
|
||||||
|
@submit="saveAliases"
|
||||||
|
@cancel="$emit('cancel')"
|
||||||
|
>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-container>
|
<v-container>
|
||||||
<v-row v-for="alias, i in aliases" :key="i">
|
<v-row v-for="alias, i in aliases" :key="i">
|
||||||
@@ -10,13 +17,16 @@
|
|||||||
<v-text-field v-model="alias.name" :label="$t('general.name')" :rules="[validators.required]" />
|
<v-text-field v-model="alias.name" :label="$t('general.name')" :rules="[validators.required]" />
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="2">
|
<v-col cols="2">
|
||||||
<BaseButtonGroup :buttons="[
|
<BaseButtonGroup
|
||||||
|
:buttons="[
|
||||||
{
|
{
|
||||||
icon: $globals.icons.delete,
|
icon: $globals.icons.delete,
|
||||||
text: $t('general.delete'),
|
text: $t('general.delete'),
|
||||||
event: 'delete',
|
event: 'delete',
|
||||||
},
|
},
|
||||||
]" @delete="deleteAlias(i)" />
|
]"
|
||||||
|
@delete="deleteAlias(i)"
|
||||||
|
/>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|||||||
@@ -113,9 +113,13 @@
|
|||||||
/>
|
/>
|
||||||
<v-divider />
|
<v-divider />
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col class="overflow-y-auto"
|
<v-col
|
||||||
|
class="overflow-y-auto"
|
||||||
:class="$vuetify.display.smAndDown ? 'py-2': 'py-6'"
|
:class="$vuetify.display.smAndDown ? 'py-2': 'py-6'"
|
||||||
style="height: 100%" cols="12" sm="7">
|
style="height: 100%"
|
||||||
|
cols="12"
|
||||||
|
sm="7"
|
||||||
|
>
|
||||||
<h2 class="text-h5 px-4 font-weight-medium opacity-80">
|
<h2 class="text-h5 px-4 font-weight-medium opacity-80">
|
||||||
{{ $t('recipe.instructions') }}
|
{{ $t('recipe.instructions') }}
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</v-select>
|
</v-select>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
class="mb-2 mx-n2"
|
class="mb-2 mx-n2"
|
||||||
>
|
>
|
||||||
<v-card-title class="text-h5 font-weight-medium opacity-80">
|
<v-card-title class="text-h5 font-weight-medium opacity-80">
|
||||||
{{ $t('recipe.api-extras') }}
|
{{ $t('recipe.api-extras') }}
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<v-divider class="ml-4" />
|
<v-divider class="ml-4" />
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
{{ $t('recipe.api-extras-description') }}
|
{{ $t('recipe.api-extras-description') }}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<!-- eslint-disable vue/no-mutating-props -->
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
|
|||||||
@@ -4,19 +4,22 @@
|
|||||||
<section>
|
<section>
|
||||||
<v-container class="ma-0 pa-0">
|
<v-container class="ma-0 pa-0">
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col v-if="preferences.imagePosition && preferences.imagePosition != ImagePosition.hidden"
|
<v-col
|
||||||
|
v-if="preferences.imagePosition && preferences.imagePosition != ImagePosition.hidden"
|
||||||
:order="preferences.imagePosition == ImagePosition.left ? -1 : 1"
|
:order="preferences.imagePosition == ImagePosition.left ? -1 : 1"
|
||||||
cols="4"
|
cols="4"
|
||||||
align-self="center"
|
align-self="center"
|
||||||
>
|
>
|
||||||
<img :key="imageKey"
|
<img
|
||||||
|
:key="imageKey"
|
||||||
:src="recipeImageUrl"
|
:src="recipeImageUrl"
|
||||||
style="min-height: 50; max-width: 100%;"
|
style="min-height: 50; max-width: 100%;"
|
||||||
>
|
>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col order="0">
|
<v-col order="0">
|
||||||
<v-card-title class="headline pl-0">
|
<v-card-title class="headline pl-0">
|
||||||
<v-icon start
|
<v-icon
|
||||||
|
start
|
||||||
color="primary"
|
color="primary"
|
||||||
>
|
>
|
||||||
{{ $globals.icons.primary }}
|
{{ $globals.icons.primary }}
|
||||||
@@ -36,7 +39,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<v-row class="d-flex justify-start">
|
<v-row class="d-flex justify-start">
|
||||||
<RecipeTimeCard :prep-time="recipe.prepTime"
|
<RecipeTimeCard
|
||||||
|
:prep-time="recipe.prepTime"
|
||||||
:total-time="recipe.totalTime"
|
:total-time="recipe.totalTime"
|
||||||
:perform-time="recipe.performTime"
|
:perform-time="recipe.performTime"
|
||||||
small
|
small
|
||||||
@@ -45,7 +49,8 @@
|
|||||||
/>
|
/>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|
||||||
<v-card-text v-if="preferences.showDescription"
|
<v-card-text
|
||||||
|
v-if="preferences.showDescription"
|
||||||
class="px-0"
|
class="px-0"
|
||||||
>
|
>
|
||||||
<SafeMarkdown :source="recipe.description" />
|
<SafeMarkdown :source="recipe.description" />
|
||||||
@@ -60,23 +65,28 @@
|
|||||||
<v-card-title class="headline pl-0">
|
<v-card-title class="headline pl-0">
|
||||||
{{ $t("recipe.ingredients") }}
|
{{ $t("recipe.ingredients") }}
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<div v-for="(ingredientSection, sectionIndex) in ingredientSections"
|
<div
|
||||||
|
v-for="(ingredientSection, sectionIndex) in ingredientSections"
|
||||||
:key="`ingredient-section-${sectionIndex}`"
|
:key="`ingredient-section-${sectionIndex}`"
|
||||||
class="print-section"
|
class="print-section"
|
||||||
>
|
>
|
||||||
<h4 v-if="ingredientSection.ingredients[0].title"
|
<h4
|
||||||
|
v-if="ingredientSection.ingredients[0].title"
|
||||||
class="ingredient-title mt-2"
|
class="ingredient-title mt-2"
|
||||||
>
|
>
|
||||||
{{ ingredientSection.ingredients[0].title }}
|
{{ ingredientSection.ingredients[0].title }}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="ingredient-grid"
|
<div
|
||||||
|
class="ingredient-grid"
|
||||||
:style="{ gridTemplateRows: `repeat(${Math.ceil(ingredientSection.ingredients.length / 2)}, min-content)` }"
|
:style="{ gridTemplateRows: `repeat(${Math.ceil(ingredientSection.ingredients.length / 2)}, min-content)` }"
|
||||||
>
|
>
|
||||||
<template v-for="(ingredient, ingredientIndex) in ingredientSection.ingredients"
|
<template
|
||||||
|
v-for="(ingredient, ingredientIndex) in ingredientSection.ingredients"
|
||||||
:key="`ingredient-${ingredientIndex}`"
|
:key="`ingredient-${ingredientIndex}`"
|
||||||
>
|
>
|
||||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
<p class="ingredient-body"
|
<p
|
||||||
|
class="ingredient-body"
|
||||||
v-html="parseText(ingredient)"
|
v-html="parseText(ingredient)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -86,20 +96,24 @@
|
|||||||
|
|
||||||
<!-- Instructions -->
|
<!-- Instructions -->
|
||||||
<section>
|
<section>
|
||||||
<div v-for="(instructionSection, sectionIndex) in instructionSections"
|
<div
|
||||||
|
v-for="(instructionSection, sectionIndex) in instructionSections"
|
||||||
:key="`instruction-section-${sectionIndex}`"
|
:key="`instruction-section-${sectionIndex}`"
|
||||||
:class="{ 'print-section': instructionSection.sectionName }"
|
:class="{ 'print-section': instructionSection.sectionName }"
|
||||||
>
|
>
|
||||||
<v-card-title v-if="!sectionIndex"
|
<v-card-title
|
||||||
|
v-if="!sectionIndex"
|
||||||
class="headline pl-0"
|
class="headline pl-0"
|
||||||
>
|
>
|
||||||
{{ $t("recipe.instructions") }}
|
{{ $t("recipe.instructions") }}
|
||||||
</v-card-title>
|
</v-card-title>
|
||||||
<div v-for="(step, stepIndex) in instructionSection.instructions"
|
<div
|
||||||
|
v-for="(step, stepIndex) in instructionSection.instructions"
|
||||||
:key="`instruction-${stepIndex}`"
|
:key="`instruction-${stepIndex}`"
|
||||||
>
|
>
|
||||||
<div class="print-section">
|
<div class="print-section">
|
||||||
<h4 v-if="step.title"
|
<h4
|
||||||
|
v-if="step.title"
|
||||||
:key="`instruction-title-${stepIndex}`"
|
:key="`instruction-title-${stepIndex}`"
|
||||||
class="instruction-title mb-2"
|
class="instruction-title mb-2"
|
||||||
>
|
>
|
||||||
@@ -112,7 +126,8 @@
|
|||||||
+ 1,
|
+ 1,
|
||||||
}) }}
|
}) }}
|
||||||
</h5>
|
</h5>
|
||||||
<SafeMarkdown :source="step.text"
|
<SafeMarkdown
|
||||||
|
:source="step.text"
|
||||||
class="recipe-step-body"
|
class="recipe-step-body"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -122,17 +137,20 @@
|
|||||||
|
|
||||||
<!-- Notes -->
|
<!-- Notes -->
|
||||||
<div v-if="preferences.showNotes">
|
<div v-if="preferences.showNotes">
|
||||||
<v-divider v-if="hasNotes"
|
<v-divider
|
||||||
|
v-if="hasNotes"
|
||||||
class="grey my-4"
|
class="grey my-4"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div v-for="(note, index) in recipe.notes"
|
<div
|
||||||
|
v-for="(note, index) in recipe.notes"
|
||||||
:key="index + 'note'"
|
:key="index + 'note'"
|
||||||
>
|
>
|
||||||
<div class="print-section">
|
<div class="print-section">
|
||||||
<h4>{{ note.title }}</h4>
|
<h4>{{ note.title }}</h4>
|
||||||
<SafeMarkdown :source="note.text"
|
<SafeMarkdown
|
||||||
|
:source="note.text"
|
||||||
class="note-body"
|
class="note-body"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -150,7 +168,8 @@
|
|||||||
<div class="print-section">
|
<div class="print-section">
|
||||||
<table class="nutrition-table">
|
<table class="nutrition-table">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(value, key) in recipe.nutrition"
|
<tr
|
||||||
|
v-for="(value, key) in recipe.nutrition"
|
||||||
:key="key"
|
:key="key"
|
||||||
>
|
>
|
||||||
<template v-if="value">
|
<template v-if="value">
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
<div @click.prevent>
|
<div @click.prevent>
|
||||||
<!-- User Rating -->
|
<!-- User Rating -->
|
||||||
<v-hover v-slot="{ isHovering, props }">
|
<v-hover v-slot="{ isHovering, props }">
|
||||||
<v-rating v-if="isOwnGroup && (userRating || isHovering || !ratingsLoaded)"
|
<v-rating
|
||||||
|
v-if="isOwnGroup && (userRating || isHovering || !ratingsLoaded)"
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
:model-value="userRating"
|
:model-value="userRating"
|
||||||
active-color="secondary"
|
active-color="secondary"
|
||||||
@@ -15,7 +16,8 @@
|
|||||||
@update:model-value="updateRating(+$event)"
|
@update:model-value="updateRating(+$event)"
|
||||||
/>
|
/>
|
||||||
<!-- Group Rating -->
|
<!-- Group Rating -->
|
||||||
<v-rating v-else
|
<v-rating
|
||||||
|
v-else
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
:model-value="groupRating"
|
:model-value="groupRating"
|
||||||
:half-increments="true"
|
:half-increments="true"
|
||||||
|
|||||||
@@ -33,20 +33,39 @@
|
|||||||
<template v-for="nav in topLink">
|
<template v-for="nav in topLink">
|
||||||
<div v-if="!nav.restricted || isOwnGroup" :key="nav.key || nav.title">
|
<div v-if="!nav.restricted || isOwnGroup" :key="nav.key || nav.title">
|
||||||
<!-- Multi Items -->
|
<!-- Multi Items -->
|
||||||
<v-list-group v-if="nav.children" :key="(nav.key || nav.title) + 'multi-item'"
|
<v-list-group
|
||||||
v-model="dropDowns[nav.title]" color="primary" :prepend-icon="nav.icon" :fluid="true">
|
v-if="nav.children"
|
||||||
|
:key="(nav.key || nav.title) + 'multi-item'"
|
||||||
|
v-model="dropDowns[nav.title]"
|
||||||
|
color="primary"
|
||||||
|
:prepend-icon="nav.icon"
|
||||||
|
:fluid="true"
|
||||||
|
>
|
||||||
<template #activator="{ props }">
|
<template #activator="{ props }">
|
||||||
<v-list-item v-bind="props" :prepend-icon="nav.icon" :title="nav.title" />
|
<v-list-item v-bind="props" :prepend-icon="nav.icon" :title="nav.title" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<v-list-item v-for="child in nav.children" :key="child.key || child.title" exact :to="child.to"
|
<v-list-item
|
||||||
:prepend-icon="child.icon" :title="child.title" class="ml-4" />
|
v-for="child in nav.children"
|
||||||
|
:key="child.key || child.title"
|
||||||
|
exact
|
||||||
|
:to="child.to"
|
||||||
|
:prepend-icon="child.icon"
|
||||||
|
:title="child.title"
|
||||||
|
class="ml-4"
|
||||||
|
/>
|
||||||
</v-list-group>
|
</v-list-group>
|
||||||
|
|
||||||
<!-- Single Item -->
|
<!-- Single Item -->
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<v-list-item :key="(nav.key || nav.title) + 'single-item'" exact link :to="nav.to"
|
<v-list-item
|
||||||
:prepend-icon="nav.icon" :title="nav.title" />
|
:key="(nav.key || nav.title) + 'single-item'"
|
||||||
|
exact
|
||||||
|
link
|
||||||
|
:to="nav.to"
|
||||||
|
:prepend-icon="nav.icon"
|
||||||
|
:title="nav.title"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -60,14 +79,27 @@
|
|||||||
<template v-for="nav in secondaryLinks">
|
<template v-for="nav in secondaryLinks">
|
||||||
<div v-if="!nav.restricted || isOwnGroup" :key="nav.key || nav.title">
|
<div v-if="!nav.restricted || isOwnGroup" :key="nav.key || nav.title">
|
||||||
<!-- Multi Items -->
|
<!-- Multi Items -->
|
||||||
<v-list-group v-if="nav.children" :key="(nav.key || nav.title) + 'multi-item'"
|
<v-list-group
|
||||||
v-model="dropDowns[nav.title]" color="primary" :prepend-icon="nav.icon" fluid>
|
v-if="nav.children"
|
||||||
|
:key="(nav.key || nav.title) + 'multi-item'"
|
||||||
|
v-model="dropDowns[nav.title]"
|
||||||
|
color="primary"
|
||||||
|
:prepend-icon="nav.icon"
|
||||||
|
fluid
|
||||||
|
>
|
||||||
<template #activator="{ props }">
|
<template #activator="{ props }">
|
||||||
<v-list-item v-bind="props" :prepend-icon="nav.icon" :title="nav.title" />
|
<v-list-item v-bind="props" :prepend-icon="nav.icon" :title="nav.title" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<v-list-item v-for="child in nav.children" :key="child.key || child.title" exact :to="child.to"
|
<v-list-item
|
||||||
class="ml-2" :prepend-icon="child.icon" :title="child.title" />
|
v-for="child in nav.children"
|
||||||
|
:key="child.key || child.title"
|
||||||
|
exact
|
||||||
|
:to="child.to"
|
||||||
|
class="ml-2"
|
||||||
|
:prepend-icon="child.icon"
|
||||||
|
:title="child.title"
|
||||||
|
/>
|
||||||
</v-list-group>
|
</v-list-group>
|
||||||
|
|
||||||
<!-- Single Item -->
|
<!-- Single Item -->
|
||||||
|
|||||||
@@ -41,7 +41,8 @@
|
|||||||
:hide-details="!inputField.hint"
|
:hide-details="!inputField.hint"
|
||||||
:persistent-hint="!!inputField.hint"
|
:persistent-hint="!!inputField.hint"
|
||||||
density="comfortable"
|
density="comfortable"
|
||||||
@change="emitBlur">
|
@change="emitBlur"
|
||||||
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<span class="ml-4">
|
<span class="ml-4">
|
||||||
{{ inputField.label }}
|
{{ inputField.label }}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- eslint-disable-next-line vue/no-v-html is safe here because all HTML is sanitized with DOMPurify in setup() -->
|
<!-- eslint-disable-next-line vue/no-v-html is safe here because all HTML is sanitized with DOMPurify in setup() -->
|
||||||
<div v-html="value" />
|
<div v-html="value" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|||||||
@@ -17,15 +17,15 @@ export interface OrganizerBase {
|
|||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FieldType =
|
export type FieldType
|
||||||
| "string"
|
= | "string"
|
||||||
| "number"
|
| "number"
|
||||||
| "boolean"
|
| "boolean"
|
||||||
| "date"
|
| "date"
|
||||||
| RecipeOrganizer;
|
| RecipeOrganizer;
|
||||||
|
|
||||||
export type FieldValue =
|
export type FieldValue
|
||||||
| string
|
= | string
|
||||||
| number
|
| number
|
||||||
| boolean
|
| boolean
|
||||||
| Date
|
| Date
|
||||||
|
|||||||
@@ -6,21 +6,20 @@ export default withNuxt({
|
|||||||
plugins: {
|
plugins: {
|
||||||
"@stylistic": stylistic,
|
"@stylistic": stylistic,
|
||||||
},
|
},
|
||||||
// Your custom configs here
|
|
||||||
rules: {
|
rules: {
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
"@stylistic/no-tabs": ["error"],
|
||||||
"vue/no-mutating-props": "warn",
|
|
||||||
"vue/no-v-html": "warn",
|
|
||||||
"object-curly-newline": "off",
|
|
||||||
"consistent-list-newline": "off",
|
|
||||||
"vue/first-attribute-linebreak": "off",
|
|
||||||
"@stylistic/no-tabs": ["error", { allowIndentationTabs: true }],
|
|
||||||
"@stylistic/no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
|
"@stylistic/no-mixed-spaces-and-tabs": ["error", "smart-tabs"],
|
||||||
"vue/max-attributes-per-line": "off",
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
"vue/html-indent": "off",
|
"vue/first-attribute-linebreak": "error",
|
||||||
"vue/html-closing-bracket-newline": "off",
|
"vue/html-closing-bracket-newline": "error",
|
||||||
// TODO: temporarily off to get this PR in without a crazy diff
|
"vue/max-attributes-per-line": [
|
||||||
"@stylistic/indent": "off",
|
"error",
|
||||||
"@stylistic/operator-linebreak": "off",
|
{
|
||||||
|
singleline: 5,
|
||||||
|
multiline: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"vue/no-mutating-props": "error",
|
||||||
|
"vue/no-v-html": "error",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-app v-if="ready"
|
<v-app
|
||||||
|
v-if="ready"
|
||||||
dark
|
dark
|
||||||
>
|
>
|
||||||
<v-card-title>
|
<v-card-title>
|
||||||
@@ -14,7 +15,8 @@
|
|||||||
<p class="primary--text">
|
<p class="primary--text">
|
||||||
4
|
4
|
||||||
</p>
|
</p>
|
||||||
<v-icon color="primary"
|
<v-icon
|
||||||
|
color="primary"
|
||||||
class="mx-auto mb-0"
|
class="mx-auto mb-0"
|
||||||
size="200"
|
size="200"
|
||||||
>
|
>
|
||||||
@@ -28,7 +30,8 @@
|
|||||||
<v-card-actions>
|
<v-card-actions>
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
<slot name="actions">
|
<slot name="actions">
|
||||||
<v-btn v-for="(button, index) in buttons"
|
<v-btn
|
||||||
|
v-for="(button, index) in buttons"
|
||||||
:key="index"
|
:key="index"
|
||||||
nuxt
|
nuxt
|
||||||
:to="button.to"
|
:to="button.to"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ export interface PaginationData<T> {
|
|||||||
items: T[];
|
items: T[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RecipeOrganizer =
|
export type RecipeOrganizer
|
||||||
| "categories"
|
= | "categories"
|
||||||
| "tags"
|
| "tags"
|
||||||
| "tools"
|
| "tools"
|
||||||
| "foods"
|
| "foods"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container fluid class="narrow-container">
|
<v-container fluid class="narrow-container">
|
||||||
<BaseDialog v-model="state.storageDetails" :title="$t('admin.maintenance.storage-details')"
|
<BaseDialog
|
||||||
|
v-model="state.storageDetails"
|
||||||
|
:title="$t('admin.maintenance.storage-details')"
|
||||||
:icon="$globals.icons.folderOutline"
|
:icon="$globals.icons.folderOutline"
|
||||||
>
|
>
|
||||||
<div class="py-2">
|
<div class="py-2">
|
||||||
<template v-for="(value, key, idx) in storageDetails" :key="`item-${key}`">
|
<template v-for="(value, key, idx) in storageDetails" :key="`item-${key}`">
|
||||||
<v-list-item>
|
<v-list-item>
|
||||||
@@ -55,9 +57,11 @@
|
|||||||
</v-card>
|
</v-card>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<BaseCardSectionTitle class="pb-0 mt-8" :icon="$globals.icons.wrench"
|
<BaseCardSectionTitle
|
||||||
|
class="pb-0 mt-8"
|
||||||
|
:icon="$globals.icons.wrench"
|
||||||
:title="$t('admin.mainentance.actions-title')"
|
:title="$t('admin.mainentance.actions-title')"
|
||||||
>
|
>
|
||||||
<i18n-t keypath="admin.maintenance.actions-description">
|
<i18n-t keypath="admin.maintenance.actions-description">
|
||||||
<template #destructive_in_bold>
|
<template #destructive_in_bold>
|
||||||
<b>{{ $t("admin.maintenance.actions-description-destructive") }}</b>
|
<b>{{ $t("admin.maintenance.actions-description-destructive") }}</b>
|
||||||
|
|||||||
@@ -163,7 +163,8 @@
|
|||||||
>
|
>
|
||||||
<template #next>
|
<template #next>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
create flat
|
create
|
||||||
|
flat
|
||||||
:disabled="isSubmitting"
|
:disabled="isSubmitting"
|
||||||
:loading="isSubmitting"
|
:loading="isSubmitting"
|
||||||
:icon="$globals.icons.check"
|
:icon="$globals.icons.check"
|
||||||
@@ -229,7 +230,7 @@
|
|||||||
<!-- Dialog Language -->
|
<!-- Dialog Language -->
|
||||||
<LanguageDialog v-model="langDialog" />
|
<LanguageDialog v-model="langDialog" />
|
||||||
</v-card>
|
</v-card>
|
||||||
</v-container>
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|||||||
@@ -151,7 +151,7 @@
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container v-if="household"
|
<v-container
|
||||||
|
v-if="household"
|
||||||
class="narrow-container"
|
class="narrow-container"
|
||||||
>
|
>
|
||||||
<BasePageTitle class="mb-5">
|
<BasePageTitle class="mb-5">
|
||||||
|
|||||||
@@ -147,7 +147,14 @@
|
|||||||
</v-btn>
|
</v-btn>
|
||||||
<v-menu offset-y>
|
<v-menu offset-y>
|
||||||
<template #activator="{ props }">
|
<template #activator="{ props }">
|
||||||
<v-chip v-bind="props" label variant="elevated" size="small" color="accent" @click.prevent>
|
<v-chip
|
||||||
|
v-bind="props"
|
||||||
|
label
|
||||||
|
variant="elevated"
|
||||||
|
size="small"
|
||||||
|
color="accent"
|
||||||
|
@click.prevent
|
||||||
|
>
|
||||||
<v-icon start>
|
<v-icon start>
|
||||||
{{ $globals.icons.tags }}
|
{{ $globals.icons.tags }}
|
||||||
</v-icon>
|
</v-icon>
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container class="mx-0 my-3 pa">
|
<v-container class="mx-0 my-3 pa">
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col v-for="(day, index) in plan" :key="index" cols="12" sm="12" md="4" lg="4" xl="2"
|
<v-col
|
||||||
class="col-borders my-1 d-flex flex-column">
|
v-for="(day, index) in plan"
|
||||||
|
:key="index"
|
||||||
|
cols="12"
|
||||||
|
sm="12"
|
||||||
|
md="4"
|
||||||
|
lg="4"
|
||||||
|
xl="2"
|
||||||
|
class="col-borders my-1 d-flex flex-column"
|
||||||
|
>
|
||||||
<v-card class="mb-2 border-left-primary rounded-sm px-2">
|
<v-card class="mb-2 border-left-primary rounded-sm px-2">
|
||||||
<v-container class="px-0 d-flex align-center" height="56px">
|
<v-container class="px-0 d-flex align-center" height="56px">
|
||||||
<v-row no-gutters style="width: 100%;">
|
<v-row no-gutters style="width: 100%;">
|
||||||
@@ -25,13 +33,17 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<RecipeCardMobile v-for="mealplan in section.meals" :key="mealplan.id"
|
<RecipeCardMobile
|
||||||
:recipe-id="mealplan.recipe ? mealplan.recipe.id! : ''" class="mb-2"
|
v-for="mealplan in section.meals"
|
||||||
|
:key="mealplan.id"
|
||||||
|
:recipe-id="mealplan.recipe ? mealplan.recipe.id! : ''"
|
||||||
|
class="mb-2"
|
||||||
:rating="mealplan.recipe ? mealplan.recipe.rating! : 0"
|
:rating="mealplan.recipe ? mealplan.recipe.rating! : 0"
|
||||||
:slug="mealplan.recipe ? mealplan.recipe.slug! : mealplan.title!"
|
:slug="mealplan.recipe ? mealplan.recipe.slug! : mealplan.title!"
|
||||||
:description="mealplan.recipe ? mealplan.recipe.description! : mealplan.text!"
|
:description="mealplan.recipe ? mealplan.recipe.description! : mealplan.text!"
|
||||||
:name="mealplan.recipe ? mealplan.recipe.name! : mealplan.title!"
|
:name="mealplan.recipe ? mealplan.recipe.name! : mealplan.title!"
|
||||||
:tags="mealplan.recipe ? mealplan.recipe.tags! : []" />
|
:tags="mealplan.recipe ? mealplan.recipe.tags! : []"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</v-col>
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
|
|||||||
Reference in New Issue
Block a user