mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-11-03 18:53:17 -05:00 
			
		
		
		
	More localization (#358)
* Translate missing items on About page * Localize import summary dialog * Make site menu translation reactive * Localize import options * Include semi colon in string * Move API texts to frontend + better status codes * Provide feedback to user when no meal is planned * Fix API tests after latest rework * Add warning for API changes in changelog * Refactor API texts handling * Refactor API texts handling #2 * Better API feedback * Rearrange strings hierarchy * Add messages upon recipe updated * Fix 'recipe effected' typo * Remove snackbar usage in backend * Translate toolbox * Provide feedback for tags CRUD * Fix messed up merge * Translate sign-up form * Better feedback for sign-up CRUD * Refactor log-in API texts handling * No error message when user is not authenticated * Remove unimportant console log
This commit is contained in:
		@@ -90,7 +90,7 @@ export default {
 | 
			
		||||
  computed: {
 | 
			
		||||
    inputLabel() {
 | 
			
		||||
      if (!this.showLabel) return null;
 | 
			
		||||
      return this.tagSelector ? this.$t('recipe.tags') : this.$t('recipe.categories');
 | 
			
		||||
      return this.tagSelector ? this.$t('tag.tags') : this.$t('recipe.categories');
 | 
			
		||||
    },
 | 
			
		||||
    activeItems() {
 | 
			
		||||
      let ItemObjects = [];
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
            mdi-import
 | 
			
		||||
          </v-icon>
 | 
			
		||||
          <v-toolbar-title class="headline">
 | 
			
		||||
            Import Summary
 | 
			
		||||
            {{ $t("settings.backup.import-summary") }}
 | 
			
		||||
          </v-toolbar-title>
 | 
			
		||||
          <v-spacer></v-spacer>
 | 
			
		||||
        </v-app-bar>
 | 
			
		||||
@@ -18,8 +18,8 @@
 | 
			
		||||
                <div>
 | 
			
		||||
                  <h3>{{ values.title }}</h3>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="success--text">Success: {{ values.success }}</div>
 | 
			
		||||
                <div class="error--text">Failed: {{ values.failure }}</div>
 | 
			
		||||
                <div class="success--text">{{ $t("general.success-count", { count: values.success }) }}</div>
 | 
			
		||||
                <div class="error--text">{{ $t("general.failed-count", { count: values.failure }) }}</div>
 | 
			
		||||
              </v-card-text>
 | 
			
		||||
            </div>
 | 
			
		||||
          </v-row>
 | 
			
		||||
@@ -28,7 +28,7 @@
 | 
			
		||||
          <v-tab>{{ $t("general.recipes") }}</v-tab>
 | 
			
		||||
          <v-tab>{{ $t("general.themes") }}</v-tab>
 | 
			
		||||
          <v-tab>{{ $t("general.settings") }}</v-tab>
 | 
			
		||||
          <v-tab> Pages </v-tab>
 | 
			
		||||
          <v-tab> {{ $t("settings.pages") }} </v-tab>
 | 
			
		||||
          <v-tab>{{ $t("general.users") }}</v-tab>
 | 
			
		||||
          <v-tab>{{ $t("general.groups") }}</v-tab>
 | 
			
		||||
        </v-tabs>
 | 
			
		||||
@@ -59,24 +59,30 @@ export default {
 | 
			
		||||
    userData: [],
 | 
			
		||||
    groupData: [],
 | 
			
		||||
    pageData: [],
 | 
			
		||||
    importHeaders: [
 | 
			
		||||
      {
 | 
			
		||||
        text: "Status",
 | 
			
		||||
        value: "status",
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        text: "Name",
 | 
			
		||||
        align: "start",
 | 
			
		||||
        sortable: true,
 | 
			
		||||
        value: "name",
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
      { text: "Exception", value: "data-table-expand", align: "center" },
 | 
			
		||||
    ],
 | 
			
		||||
    allDataTables: [],
 | 
			
		||||
  }),
 | 
			
		||||
 | 
			
		||||
  computed: {
 | 
			
		||||
    
 | 
			
		||||
    importHeaders() {
 | 
			
		||||
      return [
 | 
			
		||||
        {
 | 
			
		||||
          text: this.$t('general.status'),
 | 
			
		||||
          value: "status",
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: this.$t('general.name'),
 | 
			
		||||
          align: "start",
 | 
			
		||||
          sortable: true,
 | 
			
		||||
          value: "name",
 | 
			
		||||
        },
 | 
			
		||||
        { 
 | 
			
		||||
          text: this.$t('general.exception'), 
 | 
			
		||||
          value: "data-table-expand", 
 | 
			
		||||
          align: "center" 
 | 
			
		||||
        },
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
    recipeNumbers() {
 | 
			
		||||
      return this.calculateNumbers(this.$t("general.recipes"), this.recipeData);
 | 
			
		||||
    },
 | 
			
		||||
@@ -96,7 +102,7 @@ export default {
 | 
			
		||||
      return this.calculateNumbers(this.$t("general.groups"), this.groupData);
 | 
			
		||||
    },
 | 
			
		||||
    pageNumbers() {
 | 
			
		||||
      return this.calculateNumbers("Pages", this.pageData);
 | 
			
		||||
      return this.calculateNumbers(this.$t("settings.pages"), this.pageData);
 | 
			
		||||
    },
 | 
			
		||||
    allNumbers() {
 | 
			
		||||
      return [
 | 
			
		||||
 
 | 
			
		||||
@@ -91,18 +91,12 @@ export default {
 | 
			
		||||
      let formData = new FormData();
 | 
			
		||||
      formData.append("username", this.user.email);
 | 
			
		||||
      formData.append("password", this.user.password);
 | 
			
		||||
      let key;
 | 
			
		||||
      try {
 | 
			
		||||
        key = await api.users.login(formData);
 | 
			
		||||
      } catch {
 | 
			
		||||
      const response = await api.users.login(formData);
 | 
			
		||||
      if (!response) {
 | 
			
		||||
        this.error = true;
 | 
			
		||||
      }
 | 
			
		||||
      if (key.status != 200) {
 | 
			
		||||
        this.error = true;
 | 
			
		||||
        this.loading = false;
 | 
			
		||||
      } else {
 | 
			
		||||
        this.clear();
 | 
			
		||||
        this.$store.commit("setToken", key.data.access_token);
 | 
			
		||||
        this.$store.commit("setToken", response.data.access_token);
 | 
			
		||||
        this.$emit("logged-in");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,13 +13,13 @@
 | 
			
		||||
        class="mr-2"
 | 
			
		||||
      >
 | 
			
		||||
      </v-progress-circular>
 | 
			
		||||
      <v-toolbar-title class="headline"> Sign Up </v-toolbar-title>
 | 
			
		||||
      <v-toolbar-title class="headline"> 
 | 
			
		||||
        {{$t('signup.sign-up')}} 
 | 
			
		||||
      </v-toolbar-title>
 | 
			
		||||
      <v-spacer></v-spacer>
 | 
			
		||||
    </v-app-bar>
 | 
			
		||||
    <v-card-text>
 | 
			
		||||
      Welcome to Mealie! To become a user of this instance you are required to
 | 
			
		||||
      have a valid invitation link. If you haven't recieved an invitation you
 | 
			
		||||
      are unable to sign-up. To recieve a link, contact the sites administrator.
 | 
			
		||||
      {{$t('signup.welcome-to-mealie')}}
 | 
			
		||||
      <v-divider class="mt-3"></v-divider>
 | 
			
		||||
      <v-form ref="signUpForm" @submit.prevent="signUp">
 | 
			
		||||
        <v-text-field
 | 
			
		||||
@@ -28,7 +28,7 @@
 | 
			
		||||
          prepend-icon="mdi-account"
 | 
			
		||||
          validate-on-blur
 | 
			
		||||
          :rules="[existsRule]"
 | 
			
		||||
          label="Display Name"
 | 
			
		||||
          :label="$t('signup.display-name')"
 | 
			
		||||
          type="email"
 | 
			
		||||
        ></v-text-field>
 | 
			
		||||
        <v-text-field
 | 
			
		||||
@@ -59,7 +59,7 @@
 | 
			
		||||
          :type="showPassword ? 'text' : 'password'"
 | 
			
		||||
          :append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
 | 
			
		||||
          :rules="[
 | 
			
		||||
            user.password === user.passwordConfirm || 'Password must match',
 | 
			
		||||
            user.password === user.passwordConfirm || $t('user.password-must-match'),
 | 
			
		||||
          ]"
 | 
			
		||||
          @click:append="showPassword = !showPassword"
 | 
			
		||||
        ></v-text-field>
 | 
			
		||||
@@ -71,11 +71,11 @@
 | 
			
		||||
            block="block"
 | 
			
		||||
            type="submit"
 | 
			
		||||
          >
 | 
			
		||||
            Sign Up
 | 
			
		||||
            {{$t('signup.sign-up')}}
 | 
			
		||||
          </v-btn>
 | 
			
		||||
        </v-card-actions>
 | 
			
		||||
        <v-alert dense v-if="error" outlined class="mt-3 mb-0" type="error">
 | 
			
		||||
          Error Signing Up
 | 
			
		||||
          {{$t('signup.error-signing-up')}}
 | 
			
		||||
        </v-alert>
 | 
			
		||||
      </v-form>
 | 
			
		||||
    </v-card-text>
 | 
			
		||||
@@ -132,18 +132,16 @@ export default {
 | 
			
		||||
        admin: false,
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      let successUser = false;
 | 
			
		||||
      if (this.$refs.signUpForm.validate()) {
 | 
			
		||||
        let response = await api.signUps.createUser(this.token, userData);
 | 
			
		||||
        successUser = response.snackbar.text.includes("Created");
 | 
			
		||||
        if (await api.signUps.createUser(this.token, userData)) {
 | 
			
		||||
          this.$emit("user-created");
 | 
			
		||||
          this.$router.push("/");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.$emit("user-created");
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
      this.loading = false;
 | 
			
		||||
      if (successUser) {
 | 
			
		||||
        this.$router.push("/");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -36,8 +36,9 @@ export default {
 | 
			
		||||
      return utils.getDateAsPythonDate(dateObject);
 | 
			
		||||
    },
 | 
			
		||||
    async update() {
 | 
			
		||||
      await api.mealPlans.update(this.mealPlan.uid, this.mealPlan);
 | 
			
		||||
      this.$emit("updated");
 | 
			
		||||
      if (await api.mealPlans.update(this.mealPlan.uid, this.mealPlan)) {
 | 
			
		||||
        this.$emit("updated");
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -197,11 +197,12 @@ export default {
 | 
			
		||||
        endDate: this.endDate,
 | 
			
		||||
        meals: this.meals,
 | 
			
		||||
      };
 | 
			
		||||
      await api.mealPlans.create(mealBody);
 | 
			
		||||
      this.$emit(CREATE_EVENT);
 | 
			
		||||
      this.meals = [];
 | 
			
		||||
      this.startDate = null;
 | 
			
		||||
      this.endDate = null;
 | 
			
		||||
      if (await api.mealPlans.create(mealBody)) {
 | 
			
		||||
        this.$emit(CREATE_EVENT);
 | 
			
		||||
        this.meals = [];
 | 
			
		||||
        this.startDate = null;
 | 
			
		||||
        this.endDate = null;
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getImage(image) {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
          <v-icon left>
 | 
			
		||||
            mdi-image
 | 
			
		||||
          </v-icon>
 | 
			
		||||
          {{ $t("recipe.image") }}
 | 
			
		||||
          {{ $t("general.image") }}
 | 
			
		||||
        </v-btn>
 | 
			
		||||
      </template>
 | 
			
		||||
      <v-card width="400">
 | 
			
		||||
@@ -71,8 +71,9 @@ export default {
 | 
			
		||||
    },
 | 
			
		||||
    async getImageFromURL() {
 | 
			
		||||
      this.loading = true;
 | 
			
		||||
      const response = await api.recipes.updateImagebyURL(this.slug, this.url);
 | 
			
		||||
      if (response) this.$emit(REFRESH_EVENT);
 | 
			
		||||
      if (await api.recipes.updateImagebyURL(this.slug, this.url)) {
 | 
			
		||||
        this.$emit(REFRESH_EVENT);
 | 
			
		||||
      }
 | 
			
		||||
      this.loading = false;
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@
 | 
			
		||||
            :show-label="false"
 | 
			
		||||
          />
 | 
			
		||||
 | 
			
		||||
          <h2 class="mt-4">{{ $t("recipe.tags") }}</h2>
 | 
			
		||||
          <h2 class="mt-4">{{ $t("tag.tags") }}</h2>
 | 
			
		||||
          <CategoryTagSelector
 | 
			
		||||
            :return-object="false"
 | 
			
		||||
            v-model="value.tags"
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@
 | 
			
		||||
            </v-card>
 | 
			
		||||
            <v-card class="mt-2" v-if="tags.length > 0">
 | 
			
		||||
              <v-card-title class="py-2">
 | 
			
		||||
                {{ $t("recipe.tags") }}
 | 
			
		||||
                {{ $t("tag.tags") }}
 | 
			
		||||
              </v-card-title>
 | 
			
		||||
              <v-divider class="mx-2"></v-divider>
 | 
			
		||||
              <v-card-text>
 | 
			
		||||
@@ -69,7 +69,7 @@
 | 
			
		||||
      </v-row>
 | 
			
		||||
      <div v-if="!medium">
 | 
			
		||||
        <RecipeChips :title="$t('recipe.categories')" :items="categories" />
 | 
			
		||||
        <RecipeChips :title="$t('recipe.tags')" :items="tags" />
 | 
			
		||||
        <RecipeChips :title="$t('tag.tags')" :items="tags" />
 | 
			
		||||
        <Nutrition :value="nutrition" :edit="false" />
 | 
			
		||||
        <Assets :value="assets" :edit="false" :slug="slug" />
 | 
			
		||||
      </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -55,10 +55,10 @@ export default {
 | 
			
		||||
        let formData = new FormData();
 | 
			
		||||
        formData.append(this.fileName, this.file);
 | 
			
		||||
 | 
			
		||||
        await api.utils.uploadFile(this.url, formData);
 | 
			
		||||
 | 
			
		||||
        if(await api.utils.uploadFile(this.url, formData)) {
 | 
			
		||||
          this.$emit(UPLOAD_EVENT);
 | 
			
		||||
        }
 | 
			
		||||
        this.isSelecting = false;
 | 
			
		||||
        this.$emit(UPLOAD_EVENT);
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    onButtonClick() {
 | 
			
		||||
 
 | 
			
		||||
@@ -105,17 +105,15 @@ export default {
 | 
			
		||||
    async createRecipe() {
 | 
			
		||||
      if (this.$refs.urlForm.validate()) {
 | 
			
		||||
        this.processing = true;
 | 
			
		||||
        let response = await api.recipes.createByURL(this.recipeURL);
 | 
			
		||||
        if (response.status !== 201) {
 | 
			
		||||
          this.error = true;
 | 
			
		||||
          this.processing = false;
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.addRecipe = false;
 | 
			
		||||
        const response = await api.recipes.createByURL(this.recipeURL);
 | 
			
		||||
        this.processing = false;
 | 
			
		||||
        this.recipeURL = "";
 | 
			
		||||
        this.$router.push(`/recipe/${response.data}`);
 | 
			
		||||
        if (response) {
 | 
			
		||||
          this.addRecipe = false;
 | 
			
		||||
          this.recipeURL = "";
 | 
			
		||||
          this.$router.push(`/recipe/${response.data}`);
 | 
			
		||||
        } else {
 | 
			
		||||
          this.error = true;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -44,9 +44,9 @@ export default {
 | 
			
		||||
  components: {
 | 
			
		||||
    LoginDialog,
 | 
			
		||||
  },
 | 
			
		||||
  data: function() {
 | 
			
		||||
    return {
 | 
			
		||||
      items: [
 | 
			
		||||
  computed: {
 | 
			
		||||
    items() {
 | 
			
		||||
      return [
 | 
			
		||||
        {
 | 
			
		||||
          icon: "mdi-account",
 | 
			
		||||
          title: "Login",
 | 
			
		||||
@@ -83,10 +83,8 @@ export default {
 | 
			
		||||
          nav: "/admin",
 | 
			
		||||
          restricted: true,
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
    filteredItems() {
 | 
			
		||||
      if (this.loggedIn) {
 | 
			
		||||
        return this.items.filter(x => x.restricted == true);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user