Merge pull request #2754 from p0lycarpio/fixes/ui-improvements

fix: frontend improvements
This commit is contained in:
boc-the-git 2023-11-26 13:11:54 +11:00 committed by GitHub
commit 340841b37a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 58 additions and 43 deletions

View File

@ -1,6 +1,6 @@
<template> <template>
<div v-if="value.length > 0 || edit"> <div v-if="value.length > 0 || edit">
<v-card class="mt-2"> <v-card class="mt-4">
<v-card-title class="py-2"> <v-card-title class="py-2">
{{ $t("asset.assets") }} {{ $t("asset.assets") }}
</v-card-title> </v-card-title>

View File

@ -18,7 +18,6 @@
solo solo
hide-details hide-details
dense dense
class="mx-1"
type="number" type="number"
:placeholder="$t('recipe.quantity')" :placeholder="$t('recipe.quantity')"
@keypress="quantityFilter" @keypress="quantityFilter"
@ -89,7 +88,6 @@
hide-details hide-details
dense dense
solo solo
class="mx-1"
:placeholder="$t('recipe.notes')" :placeholder="$t('recipe.notes')"
@click="$emit('clickIngredientField', 'note')" @click="$emit('clickIngredientField', 'note')"
> >
@ -100,7 +98,7 @@
<BaseButtonGroup <BaseButtonGroup
hover hover
:large="false" :large="false"
class="my-auto" class="my-auto d-flex"
:buttons="btns" :buttons="btns"
@toggle-section="toggleTitle" @toggle-section="toggleTitle"
@toggle-original="toggleOriginalText" @toggle-original="toggleOriginalText"

View File

@ -35,7 +35,7 @@
<v-card outlined class="flex-grow-1"> <v-card outlined class="flex-grow-1">
<v-card-text class="pa-3 pb-0"> <v-card-text class="pa-3 pb-0">
<p class="">{{ comment.user.username }} {{ $d(Date.parse(comment.createdAt), "medium") }}</p> <p class="">{{ comment.user.username }} {{ $d(Date.parse(comment.createdAt), "medium") }}</p>
{{ comment.text }} <SafeMarkdown :source="comment.text" />
</v-card-text> </v-card-text>
<v-card-actions class="justify-end mt-0 pt-0"> <v-card-actions class="justify-end mt-0 pt-0">
<v-btn <v-btn
@ -60,11 +60,13 @@ import { Recipe, RecipeCommentOut } from "~/lib/api/types/recipe";
import UserAvatar from "~/components/Domain/User/UserAvatar.vue"; import UserAvatar from "~/components/Domain/User/UserAvatar.vue";
import { NoUndefinedField } from "~/lib/api/types/non-generated"; import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { usePageUser } from "~/composables/recipe-page/shared-state"; import { usePageUser } from "~/composables/recipe-page/shared-state";
import SafeMarkdown from "~/components/global/SafeMarkdown.vue";
export default defineComponent({ export default defineComponent({
components: { components: {
UserAvatar, UserAvatar,
}, SafeMarkdown
},
props: { props: {
recipe: { recipe: {
type: Object as () => NoUndefinedField<Recipe>, type: Object as () => NoUndefinedField<Recipe>,

View File

@ -24,13 +24,13 @@
</v-btn> </v-btn>
</v-card-actions> </v-card-actions>
<AdvancedOnly> <AdvancedOnly>
<v-card v-if="isEditForm" flat class="ma-2 mb-2"> <v-card v-if="isEditForm" flat class="mb-2 mx-n2">
<v-card-title> {{ $t('recipe.api-extras') }} </v-card-title> <v-card-title> {{ $t('recipe.api-extras') }} </v-card-title>
<v-divider class="mx-2"></v-divider> <v-divider class="ml-4"></v-divider>
<v-card-text> <v-card-text>
{{ $t('recipe.api-extras-description') }} {{ $t('recipe.api-extras-description') }}
<v-row v-for="(_, key) in recipe.extras" :key="key" class="mt-1"> <v-row v-for="(_, key) in recipe.extras" :key="key" class="mt-1">
<v-col cols="8"> <v-col style="max-width: 400px;">
<v-text-field v-model="recipe.extras[key]" dense :label="key"> <v-text-field v-model="recipe.extras[key]" dense :label="key">
<template #prepend> <template #prepend>
<v-btn color="error" icon class="mt-n4" @click="removeApiExtra(key)"> <v-btn color="error" icon class="mt-n4" @click="removeApiExtra(key)">
@ -41,8 +41,8 @@
</v-col> </v-col>
</v-row> </v-row>
</v-card-text> </v-card-text>
<v-card-actions class="d-flex"> <v-card-actions class="d-flex ml-2 mt-n3">
<div style="max-width: 200px"> <div>
<v-text-field v-model="apiNewKey" :label="$t('recipe.message-key')"></v-text-field> <v-text-field v-model="apiNewKey" :label="$t('recipe.message-key')"></v-text-field>
</div> </div>
<BaseButton create small class="ml-5" @click="createApiExtra" /> <BaseButton create small class="ml-5" @click="createApiExtra" />

View File

@ -26,7 +26,7 @@
</TransitionGroup> </TransitionGroup>
</draggable> </draggable>
<v-skeleton-loader v-else boilerplate elevation="2" type="list-item"> </v-skeleton-loader> <v-skeleton-loader v-else boilerplate elevation="2" type="list-item"> </v-skeleton-loader>
<div class="d-flex flex-wrap justify-center justify-sm-end mt-2"> <div class="d-flex flex-wrap justify-center justify-sm-end mt-3">
<v-tooltip top color="accent"> <v-tooltip top color="accent">
<template #activator="{ on, attrs }"> <template #activator="{ on, attrs }">
<span v-on="on"> <span v-on="on">

View File

@ -49,11 +49,13 @@
<v-card-actions> <v-card-actions>
<BaseButton cancel @click="dialog = false"> </BaseButton> <BaseButton cancel @click="dialog = false"> </BaseButton>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<BaseButton color="info" @click="autoSetReferences"> <div class="d-flex flex-wrap justify-end">
<template #icon> {{ $globals.icons.robot }}</template> <BaseButton color="info" @click="autoSetReferences">
{{ $t("recipe.auto") }} <template #icon> {{ $globals.icons.robot }}</template>
</BaseButton> {{ $t("recipe.auto") }}
<BaseButton save @click="setIngredientIds"> </BaseButton> </BaseButton>
<BaseButton class="ml-2" save @click="setIngredientIds"> </BaseButton>
</div>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
@ -84,7 +86,7 @@
<div v-for="(step, index) in value" :key="step.id" class="list-group-item"> <div v-for="(step, index) in value" :key="step.id" class="list-group-item">
<v-app-bar <v-app-bar
v-if="step.id && showTitleEditor[step.id]" v-if="step.id && showTitleEditor[step.id]"
class="primary mx-1 mt-6" class="primary mt-6"
style="cursor: pointer" style="cursor: pointer"
dark dark
dense dense
@ -219,6 +221,7 @@
</div> </div>
</TransitionGroup> </TransitionGroup>
</draggable> </draggable>
<v-divider class="mt-10 d-flex d-md-none"/>
</section> </section>
</template> </template>

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!-- Recipe Categories --> <!-- Recipe Categories -->
<v-card v-if="recipe.recipeCategory.length > 0 || isEditForm" class="mt-2"> <v-card v-if="recipe.recipeCategory.length > 0 || isEditForm" :class="{'mt-10': !isEditForm}">
<v-card-title class="py-2"> <v-card-title class="py-2">
{{ $t("recipe.categories") }} {{ $t("recipe.categories") }}
</v-card-title> </v-card-title>
@ -19,7 +19,7 @@
</v-card> </v-card>
<!-- Recipe Tags --> <!-- Recipe Tags -->
<v-card v-if="recipe.tags.length > 0 || isEditForm" class="mt-2"> <v-card v-if="recipe.tags.length > 0 || isEditForm" class="mt-4">
<v-card-title class="py-2"> <v-card-title class="py-2">
{{ $t("tag.tags") }} {{ $t("tag.tags") }}
</v-card-title> </v-card-title>
@ -45,7 +45,7 @@
</v-card-text> </v-card-text>
</v-card> </v-card>
<RecipeNutrition v-if="recipe.settings.showNutrition" v-model="recipe.nutrition" class="mt-10" :edit="isEditForm" /> <RecipeNutrition v-if="recipe.settings.showNutrition" v-model="recipe.nutrition" class="mt-4" :edit="isEditForm" />
<RecipeAssets <RecipeAssets
v-if="recipe.settings.showAssets" v-if="recipe.settings.showAssets"
v-model="recipe.assets" v-model="recipe.assets"

View File

@ -8,7 +8,7 @@
</v-btn> </v-btn>
</v-col> </v-col>
</v-row> </v-row>
<v-divider class="mx-2" /> <v-divider class="mx-2"/>
<div <div
v-if="timelineEvents.length" v-if="timelineEvents.length"
id="timeline-container" id="timeline-container"
@ -34,7 +34,7 @@
{{ $t("recipe.timeline-is-empty") }} {{ $t("recipe.timeline-is-empty") }}
</v-card-title> </v-card-title>
</v-card> </v-card>
<div v-if="loading" class="mb-3"> <div v-if="loading" class="mb-3 text-center">
<AppLoader :loading="loading" :waiting-text="$tc('general.loading-events')" /> <AppLoader :loading="loading" :waiting-text="$tc('general.loading-events')" />
</div> </div>
</div> </div>

View File

@ -85,7 +85,7 @@
@error="hideImage = true" @error="hideImage = true"
/> />
<div v-if="event.eventMessage" :class="useMobileFormat ? 'text-caption' : ''"> <div v-if="event.eventMessage" :class="useMobileFormat ? 'text-caption' : ''">
{{ event.eventMessage }} <SafeMarkdown :source="event.eventMessage" />
</div> </div>
</v-col> </v-col>
</v-row> </v-row>
@ -101,9 +101,10 @@ import RecipeTimelineContextMenu from "./RecipeTimelineContextMenu.vue";
import { useStaticRoutes } from "~/composables/api"; import { useStaticRoutes } from "~/composables/api";
import { Recipe, RecipeTimelineEventOut } from "~/lib/api/types/recipe" import { Recipe, RecipeTimelineEventOut } from "~/lib/api/types/recipe"
import UserAvatar from "~/components/Domain/User/UserAvatar.vue"; import UserAvatar from "~/components/Domain/User/UserAvatar.vue";
import SafeMarkdown from "~/components/global/SafeMarkdown.vue";
export default defineComponent({ export default defineComponent({
components: { RecipeCardMobile, RecipeTimelineContextMenu, UserAvatar }, components: { RecipeCardMobile, RecipeTimelineContextMenu, UserAvatar, SafeMarkdown },
props: { props: {
event: { event: {

View File

@ -1,6 +1,5 @@
<template> <template>
<v-container fluid> <v-container fluid>
<BannerExperimental issue="https://github.com/hay-kot/mealie/issues/871"></BannerExperimental>
<section> <section>
<!-- Delete Dialog --> <!-- Delete Dialog -->
<BaseDialog <BaseDialog
@ -44,7 +43,7 @@
></v-checkbox> ></v-checkbox>
</v-card-text> </v-card-text>
<v-card-actions class="justify-center pt-0"> <v-card-actions class="justify-center pt-0">
<BaseButton delete :disabled="!confirmImport" @click="restoreBackup(selected)"> <BaseButton delete :disabled="!confirmImport || runningRestore" @click="restoreBackup(selected)">
<template #icon> {{ $globals.icons.database }} </template> <template #icon> {{ $globals.icons.database }} </template>
{{ $t('settings.backup.restore-backup') }} {{ $t('settings.backup.restore-backup') }}
</BaseButton> </BaseButton>
@ -52,6 +51,7 @@
<p class="caption pb-0 mb-1 text-center"> <p class="caption pb-0 mb-1 text-center">
{{ selected }} {{ selected }}
</p> </p>
<v-progress-linear v-if="runningRestore" indeterminate></v-progress-linear>
</BaseDialog> </BaseDialog>
<section> <section>
@ -60,7 +60,16 @@
<i18n path="settings.backup.experimental-description" /> <i18n path="settings.backup.experimental-description" />
</v-card-text> </v-card-text>
</BaseCardSectionTitle> </BaseCardSectionTitle>
<BaseButton @click="createBackup"> {{ $t("settings.backup.create-heading") }} </BaseButton> <v-toolbar color="background" flat class="justify-between">
<BaseButton class="mr-2" @click="createBackup"> {{ $t("settings.backup.create-heading") }} </BaseButton>
<AppButtonUpload
:text-btn="false"
url="/api/admin/backups/upload"
accept=".zip"
color="info"
@uploaded="refreshBackups()"
/>
</v-toolbar>
<v-data-table <v-data-table
:headers="headers" :headers="headers"
@ -86,20 +95,17 @@
> >
<v-icon> {{ $globals.icons.delete }} </v-icon> <v-icon> {{ $globals.icons.delete }} </v-icon>
</v-btn> </v-btn>
<BaseButton small download :download-url="backupsFileNameDownload(item.name)" @click.stop="() => {}" /> <BaseButton small download :download-url="backupsFileNameDownload(item.name)" class="mx-1" @click.stop="() => {}"/>
<BaseButton small @click.stop="setSelected(item); importDialog = true">
<template #icon> {{ $globals.icons.backupRestore }}</template>
{{ $t("settings.backup.backup-restore") }}
</BaseButton>
</template> </template>
</v-data-table> </v-data-table>
<v-divider></v-divider> <v-divider></v-divider>
<div class="d-flex justify-end mt-6"> <div class="d-flex justify-end mt-6">
<div> <div>
<AppButtonUpload
:text-btn="false"
class="mr-4"
url="/api/admin/backups/upload"
accept=".zip"
color="info"
@uploaded="refreshBackups()"
/>
</div> </div>
</div> </div>
</section> </section>
@ -114,6 +120,7 @@
import { computed, defineComponent, reactive, ref, toRefs, useContext, onMounted, useRoute } from "@nuxtjs/composition-api"; import { computed, defineComponent, reactive, ref, toRefs, useContext, onMounted, useRoute } from "@nuxtjs/composition-api";
import { useAdminApi } from "~/composables/api"; import { useAdminApi } from "~/composables/api";
import { AllBackups } from "~/lib/api/types/admin"; import { AllBackups } from "~/lib/api/types/admin";
import { alert } from "~/composables/use-toast";
export default defineComponent({ export default defineComponent({
layout: "admin", layout: "admin",
@ -142,19 +149,23 @@ export default defineComponent({
if (!data?.error) { if (!data?.error) {
refreshBackups(); refreshBackups();
alert.success(i18n.tc("settings.backup.backup-created"));
} else {
alert.error(i18n.tc("settings.backup.error-creating-backup-see-log-file"));
} }
} }
async function restoreBackup(fileName: string) { async function restoreBackup(fileName: string) {
state.runningRestore = true;
const { error } = await adminApi.backups.restore(fileName); const { error } = await adminApi.backups.restore(fileName);
if (error) { if (error) {
console.log(error); console.log(error);
state.importDialog = false; state.importDialog = false;
return; } else {
alert.success(i18n.tc("settings.backup.restore-success"));
$auth.logout();
} }
$auth.logout();
} }
const deleteTarget = ref(""); const deleteTarget = ref("");
@ -163,6 +174,7 @@ export default defineComponent({
const { data } = await adminApi.backups.delete(deleteTarget.value); const { data } = await adminApi.backups.delete(deleteTarget.value);
if (!data?.error) { if (!data?.error) {
alert.success(i18n.tc("settings.backup.backup-deleted"));
refreshBackups(); refreshBackups();
} }
} }
@ -172,6 +184,7 @@ export default defineComponent({
deleteDialog: false, deleteDialog: false,
createDialog: false, createDialog: false,
importDialog: false, importDialog: false,
runningRestore: false,
search: "", search: "",
headers: [ headers: [
{ text: i18n.t("general.name"), value: "name" }, { text: i18n.t("general.name"), value: "name" },
@ -186,7 +199,6 @@ export default defineComponent({
return; return;
} }
selected.value = data.name; selected.value = data.name;
state.importDialog = true;
} }
const backupsFileNameDownload = (fileName: string) => `api/admin/backups/${fileName}`; const backupsFileNameDownload = (fileName: string) => `api/admin/backups/${fileName}`;

View File

@ -1,6 +1,6 @@
<template> <template>
<v-sheet :class="$vuetify.breakpoint.smAndDown ? 'pa-0' : 'px-3 py-0'"> <v-sheet :class="$vuetify.breakpoint.smAndDown ? 'pa-0' : 'px-3 py-0'">
<BasePageTitle v-if="groupName" divider> <BasePageTitle v-if="groupName">
<template #header> <template #header>
<v-img max-height="200" max-width="150" :src="require('~/static/svgs/manage-members.svg')" /> <v-img max-height="200" max-width="150" :src="require('~/static/svgs/manage-members.svg')" />
</template> </template>

View File

@ -6,7 +6,6 @@
<h2 class="headline">{{ $t('profile.welcome-user', [user.fullName]) }}</h2> <h2 class="headline">{{ $t('profile.welcome-user', [user.fullName]) }}</h2>
<p class="subtitle-1 mb-0 text-center"> <p class="subtitle-1 mb-0 text-center">
{{ $t('profile.description') }} {{ $t('profile.description') }}
<a href="https://hay-kot.github.io/mealie/" target="_blank"> {{ $t('general.learn-more') }} </a>
</p> </p>
<v-card flat color="background" width="100%" max-width="600px"> <v-card flat color="background" width="100%" max-width="600px">
<v-card-actions class="d-flex justify-center my-4"> <v-card-actions class="d-flex justify-center my-4">