Merge branch 'dev' of https://github.com/hay-kot/mealie into feature/authentication

This commit is contained in:
hay-kot 2021-03-20 11:55:02 -08:00
commit e5e4846848
27 changed files with 317 additions and 204 deletions

View file

@ -9,11 +9,10 @@
"python.testing.nosetestsEnabled": false,
"python.testing.pytestEnabled": true,
"python.testing.autoTestDiscoverOnSaveEnabled": false,
"python.testing.pytestArgs": [
"tests"
],
"python.testing.pytestArgs": ["tests"],
"cSpell.enableFiletypes": ["!javascript", "!python"],
"i18n-ally.localesPaths": "frontend/src/locales",
"i18n-ally.localesPaths": "frontend/src/locales/messages",
"i18n-ally.sourceLanguage": "en",
"i18n-ally.enabledFrameworks": ["vue"],
"i18n-ally.keystyle": "nested",
"cSpell.words": ["performant"],

View file

@ -70,7 +70,7 @@ export default {
this.search = !this.search;
}
});
this.$store.dispatch("initLang");
this.$store.dispatch("initLang", { currentVueComponent: this });
},
mounted() {

View file

@ -92,39 +92,39 @@ export default {
{
icon: "mdi-cog",
to: "/admin/settings",
title: "Site Settings",
title: this.$t('settings.site-settings'),
},
{
icon: "mdi-account-group",
to: "/admin/manage-users",
title: "Manage Users",
title: this.$t('settings.manage-users'),
},
{
icon: "mdi-backup-restore",
to: "/admin/backups",
title: "Backups",
title: this.$t('settings.backup-and-exports'),
},
{
icon: "mdi-database-import",
to: "/admin/migrations",
title: "Migrations",
title: this.$t('settings.migrations'),
},
],
baseLinks: [
{
icon: "mdi-account",
to: "/admin/profile",
title: "Profile",
title: this.$t('settings.profile'),
},
{
icon: "mdi-format-color-fill",
to: "/admin/themes",
title: "Themes",
title: this.$t('general.themes'),
},
{
icon: "mdi-food",
to: "/admin/meal-planner",
title: "Meal Planner",
title: this.$t('meal-plan.meal-planner'),
},
],
};

View file

@ -38,7 +38,7 @@
</v-icon>
<v-toolbar-title class="headline">
Home Page Sections
{{$t('settings.homepage.home-page-sections')}}
</v-toolbar-title>
<v-spacer></v-spacer>
@ -80,7 +80,7 @@
</v-icon>
<v-toolbar-title class="headline">
All Categories
{{$t('settings.homepage.all-categories')}}
</v-toolbar-title>
<v-spacer></v-spacer>

View file

