mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 14:33:33 -07:00
More localization (#208)
* remove unused strings * update i18n-ally settings * localized date picker * Translate CardSection * SiteMenu translatable * Translate TheUserTable * Use embedded Vuetify locales * localize TheUserTable * Localize group and sign up settings * Slightly enlarge group tile width * Localize admin side bar + user nav bar * Missing strings in Login form * Fix success message upon photo upload * Localize profile page * Missing translations in settings
This commit is contained in:
parent
44935ea72d
commit
40c12b6c37
27 changed files with 316 additions and 201 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -12,7 +12,8 @@
|
|||
"python.testing.autoTestDiscoverOnSaveEnabled": false,
|
||||
"cSpell.enableFiletypes": ["!javascript", "!python"],
|
||||
"python.testing.pytestArgs": ["mealie"],
|
||||
"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"],
|
||||
|
|
|
@ -70,7 +70,7 @@ export default {
|
|||
this.search = !this.search;
|
||||
}
|
||||
});
|
||||
this.$store.dispatch("initLang");
|
||||
this.$store.dispatch("initLang", { currentVueComponent: this });
|
||||
},
|
||||
|
||||
mounted() {
|
||||
|
|
|
@ -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'),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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="[
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
"download": "Hent",
|
||||
"import": "Importere"
|
||||
},
|
||||
"login": {
|
||||
"user": {
|
||||
"email": "E-mail",
|
||||
"password": "Adgangskode",
|
||||
"sign-in": "Log ind",
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
"all-recipes": "Alle Rezepte",
|
||||
"recent": "Neueste"
|
||||
},
|
||||
"login": {
|
||||
"user": {
|
||||
"stay-logged-in": "Eingeloggt bleiben?",
|
||||
"email": "E-Mail",
|
||||
"password": "Passwort",
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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": {}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
"themes": "Motywy",
|
||||
"confirm": "Potwierdź"
|
||||
},
|
||||
"login": {
|
||||
"user": {
|
||||
"stay-logged-in": "Pozostań zalogowany",
|
||||
"email": "Email",
|
||||
"password": "Hasło",
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
"download": "Ladda ner",
|
||||
"import": "Importera"
|
||||
},
|
||||
"login": {
|
||||
"user": {
|
||||
"email": "E-mail",
|
||||
"password": "Lösenord",
|
||||
"sign-in": "Logga in",
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
"themes": "布景主题",
|
||||
"confirm": "确定"
|
||||
},
|
||||
"login": {
|
||||
"user": {
|
||||
"stay-logged-in": "保持登录状态?",
|
||||
"email": "电子邮件",
|
||||
"password": "密码",
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
"themes": "佈景主題",
|
||||
"confirm": "確定"
|
||||
},
|
||||
"login": {
|
||||
"user": {
|
||||
"stay-logged-in": "保持登錄狀態?",
|
||||
"email": "電子郵件",
|
||||
"password": "密碼",
|
||||
|
|
|
@ -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'),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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'"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -46,8 +46,9 @@ const mutations = {
|
|||
};
|
||||
|
||||
const actions = {
|
||||
initLang({ getters }) {
|
||||
initLang({ getters }, { currentVueComponent }) {
|
||||
VueI18n.locale = getters.getActiveLang;
|
||||
currentVueComponent.$vuetify.lang.current = getters.getActiveLang;
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -112,7 +112,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")
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue