1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-08-05 05:25:26 +02:00

feat(frontend): 🚧 CRUD Functionality

This commit is contained in:
hay-kot 2021-08-02 22:15:11 -08:00
parent 00a8fdda41
commit afcad2f701
49 changed files with 845 additions and 275 deletions

View file

@ -44,13 +44,13 @@
target="_blank"
rel="noreferrer nofollow"
>
{{ $t('new-recipe.google-ld-json-info') }}
{{ $t("new-recipe.google-ld-json-info") }}
</a>
<a href="https://github.com/hay-kot/mealie/issues" target="_blank" rel="noreferrer nofollow">
{{ $t('new-recipe.github-issues') }}
{{ $t("new-recipe.github-issues") }}
</a>
<a href="https://schema.org/Recipe" target="_blank" rel="noreferrer nofollow">
{{ $t('new-recipe.recipe-markup-specification') }}
{{ $t("new-recipe.recipe-markup-specification") }}
</a>
</div>
<div class="d-flex justify-end">
@ -61,7 +61,7 @@
@click="addRecipe = false"
>
<v-icon left> {{ $globals.icons.externalLink }} </v-icon>
{{ $t('new-recipe.view-scraped-data') }}
{{ $t("new-recipe.view-scraped-data") }}
</v-btn>
</div>
</v-alert>
@ -101,7 +101,7 @@
</v-card-text>
<v-card-actions>
<TheUploadBtn class="mx-auto" :text-btn="false" @uploaded="setFile" :post="false"> </TheUploadBtn>
<AppButtonUpload class="mx-auto" :text-btn="false" @uploaded="setFile" :post="false"> </AppButtonUpload>
</v-card-actions>
</BaseDialog>
<v-speed-dial v-model="fab" :open-on-hover="absolute" :fixed="absolute" :bottom="absolute" :right="absolute">
@ -140,11 +140,11 @@
<script>
import { api } from "@/api";
import TheUploadBtn from "@/components/UI/Buttons/TheUploadBtn.vue";
import AppButtonUpload from "@/components/UI/Buttons/AppButtonUpload.vue";
import BaseDialog from "@/components/UI/Dialogs/BaseDialog.vue";
export default {
components: {
TheUploadBtn,
AppButtonUpload,
BaseDialog,
},
props: {
@ -232,8 +232,9 @@ export default {
this.processing = false;
},
isValidWebUrl(url) {
let regEx = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,256}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/gm;
return regEx.test(url) ? true : this.$t('new-recipe.must-be-a-valid-url');
let regEx =
/^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,256}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/gm;
return regEx.test(url) ? true : this.$t("new-recipe.must-be-a-valid-url");
},
},
};

View file

