Chore/general UI cleanup (#764)
* unify look and feel + button validators * Fixes #741 * add github script to mealei-next * feat(frontend): 💄 improve user-flow for creating ingredients and units in editor Creating a unit/food in the recipe editor will not automatically assign that to the auto-complete element on the ingredient. It also no longer needs a dialog and will show at the bottom of the menu at all times. * fix whitespace issue with slot * add security check to properties * fix event refresh on delete * remove depreciated page * improve API token flow * hide recipe data if not advanced user * misc adds Co-authored-by: Hayden <hay-kot@pm.me>
This commit is contained in:
parent
2afaf70a03
commit
909bc85205
17 changed files with 177 additions and 172 deletions
32
dev/scripts/github_get_release_issues.py
Normal file
32
dev/scripts/github_get_release_issues.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
import json
|
||||
|
||||
import requests
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class GithubIssue(BaseModel):
|
||||
url: str
|
||||
number: int
|
||||
title: str
|
||||
|
||||
|
||||
def get_issues_by_label(label="fixed-pending-release") -> list[GithubIssue]:
|
||||
|
||||
issues_url = f"https://api.github.com/repos/hay-kot/mealie/issues?labels={label}"
|
||||
|
||||
response = requests.get(issues_url)
|
||||
issues = json.loads(response.text)
|
||||
return [GithubIssue(**issue) for issue in issues]
|
||||
|
||||
|
||||
def format_markdown_list(issues: list[GithubIssue]) -> str:
|
||||
return "\n".join(f"- [{issue.number}]({issue.url}) - {issue.title}" for issue in issues)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
issues = get_issues_by_label()
|
||||
print(format_markdown_list(issues))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -16,6 +16,10 @@
|
|||
- User/Group settings are now completely separated from the Administration page.
|
||||
- All settings and configurations pages now have some sort of self-documenting help text. Additional text or descriptions are welcome from PRs
|
||||
- Site settings now has status on whether or not some ENV variables have been configured correctly.
|
||||
- Server Side Bare URL will let you know if the BASE_URL env variable has been set
|
||||
- Secure Site let's you know if you're serving via HTTPS or accessing by localhost. accessing without a secure site will render some of the features unusable.
|
||||
- Email Configuration Status will let you know if all the email settings have been provided and offer a way to send test emails.
|
||||
|
||||
|
||||
### 👨👩👧👦 Users and Groups
|
||||
- Recipes are now only viewable by group members
|
||||
|
@ -33,10 +37,17 @@
|
|||
- Add Recipes or Notes to a specific day
|
||||
|
||||
### 🥙 Recipes
|
||||
- You can now import multiple URLs at a time pre-tagged using the bulk importer. This task runs in the background so no need to wait for it to finish.
|
||||
- Foods/Units for Ingredients are now supported (toggle inside your recipe settings)
|
||||
- You can no use Natural Language Processing (NLP) to process ingredients and attempt to parse them into amounts, units, and foods. There additional is a "Brute Force" processor that can be used to use a pattern matching parser to try and determine ingredients. **Note** if you are processing a Non-English language you will have terrible results with the NLP and will likely need to use the Bruce Force processor.
|
||||
- Common Food and Units come pre-packaged with Mealie
|
||||
- Recipes can now scale when Food/Units are properly defined
|
||||
- Landscape and Portrait views is now available
|
||||
- Users with the advanced flag turned on will not be able to manage recipe data in bulk and perform the following actions:
|
||||
- Set Categories
|
||||
- Set Tags
|
||||
- Delete Recipes
|
||||
- Export Recipes
|
||||
|
||||
### ⚠️ Other things to know...
|
||||
- Themes have been depreciated for specific users. You can still set specific themes for your site through ENV variables. This approach should yield much better results for performance and some weirdness users have experienced.
|
||||
|
|
|
@ -30,6 +30,7 @@ export interface AdminStatistics {
|
|||
export interface CheckAppConfig {
|
||||
emailReady: boolean;
|
||||
baseUrlSet: boolean;
|
||||
isSiteSecure: boolean;
|
||||
}
|
||||
|
||||
export class AdminAboutAPI extends BaseAPI {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
:hint="hint"
|
||||
:solo="solo"
|
||||
:return-object="returnObject"
|
||||
:prepend-inner-icon="$globals.icons.tags"
|
||||
:flat="flat"
|
||||
v-bind="$attrs"
|
||||
@input="emitChange"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
v-model="value.title"
|
||||
dense
|
||||
hide-details
|
||||
class="mx-1 mb-4"
|
||||
class="mx-1 mt-3 mb-4"
|
||||
placeholder="Section Title"
|
||||
style="max-width: 500px"
|
||||
>
|
||||
|
@ -29,6 +29,7 @@
|
|||
<v-col v-if="!disableAmount && units" sm="12" md="3" cols="12">
|
||||
<v-autocomplete
|
||||
v-model="value.unit"
|
||||
:search-input.sync="unitSearch"
|
||||
hide-details
|
||||
dense
|
||||
solo
|
||||
|
@ -38,14 +39,19 @@
|
|||
class="mx-1"
|
||||
placeholder="Choose Unit"
|
||||
>
|
||||
<template #no-data>
|
||||
<RecipeIngredientUnitDialog class="mx-2" block small />
|
||||
<template #append-item>
|
||||
<div class="px-2">
|
||||
<BaseButton block small @click="createAssignUnit()"></BaseButton>
|
||||
</div>
|
||||
</template>
|
||||
</v-autocomplete>
|
||||
</v-col>
|
||||
|
||||
<!-- Foods Input -->
|
||||
<v-col v-if="!disableAmount && foods" m="12" md="3" cols="12" class="">
|
||||
<v-autocomplete
|
||||
v-model="value.food"
|
||||
:search-input.sync="foodSearch"
|
||||
hide-details
|
||||
dense
|
||||
solo
|
||||
|
@ -55,8 +61,10 @@
|
|||
class="mx-1 py-0"
|
||||
placeholder="Choose Food"
|
||||
>
|
||||
<template #no-data>
|
||||
<RecipeIngredientFoodDialog class="mx-2" block small />
|
||||
<template #append-item>
|
||||
<div class="px-2">
|
||||
<BaseButton block small @click="createAssignFood()"></BaseButton>
|
||||
</div>
|
||||
</template>
|
||||
</v-autocomplete>
|
||||
</v-col>
|
||||
|
@ -86,15 +94,12 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, toRefs } from "@nuxtjs/composition-api";
|
||||
import RecipeIngredientUnitDialog from "./RecipeIngredientUnitDialog.vue";
|
||||
import RecipeIngredientFoodDialog from "./RecipeIngredientFoodDialog.vue";
|
||||
import { defineComponent, reactive, ref, toRefs } from "@nuxtjs/composition-api";
|
||||
import { useFoods } from "~/composables/use-recipe-foods";
|
||||
import { useUnits } from "~/composables/use-recipe-units";
|
||||
import { validators } from "~/composables/use-validators";
|
||||
|
||||
export default defineComponent({
|
||||
components: { RecipeIngredientUnitDialog, RecipeIngredientFoodDialog },
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
|
@ -108,8 +113,28 @@ export default defineComponent({
|
|||
setup(props) {
|
||||
const { value } = props;
|
||||
|
||||
const { foods } = useFoods();
|
||||
// ==================================================
|
||||
// Foods
|
||||
const { foods, workingFoodData, actions: foodActions } = useFoods();
|
||||
const foodSearch = ref("");
|
||||
|
||||
async function createAssignFood() {
|
||||
workingFoodData.name = foodSearch.value;
|
||||
await foodActions.createOne();
|
||||
value.food = foods.value?.find((food) => food.name === foodSearch.value);
|
||||
}
|
||||
|
||||
// ==================================================
|
||||
// Units
|
||||
const { units, workingUnitData, actions: unitActions } = useUnits();
|
||||
const unitSearch = ref("");
|
||||
|
||||
async function createAssignUnit() {
|
||||
workingUnitData.name = unitSearch.value;
|
||||
await unitActions.createOne();
|
||||
value.unit = units.value?.find((unit) => unit.name === unitSearch.value);
|
||||
console.log(value.unit);
|
||||
}
|
||||
|
||||
const state = reactive({
|
||||
showTitle: false,
|
||||
|
@ -126,13 +151,17 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
return {
|
||||
workingUnitData,
|
||||
unitActions,
|
||||
validators,
|
||||
foods,
|
||||
units,
|
||||
...toRefs(state),
|
||||
createAssignFood,
|
||||
createAssignUnit,
|
||||
foods,
|
||||
foodSearch,
|
||||
toggleTitle,
|
||||
unitActions,
|
||||
units,
|
||||
unitSearch,
|
||||
validators,
|
||||
workingUnitData,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
<template>
|
||||
<BaseDialog
|
||||
title="Create Food"
|
||||
:icon="$globals.icons.foods"
|
||||
:keep-open="!validForm"
|
||||
@submit="actions.createOne(domCreateFoodForm)"
|
||||
>
|
||||
<v-card-text>
|
||||
<v-form ref="domCreateFoodForm">
|
||||
<v-text-field v-model="workingFoodData.name" label="Name" :rules="[validators.required]"></v-text-field>
|
||||
<v-text-field v-model="workingFoodData.description" label="Description"></v-text-field>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
<template #activator="{ open }">
|
||||
<BaseButton
|
||||
v-bind="$attrs"
|
||||
@click="
|
||||
actions.resetWorking();
|
||||
open();
|
||||
"
|
||||
></BaseButton>
|
||||
</template>
|
||||
</BaseDialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from "@nuxtjs/composition-api";
|
||||
import { useFoods } from "~/composables/use-recipe-foods";
|
||||
import { validators } from "~/composables/use-validators";
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const domCreateFoodForm = ref(null);
|
||||
const { workingFoodData, actions, validForm } = useFoods();
|
||||
return { validators, workingFoodData, actions, domCreateFoodForm, validForm };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
<template>
|
||||
<BaseDialog
|
||||
title="Create Unit"
|
||||
:icon="$globals.icons.units"
|
||||
:keep-open="!validForm"
|
||||
@submit="actions.createOne(domCreateUnitForm)"
|
||||
>
|
||||
<v-card-text>
|
||||
<v-form ref="domCreateUnitForm">
|
||||
<v-text-field v-model="workingUnitData.name" label="Name" :rules="[validators.required]"></v-text-field>
|
||||
<v-text-field v-model="workingUnitData.abbreviation" label="Abbreviation"></v-text-field>
|
||||
<v-text-field v-model="workingUnitData.description" label="Description"></v-text-field>
|
||||
<v-switch v-model="workingUnitData.fraction" label="Display as Fraction"></v-switch>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
<template #activator="{ open }">
|
||||
<BaseButton
|
||||
v-bind="$attrs"
|
||||
@click="
|
||||
actions.resetWorking();
|
||||
open();
|
||||
"
|
||||
></BaseButton>
|
||||
</template>
|
||||
</BaseDialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from "@nuxtjs/composition-api";
|
||||
import { useUnits } from "~/composables/use-recipe-units";
|
||||
import { validators } from "~/composables/use-validators";
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const domCreateUnitForm = ref(null);
|
||||
const { workingUnitData, actions, validForm } = useUnits();
|
||||
return { validators, workingUnitData, actions, validForm, domCreateUnitForm };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<v-navigation-drawer :value="value" clipped app width="240px">
|
||||
<v-navigation-drawer class="d-flex flex-column" :value="value" clipped app width="240px">
|
||||
<!-- User Profile -->
|
||||
<template v-if="$auth.user">
|
||||
<v-list-item two-line to="/user/profile" exact>
|
||||
|
@ -101,8 +101,8 @@
|
|||
</template>
|
||||
|
||||
<!-- Bottom Navigation Links -->
|
||||
<template v-if="bottomLinks">
|
||||
<v-list class="fixedBottom" nav dense>
|
||||
<template v-if="bottomLinks" #append>
|
||||
<v-list nav dense>
|
||||
<v-list-item-group v-model="bottomSelected" color="primary">
|
||||
<template v-for="nav in bottomLinks">
|
||||
<v-list-item
|
||||
|
@ -175,12 +175,6 @@ export default defineComponent({
|
|||
</script>
|
||||
|
||||
<style>
|
||||
.fixedBottom {
|
||||
position: fixed !important;
|
||||
bottom: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.no-print {
|
||||
display: none;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</v-icon>
|
||||
{{ title }}
|
||||
</v-card-title>
|
||||
<v-card-text class="pt-2">
|
||||
<v-card-text v-if="$slots.default" class="pt-2">
|
||||
<p class="pb-0 mb-0">
|
||||
<slot />
|
||||
</p>
|
||||
|
|
|
@ -86,11 +86,6 @@ export default defineComponent({
|
|||
to: "/admin/toolbox/tags",
|
||||
title: i18n.t("sidebar.categories"),
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.broom,
|
||||
to: "/admin/toolbox/organize",
|
||||
title: i18n.t("settings.organize"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -137,7 +137,7 @@ export default defineComponent({
|
|||
const { response } = await api.events.deleteEvents();
|
||||
|
||||
if (response && response.status === 200) {
|
||||
events.value = { events: [], total: 0 };
|
||||
refreshEvents();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,29 +2,25 @@
|
|||
<v-container fluid class="narrow-container">
|
||||
<BasePageTitle divider>
|
||||
<template #header>
|
||||
<v-img
|
||||
max-height="200"
|
||||
max-width="150"
|
||||
class="mb-2"
|
||||
:src="require('~/static/svgs/admin-site-settings.svg')"
|
||||
></v-img>
|
||||
<v-img max-height="200" max-width="150" :src="require('~/static/svgs/admin-site-settings.svg')"></v-img>
|
||||
</template>
|
||||
<template #title> {{ $t("settings.site-settings") }} </template>
|
||||
</BasePageTitle>
|
||||
|
||||
<section>
|
||||
<BaseCardSectionTitle :icon="$globals.icons.cog" title="General Configuration"> </BaseCardSectionTitle>
|
||||
<v-card class="mb-4">
|
||||
<BaseCardSectionTitle class="pb-0" :icon="$globals.icons.cog" title="General Configuration">
|
||||
</BaseCardSectionTitle>
|
||||
<v-card v-for="(check, idx) in simpleChecks" :key="idx" class="mb-4">
|
||||
<v-list-item>
|
||||
<v-list-item-avatar>
|
||||
<v-icon :color="getColor(appConfig.baseUrlSet)">
|
||||
{{ appConfig.baseUrlSet ? $globals.icons.checkboxMarkedCircle : $globals.icons.close }}
|
||||
<v-icon :color="getColor(check.status)">
|
||||
{{ check.status ? $globals.icons.checkboxMarkedCircle : $globals.icons.close }}
|
||||
</v-icon>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title :class="getTextClass(appConfig.baseUrlSet)"> Server Side Base URL </v-list-item-title>
|
||||
<v-list-item-subtitle :class="getTextClass(appConfig.baseUrlSet)">
|
||||
{{ appConfig.baseUrlSet ? "Ready" : "Not Ready - `BASE_URL` still default on API Server" }}
|
||||
<v-list-item-title :class="getTextClass(check.status)"> {{ check.text }} </v-list-item-title>
|
||||
<v-list-item-subtitle :class="getTextClass(check.status)">
|
||||
{{ check.status ? check.successText : check.errorText }}
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
@ -82,6 +78,13 @@ import { CheckAppConfig } from "~/api/admin/admin-about";
|
|||
import { useAdminApi, useApiSingleton } from "~/composables/use-api";
|
||||
import { validators } from "~/composables/use-validators";
|
||||
|
||||
interface SimpleCheck {
|
||||
status: boolean;
|
||||
text: string;
|
||||
successText: string;
|
||||
errorText: string;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
layout: "admin",
|
||||
setup() {
|
||||
|
@ -96,6 +99,7 @@ export default defineComponent({
|
|||
const appConfig = ref<CheckAppConfig>({
|
||||
emailReady: false,
|
||||
baseUrlSet: false,
|
||||
isSiteSecure: false,
|
||||
});
|
||||
|
||||
const api = useApiSingleton();
|
||||
|
@ -107,6 +111,29 @@ export default defineComponent({
|
|||
if (data) {
|
||||
appConfig.value = data;
|
||||
}
|
||||
|
||||
appConfig.value.isSiteSecure = isLocalhostorHttps();
|
||||
});
|
||||
|
||||
function isLocalhostorHttps() {
|
||||
return window.location.hostname === "localhost" || window.location.protocol === "https:";
|
||||
}
|
||||
|
||||
const simpleChecks = computed<SimpleCheck[]>(() => {
|
||||
return [
|
||||
{
|
||||
status: appConfig.value.baseUrlSet,
|
||||
text: "Server Side Base URL",
|
||||
errorText: "Error - `BASE_URL` still default on API Server",
|
||||
successText: "Server Side URL does not match the default",
|
||||
},
|
||||
{
|
||||
status: appConfig.value.isSiteSecure,
|
||||
text: "Secure Site",
|
||||
errorText: "Error - Serve via localhost or secure with https.",
|
||||
successText: "Site is accessed by localhost or https",
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
async function testEmail() {
|
||||
|
@ -147,6 +174,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
return {
|
||||
simpleChecks,
|
||||
getColor,
|
||||
getTextClass,
|
||||
appConfig,
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
<template>
|
||||
<v-container fluid>
|
||||
<BaseCardSectionTitle title="Organize Recipes"> </BaseCardSectionTitle>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "@nuxtjs/composition-api";
|
||||
|
||||
export default defineComponent({
|
||||
layout: "admin",
|
||||
setup() {
|
||||
return {};
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.$t("settings.organize") as string,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
|
@ -27,6 +27,7 @@
|
|||
<v-text-field
|
||||
v-model="recipeUrl"
|
||||
:label="$t('new-recipe.recipe-url')"
|
||||
:prepend-inner-icon="$globals.icons.link"
|
||||
validate-on-blur
|
||||
autofocus
|
||||
filled
|
||||
|
@ -40,7 +41,7 @@
|
|||
</v-card-text>
|
||||
<v-card-actions class="justify-center">
|
||||
<div style="width: 250px">
|
||||
<BaseButton rounded block type="submit" :loading="loading" />
|
||||
<BaseButton :disabled="recipeUrl === null" rounded block type="submit" :loading="loading" />
|
||||
</div>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
|
@ -86,6 +87,7 @@
|
|||
<v-text-field
|
||||
v-model="newRecipeName"
|
||||
:label="$t('recipe.recipe-name')"
|
||||
:prepend-inner-icon="$globals.icons.primary"
|
||||
validate-on-blur
|
||||
autofocus
|
||||
filled
|
||||
|
@ -100,7 +102,13 @@
|
|||
</v-card-text>
|
||||
<v-card-actions class="justify-center">
|
||||
<div style="width: 250px">
|
||||
<BaseButton rounded block :loading="loading" @click="createByName(newRecipeName)" />
|
||||
<BaseButton
|
||||
:disabled="newRecipeName === ''"
|
||||
rounded
|
||||
block
|
||||
:loading="loading"
|
||||
@click="createByName(newRecipeName)"
|
||||
/>
|
||||
</div>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
|
@ -131,7 +139,14 @@
|
|||
</v-card-text>
|
||||
<v-card-actions class="justify-center">
|
||||
<div style="width: 250px">
|
||||
<BaseButton large rounded block :loading="loading" @click="createByZip" />
|
||||
<BaseButton
|
||||
:disabled="newRecipeZip === null"
|
||||
large
|
||||
rounded
|
||||
block
|
||||
:loading="loading"
|
||||
@click="createByZip"
|
||||
/>
|
||||
</div>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
|
@ -142,7 +157,7 @@
|
|||
<v-tab-item value="debug" eager>
|
||||
<v-form ref="domUrlForm" @submit.prevent="debugUrl(recipeUrl)">
|
||||
<v-card flat>
|
||||
<v-card-title class="headline"> Recipe Importer </v-card-title>
|
||||
<v-card-title class="headline"> Recipe Debugger </v-card-title>
|
||||
<v-card-text>
|
||||
Grab the URL of the recipe you want to debug and paste it here. The URL will be scraped by the recipe
|
||||
scraper and the results will be displayed. If you don't see any data returned, the site you are trying
|
||||
|
@ -151,6 +166,7 @@
|
|||
v-model="recipeUrl"
|
||||
:label="$t('new-recipe.recipe-url')"
|
||||
validate-on-blur
|
||||
:prepend-inner-icon="$globals.icons.link"
|
||||
autofocus
|
||||
filled
|
||||
clearable
|
||||
|
@ -163,7 +179,14 @@
|
|||
</v-card-text>
|
||||
<v-card-actions class="justify-center">
|
||||
<div style="width: 250px">
|
||||
<BaseButton rounded block type="submit" color="info" :loading="loading">
|
||||
<BaseButton
|
||||
:disabled="recipeUrl === null"
|
||||
rounded
|
||||
block
|
||||
type="submit"
|
||||
color="info"
|
||||
:loading="loading"
|
||||
>
|
||||
<template #icon>
|
||||
{{ $globals.icons.robot }}
|
||||
</template>
|
||||
|
|
|
@ -20,9 +20,7 @@
|
|||
class="mb-0 pb-0"
|
||||
:label="$t('settings.token.api-token')"
|
||||
readonly
|
||||
:append-outer-icon="$globals.icons.contentCopy"
|
||||
@click="copyToken"
|
||||
@click:append-outer="copyToken"
|
||||
rows="3"
|
||||
>
|
||||
</v-textarea>
|
||||
<v-subheader class="text-center">
|
||||
|
@ -34,13 +32,14 @@
|
|||
</v-subheader>
|
||||
</template>
|
||||
</v-card-text>
|
||||
<v-expand-transition>
|
||||
<v-card-actions v-show="name != ''">
|
||||
<v-spacer></v-spacer>
|
||||
<v-card-actions>
|
||||
<BaseButton v-if="createdToken" cancel @click="resetCreate()"> Close </BaseButton>
|
||||
<BaseButton v-else :cancel="false" @click="createToken(name)"> Generate </BaseButton>
|
||||
<v-spacer></v-spacer>
|
||||
<AppButtonCopy v-if="createdToken" :icon="false" color="info" :copy-text="createdToken"> </AppButtonCopy>
|
||||
<BaseButton v-else key="generate-button" :disabled="name == ''" @click="createToken(name)">
|
||||
Generate
|
||||
</BaseButton>
|
||||
</v-card-actions>
|
||||
</v-expand-transition>
|
||||
</v-card>
|
||||
</section>
|
||||
<BaseCardSectionTitle class="mt-10" title="Active Tokens"> </BaseCardSectionTitle>
|
||||
|
@ -117,14 +116,7 @@ export default defineComponent({
|
|||
return data;
|
||||
}
|
||||
|
||||
function copyToken() {
|
||||
navigator.clipboard.writeText(createdToken.value).then(
|
||||
() => console.log("Copied", createdToken.value),
|
||||
() => console.log("Copied Failed", createdToken.value)
|
||||
);
|
||||
}
|
||||
|
||||
return { createToken, deleteToken, copyToken, createdToken, loading, name, user, resetCreate };
|
||||
return { createToken, deleteToken, createdToken, loading, name, user, resetCreate };
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
See who's in your group and manage their permissions.
|
||||
</UserProfileLinkCard>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6">
|
||||
<v-col v-if="user.advanced" cols="12" sm="12" md="6">
|
||||
<UserProfileLinkCard
|
||||
:link="{ text: 'Manage Recipe Data', to: '/user/group/recipe-data' }"
|
||||
:image="require('~/static/svgs/manage-recipes.svg')"
|
||||
|
|
|
@ -24,7 +24,8 @@ async def get_events(session: Session = Depends(generate_session)):
|
|||
async def delete_events(session: Session = Depends(generate_session)):
|
||||
""" Get event from the Database """
|
||||
db = get_database(session)
|
||||
return db.events.delete_all()
|
||||
db.events.delete_all()
|
||||
return {"message": "All events deleted"}
|
||||
|
||||
|
||||
@router.delete("/{id}")
|
||||
|
|
Loading…
Reference in a new issue