Add singular/plural collection name translations (#5302)

* Add singular/plural options to collection translations

* Use singular/plural item names in related values

* Use singular / plural names on item detail

* Use singular/plural for drawer item

* Fix translation
This commit is contained in:
Rijk van Zanten
2021-04-27 16:22:52 -04:00
committed by GitHub
parent 451cdac8ef
commit 84f4a1da01
7 changed files with 72 additions and 13 deletions

View File

@@ -64,7 +64,23 @@ fields:
interface: system-language
width: half
- field: translation
name: translation
name: Collection Name
type: string
meta:
interface: text-input
width: half
options:
placeholder: Enter a translation...
- field: singular
name: Singular Unit
type: string
meta:
interface: text-input
width: half
options:
placeholder: Enter a translation...
- field: plural
name: Plural Unit
type: string
meta:
interface: text-input

View File

@@ -7,8 +7,11 @@
>
<template #activator="{ toggle }">
<span @click.stop="toggle" class="toggle" :class="{ subdued: value.length === 0 }">
<span class="label" v-if="value.length < 100">{{ $tc('item_count', value.length) }}</span>
<span class="label" v-else>{{ $tc('item_count', value.length, { count: '100+' }) }}</span>
<span class="label">
{{ value.length }}
<template v-if="value.length >= 100">+</template>
{{ unit }}
</span>
</span>
</template>
@@ -31,6 +34,7 @@ import { defineComponent, computed, PropType, Ref } from '@vue/composition-api';
import getRelatedCollection from '@/utils/get-related-collection';
import useCollection from '@/composables/use-collection';
import ValueNull from '@/views/private/components/value-null';
import { i18n } from '@/lang';
export default defineComponent({
components: { ValueNull },
@@ -71,7 +75,25 @@ export default defineComponent({
return props.template || `{{ ${primaryKeyField.value!.field} }}`;
});
return { relatedCollection, primaryKeyField, getLinkForItem, _template };
const unit = computed(() => {
if (Array.isArray(props.value)) {
if (props.value.length === 1) {
if (i18n.te(`collection_names_singular.${relatedCollection.value}`)) {
return i18n.t(`collection_names_singular.${relatedCollection.value}`);
} else {
return i18n.t('item');
}
} else {
if (i18n.te(`collection_names_plural.${relatedCollection.value}`)) {
return i18n.t(`collection_names_plural.${relatedCollection.value}`);
} else {
return i18n.t('items');
}
}
}
});
return { relatedCollection, primaryKeyField, getLinkForItem, _template, unit };
function getLinkForItem(item: any) {
if (!relatedCollection.value || !primaryKeyField.value) return null;

View File

@@ -483,6 +483,8 @@ operators:
has: Contains some of these keys
loading: Loading...
drop_to_upload: Drop to Upload
item: Item
items: Items
upload_file: Upload File
upload_file_indeterminate: Uploading File...
upload_file_success: File Uploaded
@@ -602,6 +604,8 @@ adding_user: Adding User
unknown_user: Unknown User
creating_in: 'Creating Item in {collection}'
editing_in: 'Editing Item in {collection}'
creating_unit: 'Creating {unit}'
editing_unit: 'Editing {unit}'
editing_in_batch: 'Batch Editing {count} Items'
no_options_available: No options available
settings_data_model: Data Model
@@ -690,7 +694,7 @@ fields:
display_template: Display Template
hidden: Hidden
singleton: Singleton
translations: Collection Name Translations
translations: Collection Naming Translations
archive_app_filter: Archive App Filter
archive_value: Archive Value
unarchive_value: Unarchive Value

View File

@@ -299,6 +299,12 @@ export default defineComponent({
const leaveTo = ref<string | null>(null);
const title = computed(() => {
if (i18n.te(`collection_names_singular.${props.collection}`)) {
return isNew.value
? i18n.t('creating_unit', { unit: i18n.t(`collection_names_singular.${props.collection}`) })
: i18n.t('editing_unit', { unit: i18n.t(`collection_names_singular.${props.collection}`) });
}
return isNew.value
? i18n.t('creating_in', { collection: collectionInfo.value?.name })
: i18n.t('editing_in', { collection: collectionInfo.value?.name });

View File

@@ -37,12 +37,18 @@ export const useCollectionsStore = createStore({
if (collection.meta && notEmpty(collection.meta.translations)) {
for (let i = 0; i < collection.meta.translations.length; i++) {
const { language, translation } = collection.meta.translations[i];
const { language, translation, singular, plural } = collection.meta.translations[i];
i18n.mergeLocaleMessage(language, {
collection_names: {
[collection.collection]: translation,
},
collection_names_singular: {
[collection.collection]: singular,
},
collection_names_plural: {
[collection.collection]: plural,
},
});
}
}

View File

@@ -3,6 +3,8 @@ import VueI18n from 'vue-i18n';
type Translations = {
language: string;
translation: string;
singular: string;
plural: string;
};
export interface CollectionRaw {

View File

@@ -122,15 +122,18 @@ export default defineComponent({
const { info: collectionInfo } = useCollection(collection);
const title = computed(() => {
if (props.primaryKey === '+') {
return i18n.t('creating_in', {
collection: junctionRelatedCollectionInfo?.value?.name || collectionInfo.value?.name,
});
const collection = junctionRelatedCollectionInfo?.value || collectionInfo.value!;
const isNew = props.primaryKey === '+';
if (i18n.te(`collection_names_singular.${collection.collection}`)) {
return isNew
? i18n.t('creating_unit', { unit: i18n.t(`collection_names_singular.${collection.collection}`) })
: i18n.t('editing_unit', { unit: i18n.t(`collection_names_singular.${collection.collection}`) });
}
return i18n.t('editing_in', {
collection: junctionRelatedCollectionInfo?.value?.name || collectionInfo.value?.name,
});
return isNew
? i18n.t('creating_in', { collection: collection.name })
: i18n.t('editing_in', { collection: collection.name });
});
const showDivider = computed(() => {