@ -29,13 +29,13 @@
</div>
</template>
<div class="d-flex row py-3 justify-end">
<TheUploadBtn url="/api/backups/upload" @uploaded="getAvailableBackups">
<AppButtonUpload url="/api/backups/upload" @uploaded="getAvailableBackups">
<template v-slot="{ isSelecting, onButtonClick }">
<v-btn :loading="isSelecting" class="mx-2" small color="info" @click="onButtonClick">
<v-icon left> {{ $globals.icons.upload }} </v-icon> {{ $t("general.upload") }}
</v-btn>
</template>
</TheUploadBtn>
</AppButtonUpload>
<BackupDialog :color="color" />
<v-btn :loading="loading" class="mx-2" small color="success" @click="createBackup">
@ -74,7 +74,7 @@
</template>
<script>
import TheUploadBtn from "@/components/UI/Buttons/TheUploadBtn";
import AppButtonUpload from "@/components/UI/Buttons/AppButtonUpload";
import ImportSummaryDialog from "@/components/ImportSummaryDialog";
import ConfirmationDialog from "@/components/UI/Dialogs/ConfirmationDialog";
import { api } from "@/api";
@ -85,7 +85,7 @@ const IMPORT_EVENT = "import";
const DELETE_EVENT = "delete";
export default {
components: { StatCard, ImportDialog, TheUploadBtn, ImportSummaryDialog, BackupDialog, ConfirmationDialog },
components: { StatCard, ImportDialog, AppButtonUpload, ImportSummaryDialog, BackupDialog, ConfirmationDialog },
data() {
return {
color: "accent",

View file

@ -70,7 +70,7 @@
<v-data-table :headers="headers" :items="links" sort-by="calories">
<template v-slot:item.token="{ item }">
{{ `${baseURL}/sign-up/${item.token}` }}
<TheCopyButton :copy-text="`${baseURL}/sign-up/${item.token}`" />
<AppCopyButton :copy-text="`${baseURL}/sign-up/${item.token}`" />
</template>
<template v-slot:item.admin="{ item }">
<v-btn small :color="item.admin ? 'success' : 'error'" text>
@ -94,12 +94,12 @@
</template>
<script>
import TheCopyButton from "@/components/UI/Buttons/TheCopyButton";
import AppCopyButton from "@/components/UI/Buttons/AppCopyButton";
import ConfirmationDialog from "@/components/UI/Dialogs/ConfirmationDialog";
import { api } from "@/api";
import { validators } from "@/mixins/validators";
export default {
components: { ConfirmationDialog, TheCopyButton },
components: { ConfirmationDialog, AppCopyButton },
mixins: [validators],
data() {
return {

View file

@ -5,7 +5,7 @@
{{ title }}
<v-spacer></v-spacer>
<span>
<TheUploadBtn
<AppButtonUpload
class="mt-1"
:url="`/api/migrations/${folder}/upload`"
fileName="archive"
@ -55,7 +55,7 @@
</template>
<script>
import TheUploadBtn from "@/components/UI/Buttons/TheUploadBtn";
import AppButtonUpload from "@/components/UI/Buttons/AppButtonUpload";
import { api } from "@/api";
import MigrationDialog from "./MigrationDialog";
export default {
@ -66,7 +66,7 @@ export default {
available: Array,
},
components: {
TheUploadBtn,
AppButtonUpload,
MigrationDialog,
},
data() {

View file

@ -90,7 +90,7 @@
</v-card-text>
<v-divider></v-divider>
<v-card-actions class="pb-1 pt-3">
<TheUploadBtn
<AppButtonUpload
:icon="$globals.icons.fileImage"
:text="$t('user.upload-photo')"
:url="userProfileImage"
@ -106,14 +106,14 @@
<script>
import BaseDialog from "@/components/UI/Dialogs/BaseDialog";
import StatCard from "@/components/UI/StatCard";
import TheUploadBtn from "@/components/UI/Buttons/TheUploadBtn";
import AppButtonUpload from "@/components/UI/Buttons/AppButtonUpload";
import { api } from "@/api";
import { validators } from "@/mixins/validators";
import { initials } from "@/mixins/initials";
export default {
components: {
BaseDialog,
TheUploadBtn,
AppButtonUpload,
StatCard,
},
mixins: [validators, initials],

View file

@ -38,9 +38,9 @@
{{ $t("shopping-list.shopping-list") }}
</v-btn>
<v-spacer></v-spacer>
<TheCopyButton color="info" :copy-text="mealPlanURL(mealplan.uid)">
<AppCopyButton color="info" :copy-text="mealPlanURL(mealplan.uid)">
{{ $t("general.link-copied") }}
</TheCopyButton>
</AppCopyButton>
</v-card-actions>
<v-list class="mt-0 pt-0">
@ -90,12 +90,12 @@ import { api } from "@/api";
import { utils } from "@/utils";
import NewMeal from "@/components/MealPlan/MealPlanNew";
import EditPlan from "@/components/MealPlan/MealPlanEditor";
import TheCopyButton from "@/components/UI/Buttons/TheCopyButton";
import AppCopyButton from "@/components/UI/Buttons/AppCopyButton";
export default {
components: {
NewMeal,
EditPlan,
TheCopyButton,
AppCopyButton,
},
data: () => ({
plannedMeals: [],
@ -120,7 +120,7 @@ export default {
},
editPlan(id) {
this.plannedMeals.forEach(element => {
this.plannedMeals.forEach((element) => {
if (element.uid === id) {
this.editMealPlan = element;
}

View file

@ -51,7 +51,7 @@
<v-card v-else-if="activeList">
<v-card-title class="headline">
<TheCopyButton v-if="!edit" :copy-text="listAsText" color="info" />
<AppCopyButton v-if="!edit" :copy-text="listAsText" color="info" />
<v-text-field label="Name" single-line dense v-if="edit" v-model="activeList.name"> </v-text-field>
<div v-else>
{{ activeList.name }}
@ -141,14 +141,14 @@
<script>
import BaseDialog from "@/components/UI/Dialogs/BaseDialog";
import SearchDialog from "@/components/UI/Dialogs/SearchDialog";
import TheCopyButton from "@/components/UI/Buttons/TheCopyButton";
import AppCopyButton from "@/components/UI/Buttons/AppCopyButton";
import VueMarkdown from "@adapttive/vue-markdown";
import { api } from "@/api";
export default {
components: {
BaseDialog,
SearchDialog,
TheCopyButton,
AppCopyButton,
VueMarkdown,
},
data() {
@ -176,7 +176,7 @@ export default {
},
},
listAsText() {
const formatList = this.activeList.items.map(x => {
const formatList = this.activeList.items.map((x) => {
return `${x.quantity} - ${x.text}`;
});
@ -206,7 +206,7 @@ export default {
const recipe = response.data;
const ingredients = recipe.recipeIngredient.map(x => ({
const ingredients = recipe.recipeIngredient.map((x) => ({
title: "",
text: x.note,
quantity: 1,
@ -217,14 +217,14 @@ export default {
this.consolidateList();
},
consolidateList() {
const allText = this.activeList.items.map(x => x.text);
const allText = this.activeList.items.map((x) => x.text);
const uniqueText = allText.filter((item, index) => {
return allText.indexOf(item) === index;
});
const newItems = uniqueText.map(x => {
let matchingItems = this.activeList.items.filter(y => y.text === x);
const newItems = uniqueText.map((x) => {
let matchingItems = this.activeList.items.filter((y) => y.text === x);
matchingItems[0].quantity = this.sumQuantiy(matchingItems);
return matchingItems[0];
});
@ -233,7 +233,7 @@ export default {
},
sumQuantiy(itemList) {
let quantity = 0;
itemList.forEach(element => {
itemList.forEach((element) => {
quantity += element.quantity;
});
return quantity;
@ -241,7 +241,7 @@ export default {
setActiveList() {
if (!this.list) return null;
if (!this.group.shoppingLists) return null;
this.activeList = this.group.shoppingLists.find(x => x.id == this.list);
this.activeList = this.group.shoppingLists.find((x) => x.id == this.list);
},
async createNewList() {
this.newList.group = this.group.name;