@ -2,8 +2,8 @@
<div>
<Confirmation
ref="deleteGroupConfirm"
title="Confirm Group Deletion"
:message="`Are you sure you want to delete <b>${group.name}<b/>`"
:title="$t('user.confirm-group-deletion')"
:message="$t('user.are-you-sure-you-want-to-delete-the-group', { groupName:group.name })"
icon="mdi-alert"
@confirm="deleteGroup"
:width="450"
@ -13,7 +13,7 @@
<v-list dense>
<v-card-title class="py-1">{{ group.name }}</v-card-title>
<v-divider></v-divider>
<v-subheader>Group ID: {{ group.id }}</v-subheader>
<v-subheader>{{ $t('user.group-id-with-value', { groupID: group.id }) }}</v-subheader>
<v-list-item-group color="primary">
<v-list-item v-for="property in groupProps" :key="property.text">
<v-list-item-icon>
@ -36,11 +36,11 @@
@click="confirmDelete"
:disabled="ableToDelete"
>
Delete
{{ $t('general.delete') }}
</v-btn>
<!-- Coming Soon! -->
<v-btn small color="success" disabled>
Edit
{{ $t('general.edit') }}
</v-btn>
</v-card-actions>
</v-card>
@ -94,22 +94,22 @@ export default {
buildData() {
this.groupProps = [
{
text: "Total Users",
text: this.$t('user.total-users'),
icon: "mdi-account",
value: this.group.users.length,
},
{
text: "Total MealPlans",
text: this.$t('user.total-mealplans'),
icon: "mdi-food",
value: this.group.mealplans.length,
},
{
text: "Webhooks Enabled",
text: this.$t('user.webhooks-enabled'),
icon: "mdi-webhook",
value: this.group.webhookEnable ? "True" : "False",
value: this.group.webhookEnable ? this.$t('general.yes') : this.$t('general.no'),
},
{
text: "Webhook Time",
text: this.$t('user.webhook-time'),
icon: "mdi-clock-outline",
value: this.group.webhookTime,
},

View file

@ -9,7 +9,7 @@
clearable
class="mr-2 pt-0"
append-icon="mdi-filter"
label="Filter"
:label="$t('general.filter')"
single-line
hide-details
></v-text-field>
@ -24,7 +24,7 @@
v-bind="attrs"
v-on="on"
>
Create Group
{{ $t('user.create-group') }}
</v-btn>
</template>
<v-card>
@ -34,7 +34,7 @@
</v-icon>
<v-toolbar-title class="headline">
Create Group
{{ $t('user.create-group') }}
</v-toolbar-title>
<v-spacer></v-spacer>
@ -44,7 +44,7 @@
<v-form ref="newGroup">
<v-text-field
v-model="newGroupName"
label="Group Name"
:label="$t('user.group-name')"
:rules="[existsRule]"
></v-text-field>
</v-form>
@ -53,10 +53,10 @@
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="grey" text @click="groupDialog = false">
Cancel
{{ $t('general.cancel') }}
</v-btn>
<v-btn color="primary" @click="createGroup">
Create
{{ $t('general.create') }}
</v-btn>
</v-card-actions>
</v-card>
@ -67,7 +67,7 @@
<v-col
:sm="6"
:md="6"
:lg="3"
:lg="4"
:xl="3"
v-for="group in groups"
:key="group.id"

View file

@ -2,8 +2,8 @@
<v-card outlined class="mt-n1">
<Confirmation
ref="deleteUserDialog"
title="Confirm User Deletion"
:message="`Are you sure you want to delete the link <b>${activeName}<b/>`"
:title="$t('user.confirm-link-deletion')"
:message="$t('user.are-you-sure-you-want-to-delete-the-link', {link: activeName })"
icon="mdi-alert"
@confirm="deleteUser"
:width="450"
@ -14,14 +14,14 @@
mdi-link-variant
</v-icon>
<v-toolbar-title class="headine">
Sign Up Links
{{ $t('user.sign-up-links') }}
</v-toolbar-title>
<v-spacer> </v-spacer>
<v-dialog v-model="dialog" max-width="600px">
<template v-slot:activator="{ on, attrs }">
<v-btn small color="success" dark v-bind="attrs" v-on="on">
Create Link
{{ $t('user.create-link') }}
</v-btn>
</template>
<v-card>
@ -31,7 +31,7 @@
</v-icon>
<v-toolbar-title class="headline">
Create Link
{{ $t('user.create-link') }}
</v-toolbar-title>
<v-spacer></v-spacer>
@ -43,13 +43,13 @@
<v-text-field
class="mr-2"
v-model="editedItem.name"
label="Link Name"
:label="$t('user.link-name')"
:rules="[existsRule]"
validate-on-blur
></v-text-field>
<v-checkbox
v-model="editedItem.admin"
label="Admin"
:label="$t('user.admin')"
></v-checkbox>
</v-row>
</v-form>
@ -58,10 +58,10 @@
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="grey" text @click="close">
Cancel
{{ $t('general.cancel') }}
</v-btn>
<v-btn color="primary" @click="save">
Save
{{ $t('general.save') }}
</v-btn>
</v-card-actions>
</v-card>
@ -90,7 +90,7 @@
<v-icon small left>
mdi-account-cog
</v-icon>
{{ item.admin ? "Yes" : "No" }}
{{ item.admin ? $t('general.yes') : $t('general.no') }}
</v-btn>
</template>
<template v-slot:item.actions="{ item }">
@ -98,7 +98,7 @@
<v-icon small left>
mdi-delete
</v-icon>
Delete
{{ $t('general.delete') }}
</v-btn>
</template>
</v-data-table>
@ -113,37 +113,39 @@ import { validators } from "@/mixins/validators";
export default {
components: { Confirmation },
mixins: [validators],
data: () => ({
dialog: false,
activeId: null,
activeName: null,
headers: [
{
text: "Link ID",
align: "start",
sortable: false,
value: "id",
data() {
return {
dialog: false,
activeId: null,
activeName: null,
headers: [
{
text: this.$t('user.link-id'),
align: "start",
sortable: false,
value: "id",
},
{ text: this.$t('general.name'), value: "name" },
{ text: this.$t('general.token'), value: "token" },
{ text: this.$t('user.admin'), value: "admin", align: "center" },
{ text: "", value: "actions", sortable: false, align: "center" },
],
links: [],
editedIndex: -1,
editedItem: {
name: "",
admin: false,
token: "",
id: 0,
},
{ text: "Name", value: "name" },
{ text: "Token", value: "token" },
{ text: "Admin", value: "admin", align: "center" },
{ text: "", value: "actions", sortable: false, align: "center" },
],
links: [],
editedIndex: -1,
editedItem: {
name: "",
admin: false,
token: "",
id: 0,
},
defaultItem: {
name: "",
token: "",
admin: false,
id: 0,
},
}),
defaultItem: {
name: "",
token: "",
admin: false,
id: 0,
},
}
},
computed: {
baseURL() {

View file

@ -2,10 +2,8 @@
<v-card outlined class="mt-n1">
<Confirmation
ref="deleteUserDialog"
title="Confirm User Deletion"
:message="
`Are you sure you want to delete the user <b>${activeName} ID: ${activeId}<b/>`
"
:title="$t('user.confirm-user-deletion')"
:message="$t('user.are-you-sure-you-want-to-delete-the-user', { activeName, activeId })"
icon="mdi-alert"
@confirm="deleteUser"
:width="450"
@ -18,7 +16,7 @@
v-model="search"
class="mr-2"
append-icon="mdi-filter"
label="Filter"
:label="$t('general.filter')"
single-line
hide-details
></v-text-field>
@ -27,7 +25,7 @@
<v-dialog v-model="dialog" max-width="600px">
<template v-slot:activator="{ on, attrs }">
<v-btn small color="success" dark v-bind="attrs" v-on="on">
Create User
{{$t('user.create-user')}}
</v-btn>
</template>
<v-card>
@ -42,7 +40,7 @@
<v-spacer></v-spacer>
<v-toolbar-title class="headline">
User ID: {{ editedItem.id }}
{{$t('user.user-id-with-value', {id: editedItem.id }) }}
</v-toolbar-title>
</v-app-bar>
@ -52,7 +50,7 @@
<v-col cols="12" sm="12" md="6">
<v-text-field
v-model="editedItem.fullName"
label="Full Name"
:label="$t('user.full-name')"
:rules="[existsRule]"
validate-on-blur
></v-text-field>
@ -60,7 +58,7 @@
<v-col cols="12" sm="12" md="6">
<v-text-field
v-model="editedItem.email"
label="Email"
:label="$t('user.email')"
:rules="[existsRule, emailRule]"
validate-on-blur
></v-text-field>
@ -70,19 +68,19 @@
dense
v-model="editedItem.group"
:items="existingGroups"
label="User Group"
:label="$t('user.user-group')"
></v-select>
</v-col>
<v-col cols="12" sm="12" md="6" v-if="showPassword">
<v-text-field
dense
v-model="editedItem.password"
label="User Password"
:label="$t('user.user-password')"
:rules="[existsRule, minRule]"
></v-text-field>
</v-col>
<v-col cols="12" sm="12" md="3">
<v-switch v-model="editedItem.admin" label="Admin"></v-switch>
<v-switch v-model="editedItem.admin" :label="$t('user.admin')"></v-switch>
</v-col>
</v-row>
</v-form>
@ -91,10 +89,10 @@
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="grey" text @click="close">
Cancel
{{$t('general.cancel')}}
</v-btn>
<v-btn color="primary" @click="save">
Save
{{$t('general.save')}}
</v-btn>
</v-card-actions>
</v-card>
@ -113,13 +111,13 @@
<v-icon small left>
mdi-delete
</v-icon>
Delete
{{$t('general.delete')}}
</v-btn>
<v-btn small color="success" @click="editItem(item)">
<v-icon small left class="mr-2">
mdi-pencil
</v-icon>
Edit
{{$t('general.edit')}}
</v-btn>
</template>
<template v-slot:item.admin="{ item }">
@ -127,7 +125,7 @@
</template>
<template v-slot:no-data>
<v-btn color="primary" @click="initialize">
Reset
{{$t('general.reset')}}
</v-btn>
</template>
</v-data-table>
@ -142,47 +140,49 @@ import { validators } from "@/mixins/validators";
export default {
components: { Confirmation },
mixins: [validators],
data: () => ({
search: "",
dialog: false,
activeId: null,
activeName: null,
headers: [
{
text: "User ID",
align: "start",
sortable: false,
value: "id",
data() {
return {
search: "",
dialog: false,
activeId: null,
activeName: null,
headers: [
{
text: this.$t("user.user-id"),
align: "start",
sortable: false,
value: "id",
},
{ text: this.$t('user.full-name'), value: "fullName" },
{ text: this.$t('user.email'), value: "email" },
{ text: this.$t('user.group'), value: "group" },
{ text: this.$t('user.admin'), value: "admin" },
{ text: "", value: "actions", sortable: false, align: "center" },
],
users: [],
editedIndex: -1,
editedItem: {
id: 0,
fullName: "",
password: "",
email: "",
group: "",
admin: false,
},
{ text: "Full Name", value: "fullName" },
{ text: "Email", value: "email" },
{ text: "Group", value: "group" },
{ text: "Admin", value: "admin" },
{ text: "", value: "actions", sortable: false, align: "center" },
],
users: [],
editedIndex: -1,
editedItem: {
id: 0,
fullName: "",
password: "",
email: "",
group: "",
admin: false,
},
defaultItem: {
id: 0,
fullName: "",
password: "",
email: "",
group: "",
admin: false,
},
}),
defaultItem: {
id: 0,
fullName: "",
password: "",
email: "",
group: "",
admin: false,
},
}
},
computed: {
formTitle() {
return this.editedIndex === -1 ? "New User" : "Edit User";
return this.editedIndex === -1 ? this.$t('user.new-user') : this.$t('user.edit-user');
},
showPassword() {
return this.editedIndex === -1 ? true : false;

View file

@ -10,7 +10,7 @@
/>
<v-card flat outlined class="ma-2">
<v-card-text class="mb-n5 mt-n2">
<h3>{{ theme.name }} {{ current ? "(Current)" : "" }}</h3>
<h3>{{ theme.name }} {{ current ? $t('general.current-parenthesis') : "" }}</h3>
</v-card-text>
<v-card-text>
<v-row flex align-center>
@ -27,10 +27,10 @@
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-btn text color="error" @click="confirmDelete"> Delete </v-btn>
<v-btn text color="error" @click="confirmDelete"> {{$t('general.delete')}} </v-btn>
<v-spacer></v-spacer>
<!-- <v-btn text color="accent" @click="editTheme">Edit</v-btn> -->
<v-btn text color="success" @click="saveThemes">Apply</v-btn>
<v-btn text color="success" @click="saveThemes">{{$t('general.apply')}}</v-btn>
</v-card-actions>
</v-card>
</div>

View file

@ -13,7 +13,7 @@
class="mr-2"
>
</v-progress-circular>
<v-toolbar-title class="headline"> Login </v-toolbar-title>
<v-toolbar-title class="headline">{{$t('user.login')}}</v-toolbar-title>
<v-spacer></v-spacer>
</v-app-bar>
<v-card-text>
@ -30,7 +30,7 @@
light="light"
prepend-icon="mdi-email"
validate-on-blur
:label="$t('login.email')"
:label="$t('user.email')"
type="email"
></v-text-field>
<v-text-field
@ -38,7 +38,7 @@
light="light"
class="mb-2s"
prepend-icon="mdi-lock"
:label="$t('login.password')"
:label="$t('user.password')"
:type="showPassword ? 'text' : 'password'"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
@click:append="showPassword = !showPassword"
@ -52,11 +52,11 @@
color="primary"
block="block"
type="submit"
>{{ $t("login.sign-in") }}</v-btn
>{{ $t("user.sign-in") }}</v-btn
>
</v-card-actions>
<v-alert v-if="error" outlined class="mt-3 mb-0" type="error">
Could Not Validate Credentials
{{$t('user.could-not-validate-credentials')}}
</v-alert>
</v-card-text>
</v-card>

View file

@ -37,7 +37,7 @@
prepend-icon="mdi-email"
validate-on-blur
:rules="[existsRule, emailRule]"
:label="$t('login.email')"
:label="$t('user.email')"
type="email"
></v-text-field>
<v-text-field
@ -46,7 +46,7 @@
class="mb-2s"
prepend-icon="mdi-lock"
validate-on-blur
:label="$t('login.password')"
:label="$t('user.password')"
:type="showPassword ? 'text' : 'password'"
:rules="[minRule]"
></v-text-field>
@ -55,7 +55,7 @@
light="light"
class="mb-2s"
prepend-icon="mdi-lock"
:label="$t('login.password')"
:label="$t('user.password')"
:type="showPassword ? 'text' : 'password'"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
:rules="[

View file

@ -15,15 +15,15 @@
<v-menu offset-y v-if="sortable">
<template v-slot:activator="{ on, attrs }">
<v-btn-toggle group>
<v-btn text v-bind="attrs" v-on="on"> Sort </v-btn>
<v-btn text v-bind="attrs" v-on="on">{{$t('general.sort')}}</v-btn>
</v-btn-toggle>
</template>
<v-list>
<v-list-item @click="$emit('sort-recent')">
<v-list-item-title> Recent </v-list-item-title>
<v-list-item-title>{{$t('general.recent')}}</v-list-item-title>
</v-list-item>
<v-list-item @click="$emit('sort')">
<v-list-item-title> A-Z </v-list-item-title>
<v-list-item-title>{{$t('general.sort-alphabetically')}}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>

View file

@ -54,31 +54,31 @@ export default {
},
{
icon: "mdi-calendar-week",
title: this.$i18n.t("meal-plan.dinner-this-week"),
title: this.$t("meal-plan.dinner-this-week"),
nav: "/meal-plan/this-week",
restricted: true,
},
{
icon: "mdi-calendar-today",
title: this.$i18n.t("meal-plan.dinner-today"),
title: this.$t("meal-plan.dinner-today"),
nav: "/meal-plan/today",
restricted: true,
},
{
icon: "mdi-calendar-multiselect",
title: this.$i18n.t("meal-plan.planner"),
title: this.$t("meal-plan.planner"),
nav: "/meal-plan/planner",
restricted: true,
},
{
icon: "mdi-account",
title: "Logout",
icon: "mdi-logout",
title: this.$t('user.logout'),
restricted: true,
nav: "/logout",
},
{
icon: "mdi-cog",
title: this.$i18n.t("general.settings"),
title: this.$t("general.settings"),
nav: "/admin",
restricted: true,
},

View file

@ -30,7 +30,7 @@
"download": "Hent",
"import": "Importere"
},
"login": {
"user": {
"email": "E-mail",
"password": "Adgangskode",
"sign-in": "Log ind",

View file

@ -41,7 +41,7 @@
"all-recipes": "Alle Rezepte",
"recent": "Neueste"
},
"login": {
"user": {
"stay-logged-in": "Eingeloggt bleiben?",
"email": "E-Mail",
"password": "Passwort",

View file

@ -1,12 +1,4 @@
{
"dateTimeFormats": {
"short": {
"month": "short",
"day": "numeric",
"weekday": "long"
}
},
"404": {
"page-not-found": "404 Page Not Found",
"take-me-home": "Take me Home"
@ -43,19 +35,71 @@
"templates": "Templates",
"recipes": "Recipes",
"themes": "Themes",
"confirm": "Confirm"
"confirm": "Confirm",
"sort": "Sort",
"recent": "Recent",
"sort-alphabetically": "A-Z",
"reset": "Reset",
"filter": "Filter",
"yes": "Yes",
"no": "No",
"token": "Token",
"field-required": "Field Required",
"apply": "Apply",
"current-parenthesis": "(Current)"
},
"page": {
"home-page": "Home Page",
"all-recipes": "All Recipes",
"recent": "Recent"
},
"login": {
"user": {
"stay-logged-in": "Stay logged in?",
"email": "Email",
"password": "Password",
"sign-in": "Sign in",
"sign-up": "Sign up"
"sign-up": "Sign up",
"logout": "Logout",
"full-name": "Full Name",
"user-group": "User Group",
"user-password": "User Password",
"admin": "Admin",
"user-id": "User ID",
"user-id-with-value": "User ID: {id}",
"group": "Group",
"new-user": "New User",
"edit-user": "Edit User",
"create-user": "Create User",
"confirm-user-deletion": "Confirm User Deletion",
"are-you-sure-you-want-to-delete-the-user": "Are you sure you want to delete the user <b>{activeName} ID: {activeId}<b/>?",
"confirm-group-deletion": "Confirm Group Deletion",
"total-users": "Total Users",
"total-mealplans": "Total MealPlans",
"webhooks-enabled": "Webhooks Enabled",
"webhook-time": "Webhook Time",
"create-group": "Create Group",
"sign-up-links": "Sign Up Links",
"create-link": "Create Link",
"link-name": "Link Name",
"group-id-with-value": "Group ID: {groupID}",
"are-you-sure-you-want-to-delete-the-group": "Are you sure you want to delete <b>{groupName}<b/>?",
"group-name": "Group Name",
"confirm-link-deletion": "Confirm Link Deletion",
"are-you-sure-you-want-to-delete-the-link": "Are you sure you want to delete the link <b>{link}<b/>?",
"link-id": "Link ID",
"users": "Users",
"groups": "Groups",
"could-not-validate-credentials": "Could Not Validate Credentials",
"login": "Login",
"groups-can-only-be-set-by-administrators": "Groups can only be set by administrators",
"upload-photo": "Upload Photo",
"reset-password": "Reset Password",
"current-password": "Current Password",
"new-password": "New Password",
"confirm-password": "Confirm Password",
"password-must-match": "Password must match",
"e-mail-must-be-valid": "E-mail must be valid",
"use-8-characters-or-more-for-your-password": "Use 8 characters or more for your password"
},
"meal-plan": {
"shopping-list": "Shopping List",
@ -163,8 +207,13 @@
"homepage-categories": "Homepage Categories",
"home-page": "Home Page",
"all-categories": "All Categories",
"show-recent": "Show Recent"
}
"show-recent": "Show Recent",
"home-page-sections": "Home Page Sections"
},
"site-settings": "Site Settings",
"manage-users": "Manage Users",
"migrations": "Migrations",
"profile": "Profile"
},
"migration": {
"recipe-migration": "Recipe Migration",
@ -181,4 +230,4 @@
"description": "Migrate data from Chowdown"
}
}
}
}

View file

@ -1,12 +1,4 @@
{
"dateTimeFormats": {
"short": {
"month": "short",
"day": "numeric",
"weekday": "long"
}
},
"404": {
"page-not-found": "404 Page introuvable",
"take-me-home": "Retour à l'accueil"
@ -28,7 +20,7 @@
"save": "Sauvegarder",
"image-file": "Image",
"update": "Mettre à jour",
"edit": "Editer",
"edit": "Modifier",
"delete": "Supprimer",
"select": "Sélectionner",
"random": "Aléatoire",
@ -43,19 +35,71 @@
"templates": "Modèles",
"recipes": "Recettes",
"themes": "Thèmes",
"confirm": "Confirmer"
"confirm": "Confirmer",
"recent": "Récent",
"sort": "Trier",
"sort-alphabetically": "A-Z",
"reset": "Réinitialiser",
"filter": "Filtrer",
"no": "Non",
"yes": "Oui",
"token": "Jeton",
"field-required": "Champ obligatoire",
"apply": "Appliquer",
"current-parenthesis": "(Actuel)"
},
"page": {
"home-page": "Accueil",
"all-recipes": "Toutes mes recettes",
"recent": "Récent"
},
"login": {
"user": {
"stay-logged-in": "Rester connecté(e) ?",
"email": "Email",
"email": "E-mail",
"password": "Mot de passe",
"sign-in": "Se connecter",
"sign-up": "S'inscrire"
"sign-up": "S'inscrire",
"logout": "Déconnexion",
"admin": "Admin",
"edit-user": "Modifier l'utilisateur",
"full-name": "Nom",
"group": "Groupe",
"new-user": "Nouvel utilisateur",
"user-group": "Groupe utilisateur",
"user-id": "ID utilisateur",
"user-password": "Mot de passe de l'utilisateur",
"create-user": "Créer utilisateur",
"are-you-sure-you-want-to-delete-the-user": "Êtes-vous sûr de vouloir supprimer l'utilisateur <b>{activeName} ID : {activeId}<b/> ?",
"confirm-user-deletion": "Confirmer la suppression",
"confirm-group-deletion": "Confirmer la suppression du groupe",
"create-group": "Créer un groupe",
"create-link": "Créer un lien",
"group-id-with-value": "ID groupe : {groupID}",
"are-you-sure-you-want-to-delete-the-group": "Êtes-vous sûr de vouloir supprimer <b>{groupName}<b/> ?",
"link-name": "Nom du lien",
"sign-up-links": "Liens d'inscription",
"total-mealplans": "Nombre de repas planifiés",
"total-users": "Nombre d'utilisateurs",
"user-id-with-value": "ID utilisateur : {id}",
"webhook-time": "Heure du Webhook",
"webhooks-enabled": "Webhooks activés",
"are-you-sure-you-want-to-delete-the-link": "Êtes-vous sûr de vouloir supprimer le lien <b>{link}<b/> ?",
"confirm-link-deletion": "Confirmer la suppresion du lien",
"group-name": "Nom du groupe",
"link-id": "ID du lien",
"groups": "Groupes",
"users": "Utilisateurs",
"could-not-validate-credentials": "La vérification de vos identifiants a échoué",
"login": "Connexion",
"groups-can-only-be-set-by-administrators": "Les groupes sont assignés par les administrateurs",
"confirm-password": "Confirmer mot de passe",
"current-password": "Mot de passe actuel",
"e-mail-must-be-valid": "L'e-mail doit être valide",
"new-password": "Nouveau mot de passe",
"password-must-match": "Les mots de passe doivent correspondre",
"reset-password": "Réinitialiser le mot de passe",
"upload-photo": "Importer une photo",
"use-8-characters-or-more-for-your-password": "Utiliser au moins 8 caractères pour votre mot de passe"
},
"meal-plan": {
"shopping-list": "Liste d'achats",
@ -108,12 +152,12 @@
"local-api": "API local",
"language": "Langue",
"add-a-new-theme": "Ajouter un nouveau thème",
"set-new-time": "Indiquer un nouveau temps",
"set-new-time": "Indiquer une nouvelle heure",
"current": "Version :",
"latest": "Dernière",
"explore-the-docs": "Parcourir la documentation",
"contribute": "Contribuer",
"backup-and-exports": "Sauver et exporter",
"backup-and-exports": "Sauvegardes",
"backup-info": "Les sauvegardes sont exportées en format JSON standard, ainsi que toutes les images stockées sur le système. Dans votre dossier de sauvegarde, vous trouverez un dossier .zip qui contient toutes les recettes en JSON et les images de la base de données. De plus, si vous avez sélectionné le format de fichier markdown, il sera sauvegardé dans le même dossier .zip. Pour importer une sauvegarde, celle-ci doit être enregistrée dans votre dossier de sauvegardes. Une sauvegarde automatique est effectuée quotidiennement à 03h00.",
"available-backups": "Sauvegardes disponibles",
"theme": {
@ -163,8 +207,13 @@
"card-per-section": "Tuiles par section",
"home-page": "Page d'accueil",
"homepage-categories": "Catégories de la page d'accueil",
"show-recent": "Afficher les récentes"
}
"show-recent": "Afficher les récentes",
"home-page-sections": "Sections de la page d'accueil"
},
"manage-users": "Utilisateurs",
"migrations": "Migrations",
"profile": "Profil",
"site-settings": "Paramètres site"
},
"migration": {
"recipe-migration": "Migrer les recettes",
@ -180,5 +229,6 @@
"title": "Chowdown",
"description": "Importer des recettes depuis Chowdown"
}
}
},
"auth": {}
}

View file

@ -36,7 +36,7 @@
"themes": "Motywy",
"confirm": "Potwierdź"
},
"login": {
"user": {
"stay-logged-in": "Pozostań zalogowany",
"email": "Email",
"password": "Hasło",

View file

@ -30,7 +30,7 @@
"download": "Ladda ner",
"import": "Importera"
},
"login": {
"user": {
"email": "E-mail",
"password": "Lösenord",
"sign-in": "Logga in",

View file

@ -36,7 +36,7 @@
"themes": "布景主题",
"confirm": "确定"
},
"login": {
"user": {
"stay-logged-in": "保持登录状态?",
"email": "电子邮件",
"password": "密码",

View file

@ -36,7 +36,7 @@
"themes": "佈景主題",
"confirm": "確定"
},
"login": {
"user": {
"stay-logged-in": "保持登錄狀態?",
"email": "電子郵件",
"password": "密碼",

View file

@ -4,12 +4,12 @@ export const validators = {
emailRule: v =>
!v ||
/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(v) ||
"E-mail must be valid",
this.$t('user.e-mail-must-be-valid'),
existsRule: value => !!value || "Field Required",
existsRule: value => !!value || this.$t('general.field-required'),
minRule: v =>
v.length >= 8 || "Use 8 characters or more for your password",
v.length >= 8 || this.$t('user.use-8-characters-or-more-for-your-password'),
};
},
};

View file

@ -11,17 +11,17 @@
<v-tabs-slider></v-tabs-slider>
<v-tab>
Users
{{$t('user.users')}}
<v-icon>mdi-account</v-icon>
</v-tab>
<v-tab>
Sign-Up Links
{{$t('user.sign-up-links')}}
<v-icon>mdi-account-plus-outline</v-icon>
</v-tab>
<v-tab>
Groups
{{$t('user.groups')}}
<v-icon>mdi-account-group</v-icon>
</v-tab>
</v-tabs>

View file

@ -13,9 +13,9 @@
>
</v-progress-circular>
</span>
Profile
{{$t('settings.profile')}}
<v-spacer></v-spacer>
User ID: {{ user.id }}
{{$t('user.user-id-with-value', {id: user.id }) }}
</v-card-title>
<v-divider></v-divider>
<v-card-text>
@ -39,7 +39,7 @@
<v-col cols="12" md="9">
<v-form>
<v-text-field
label="Full Name"
:label="$t('user.full-name')"
required
v-model="user.fullName"
:rules="[existsRule]"
@ -47,7 +47,7 @@
>
</v-text-field>
<v-text-field
label="Email"
:label="$t('user.email')"
:rules="[emailRule]"
validate-on-blur
required
@ -55,11 +55,11 @@
>
</v-text-field>
<v-text-field
label="Group"
:label="$t('user.group')"
readonly
v-model="user.group"
persistent-hint
hint="Group groups can only be set by administrators"
:hint="$t('user.groups-can-only-be-set-by-administrators')"
>
</v-text-field>
</v-form>
@ -70,7 +70,7 @@
<v-card-actions>
<UploadBtn
icon="mdi-image-area"
text="Upload Photo"
:text="$t('user.upload-photo')"
:url="userProfileImage"
file-name="profile_image"
/>
@ -86,7 +86,7 @@
<v-col cols="12" md="4" sm="12">
<v-card height="100%">
<v-card-title class="headline">
Reset Password
{{$t('user.reset-password')}}
<v-spacer></v-spacer>
</v-card-title>
<v-divider></v-divider>
@ -95,7 +95,7 @@
<v-text-field
v-model="password.current"
prepend-icon="mdi-lock"
label="Current Password"
:label="$t('user.current-password')"
:rules="[existsRule]"
validate-on-blur
:type="showPassword ? 'text' : 'password'"
@ -104,7 +104,7 @@
<v-text-field
v-model="password.newOne"
prepend-icon="mdi-lock"
label="New Password"
:label="$t('user.new-password')"
:rules="[minRule]"
:type="showPassword ? 'text' : 'password'"
@click:append="showPassword.newOne = !showPassword.newOne"
@ -112,9 +112,9 @@
<v-text-field
v-model="password.newTwo"
prepend-icon="mdi-lock"
label="Confirm Password"
:label="$t('user.confirm-password')"
:rules="[
password.newOne === password.newTwo || 'Password must match',
password.newOne === password.newTwo || $t('user.password-must-match'),
]"
validate-on-blur
:type="showPassword ? 'text' : 'password'"

View file

@ -3,6 +3,12 @@ import Vuetify from "vuetify/lib";
Vue.use(Vuetify);
import fr from 'vuetify/es5/locale/fr';
import pl from 'vuetify/es5/locale/pl';
import sv from 'vuetify/es5/locale/sv';
import de from 'vuetify/es5/locale/de';
const vuetify = new Vuetify({
theme: {
dark: false,
@ -29,6 +35,12 @@ const vuetify = new Vuetify({
},
},
},
lang: {
locales: {
fr, pl, sv, de
},
current: 'en',
},
});
export default vuetify;

View file

@ -46,8 +46,9 @@ const mutations = {
};
const actions = {
initLang({ getters }) {
initLang({ getters }, { currentVueComponent }) {
VueI18n.locale = getters.getActiveLang;
currentVueComponent.$vuetify.lang.current = getters.getActiveLang;
},
};

View file

@ -110,7 +110,7 @@ async def update_user_image(
shutil.copyfileobj(profile_image.file, buffer)
if dest.is_file:
return SnackResponse.success("Backup uploaded")
return SnackResponse.success("File uploaded")
else:
return SnackResponse.error("Failure uploading file")