settings and model dialogs

This commit is contained in:
vabene1111
2024-09-21 12:46:54 +02:00
parent ed4592ae0c
commit 55bd417105
39 changed files with 531 additions and 199 deletions

View File

@@ -0,0 +1,44 @@
<template>
<v-btn ref="copyBtn" :color="color" :size="size" :density="density" @click="clickCopy()">
<v-icon icon="$copy"></v-icon>
<v-tooltip v-model="showToolip" :target="btn" location="top">
<v-icon icon="$copy"></v-icon>
Copied!
</v-tooltip>
</v-btn>
</template>
<script setup lang="ts">
import {useClipboard} from "@vueuse/core";
import {ref, useTemplateRef} from "vue";
const {copy} = useClipboard()
const props = defineProps({
copyValue: {type: String, default: ''},
color: {type: String, default: 'success'},
size: {type: String, default: 'default'},
density: {type: String, default: 'default'},
})
const btn = useTemplateRef('copyBtn')
const showToolip = ref(false)
function clickCopy() {
copy(props.copyValue)
showToolip.value = true
setTimeout(() => {
showToolip.value = false
}, 3000)
}
</script>
<style scoped>
</style>

View File

@@ -1,6 +1,8 @@
<template>
<v-dialog max-width="600" activator="parent" v-model="dialog">
<access-token-editor :item="item" @create="createEvent" @save="saveEvent" @delete="deleteEvent" dialog @close="dialog = false" v-if="model == SupportedModels.AccessToken"></access-token-editor>
<invite-link-editor :item="item" @create="createEvent" @save="saveEvent" @delete="deleteEvent" dialog @close="dialog = false" v-if="model == SupportedModels.InviteLink"></invite-link-editor>
<user-space-editor :item="item" @create="createEvent" @save="saveEvent" @delete="deleteEvent" dialog @close="dialog = false" v-if="model == SupportedModels.UserSpace"></user-space-editor>
</v-dialog>
</template>
@@ -10,9 +12,13 @@
import {PropType, ref} from "vue";
import AccessTokenEditor from "@/components/model_editors/AccessTokenEditor.vue";
import {AccessToken, Food} from "@/openapi";
import InviteLinkEditor from "@/components/model_editors/InviteLinkEditor.vue";
import UserSpaceEditor from "@/components/model_editors/UserSpaceEditor.vue";
enum SupportedModels {
AccessToken = 'AccessToken'
AccessToken = 'AccessToken',
InviteLink = 'InviteLink',
UserSpace = 'UserSpace',
}
const emit = defineEmits(['create', 'save', 'delete'])
@@ -21,7 +27,6 @@ const props = defineProps({
model: {
type: String,
required: true,
validator: (val) => ['AccessToken'].includes(val)
},
item: {default: null},
closeAfterCreate: {default: true},

View File

@@ -10,8 +10,8 @@
<v-col cols="10">
<v-text-field label="Token" v-model="editingObj.token" disabled></v-text-field>
</v-col>
<v-col cols="2">
<v-btn color="info" variant="tonal" icon="$copy" @click="copy(editingObj.token)"></v-btn>
<v-col cols="2" >
<btn-copy :copy-value="editingObj.token" class="me-1"></btn-copy>
</v-col>
</v-row>
@@ -20,10 +20,10 @@
</v-form>
</v-card-text>
<v-card-actions>
<v-btn color="save" prepend-icon="$save" @click="saveObject">{{ isUpdate ? $t('Save') : $t('Create') }}</v-btn>
<v-btn color="delete" prepend-icon="$delete" v-if="isUpdate">{{ $t('Delete') }}
<delete-confirm-dialog :object-name="objectName" @delete="deleteObject"></delete-confirm-dialog>
</v-btn>
<v-btn color="save" prepend-icon="$save" @click="saveObject">{{ isUpdate ? $t('Save') : $t('Create') }}</v-btn>
</v-card-actions>
</v-card>
</template>
@@ -38,6 +38,7 @@ import {useI18n} from "vue-i18n";
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
import {DateTime} from "luxon";
import {useClipboard} from "@vueuse/core";
import BtnCopy from "@/components/buttons/BtnCopy.vue";
const {t} = useI18n()
const {copy} = useClipboard()
@@ -108,7 +109,7 @@ async function deleteObject() {
let api = new ApiApi()
api.apiAccessTokenDestroy({id: editingObj.value.id}).then(r => {
editingObj.value = {} as AccessToken
emit('delete')
emit('delete', editingObj.value)
}).catch(err => {
useMessageStore().addError(ErrorMessageType.DELETE_ERROR, err)
})

View File

@@ -0,0 +1,131 @@
<template>
<v-card>
<v-card-title>
{{ $t(OBJ_LOCALIZATION_KEY) }}
<v-btn class="float-right" icon="$close" variant="plain" @click="emit('close')" v-if="dialog"></v-btn>
</v-card-title>
<v-card-text>
<v-form>
<v-text-field :label="$t('Email')" v-model="editingObj.email"></v-text-field>
<v-select :label="$t('Role')" :items="groups" item-value="id" item-title="name" return-object v-model="editingObj.group"></v-select>
<v-date-input :label="$t('Valid Until')" v-model="editingObj.validUntil"></v-date-input>
<v-textarea :label="$t('Note')" v-model="editingObj.internalNote"></v-textarea>
<v-checkbox :label="$t('Reusable')" v-model="editingObj.reusable"></v-checkbox>
</v-form>
</v-card-text>
<v-card-actions>
<v-btn color="delete" prepend-icon="$delete" v-if="isUpdate">{{ $t('Delete') }}
<delete-confirm-dialog :object-name="objectName" @delete="deleteObject"></delete-confirm-dialog>
</v-btn>
<v-btn color="save" prepend-icon="$save" @click="saveObject">{{ isUpdate ? $t('Save') : $t('Create') }}</v-btn>
</v-card-actions>
</v-card>
</template>
<script setup lang="ts">
import {VDateInput} from 'vuetify/labs/VDateInput' //TODO remove once component is out of labs
import {computed, onMounted, ref} from "vue";
import {AccessToken, ApiApi, Group, InviteLink} from "@/openapi";
import DeleteConfirmDialog from "@/components/dialogs/DeleteConfirmDialog.vue";
import {useI18n} from "vue-i18n";
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
import {DateTime} from "luxon";
import {useClipboard} from "@vueuse/core";
const {t} = useI18n()
const {copy} = useClipboard()
const emit = defineEmits(['create', 'save', 'delete', 'close'])
const props = defineProps({
item: {type: {} as InviteLink, required: false},
dialog: {type: Boolean, default: false}
})
const OBJ_LOCALIZATION_KEY = 'Invite_Link'
const editingObj = ref({} as InviteLink)
const loading = ref(false)
// object specific data (for selects/display)
const groups = ref([] as Group[])
/**
* checks if given object has ID property to determine if it needs to be updated or created
*/
const isUpdate = computed(() => {
return editingObj.value.id !== undefined
})
/**
* display name for object in headers/delete dialog/...
*/
const objectName = computed(() => {
return isUpdate ? `${t(OBJ_LOCALIZATION_KEY)} ${editingObj.value.token}` : `${t(OBJ_LOCALIZATION_KEY)} (${t('New')})`
})
onMounted(() => {
const api = new ApiApi()
api.apiGroupList().then(r => {
groups.value = r
if (props.item != null) {
editingObj.value = props.item
} else {
// functions to populate defaults
editingObj.value.validUntil = DateTime.now().plus({month: 1}).toJSDate()
editingObj.value.group = groups.value[0]
}
}).catch(err => {
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err)
})
})
/**
* saves the edited object in the database
*/
async function saveObject() {
let api = new ApiApi()
if (isUpdate.value) {
api.apiInviteLinkUpdate({id: editingObj.value.id, inviteLink: editingObj.value}).then(r => {
editingObj.value = r
emit('save', r)
useMessageStore().addPreparedMessage(PreparedMessage.UPDATE_SUCCESS)
}).catch(err => {
useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err)
})
} else {
api.apiInviteLinkCreate({inviteLink: editingObj.value}).then(r => {
editingObj.value = r
emit('create', r)
useMessageStore().addPreparedMessage(PreparedMessage.CREATE_SUCCESS)
}).catch(err => {
useMessageStore().addError(ErrorMessageType.CREATE_ERROR, err)
})
}
}
/**
* deletes the editing object from the database
*/
async function deleteObject() {
let api = new ApiApi()
api.apiInviteLinkDestroy({id: editingObj.value.id}).then(r => {
editingObj.value = {} as InviteLink
emit('delete')
}).catch(err => {
useMessageStore().addError(ErrorMessageType.DELETE_ERROR, err)
})
}
</script>
<style scoped>
</style>

View File

@@ -0,0 +1,112 @@
<template>
<v-card>
<v-card-title>
{{ $t(OBJ_LOCALIZATION_KEY) }}
<v-btn class="float-right" icon="$close" variant="plain" @click="emit('close')" v-if="dialog"></v-btn>
</v-card-title>
<v-card-text>
<v-form>
<v-select :label="$t('Role')" :items="groups" item-value="id" item-title="name" return-object multiple v-model="editingObj.groups"></v-select>
</v-form>
</v-card-text>
<v-card-actions>
<v-btn color="delete" prepend-icon="$delete" v-if="isUpdate">{{ $t('Delete') }}
<delete-confirm-dialog :object-name="objectName" @delete="deleteObject"></delete-confirm-dialog>
</v-btn>
<v-btn color="save" prepend-icon="$save" @click="saveObject">{{ isUpdate ? $t('Save') : $t('Create') }}</v-btn>
</v-card-actions>
</v-card>
</template>
<script setup lang="ts">
import {computed, onMounted, ref} from "vue";
import {AccessToken, ApiApi, Group, InviteLink, UserSpace} from "@/openapi";
import DeleteConfirmDialog from "@/components/dialogs/DeleteConfirmDialog.vue";
import {useI18n} from "vue-i18n";
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
import {DateTime} from "luxon";
import {useClipboard} from "@vueuse/core";
import {tr} from "vuetify/locale";
const {t} = useI18n()
const {copy} = useClipboard()
const emit = defineEmits(['create', 'save', 'delete', 'close'])
const props = defineProps({
item: {type: {} as UserSpace, required: true},
dialog: {type: Boolean, default: false}
})
const OBJ_LOCALIZATION_KEY = 'Invite_Link'
const editingObj = ref({} as UserSpace)
const loading = ref(false)
// object specific data (for selects/display)
const groups = ref([] as Group[])
/**
* checks if given object has ID property to determine if it needs to be updated or created
*/
const isUpdate = computed(() => {
return editingObj.value.id !== undefined
})
/**
* display name for object in headers/delete dialog/...
*/
const objectName = computed(() => {
return isUpdate ? `${t(OBJ_LOCALIZATION_KEY)} ${editingObj.value.token}` : `${t(OBJ_LOCALIZATION_KEY)} (${t('New')})`
})
onMounted(() => {
const api = new ApiApi()
api.apiGroupList().then(r => {
groups.value = r
}).catch(err => {
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err)
})
if (props.item != null) {
editingObj.value = props.item
} else {
console.error('UserSpaceEditor cannot create items')
}
})
/**
* saves the edited object in the database
*/
async function saveObject() {
let api = new ApiApi()
if (isUpdate.value) {
api.apiUserSpacePartialUpdate({id: editingObj.value.id, patchedUserSpace: editingObj.value}).then(r => {
editingObj.value = r
emit('save', r)
useMessageStore().addPreparedMessage(PreparedMessage.UPDATE_SUCCESS)
}).catch(err => {
useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err)
})
}
}
/**
* deletes the editing object from the database
*/
async function deleteObject() {
let api = new ApiApi()
api.apiUserSpaceDestroy({id: editingObj.value.id}).then(r => {
editingObj.value = {} as UserSpace
emit('delete', editingObj.value)
}).catch(err => {
useMessageStore().addError(ErrorMessageType.DELETE_ERROR, err)
})
}
</script>
<style scoped>
</style>

View File

@@ -1,75 +1,40 @@
<template>
<v-form>
<p class="text-h6">{{ $t('SpaceMembers') }}</p>
<v-divider class="mb-3"></v-divider>
<v-divider></v-divider>
<p class="text-subtitle-2">{{$t('SpaceMemberHelp')}}</p>
<v-data-table :items="spaceUserSpaces" :headers="userTableHeaders" density="compact" :hide-default-footer="spaceUserSpaces.length < 10">
<v-data-table :items="spaceUserSpaces" :headers="userTableHeaders" density="compact" :hide-default-footer="spaceUserSpaces.length < 10" class="mt-3">
<template #item.groups="{item}">
<span v-for="g in item.groups">{{ g.name }}&nbsp;</span>
</template>
<template #item.edit="{item}">
<v-btn icon="$edit" color="edit" size="small" variant="tonal" @click="spaceUserEditDialogUserSpace = Object.assign({}, item); spaceUserEditDialogState = true"></v-btn>
<v-btn color="edit" size="small" v-if="item.user.id != useUserPreferenceStore().activeSpace.createdBy.id">
<v-icon icon="$edit"></v-icon>
<model-editor-dialog model="UserSpace" :item="item" @delete="deleteUserSpace(item)" class="mt-2"></model-editor-dialog>
</v-btn>
<v-chip color="edit" v-else>{{$t('Owner')}}</v-chip>
</template>
</v-data-table>
<v-dialog v-model="spaceUserEditDialogState" max-width="400px">
<v-card>
<v-card-title>{{ $t('User') }}: {{ spaceUserEditDialogUserSpace.user.displayName }}</v-card-title>
<v-card-subtitle>{{ $t('Created') }} {{ DateTime.fromJSDate(spaceUserEditDialogUserSpace.createdAt).toLocaleString(DateTime.DATETIME_MED) }}</v-card-subtitle>
<v-card-text>
<v-form>
<v-select :items="groups" item-value="id" item-title="name" v-model="spaceUserEditDialogUserSpace.groups" multiple return-object></v-select>
</v-form>
<div v-if="spaceUserEditDialogUserSpace.internalNote">
<p>{{ $t('Note') }}</p>
<span>{{ spaceUserEditDialogUserSpace.internalNote }}</span>
</div>
</v-card-text>
<v-card-actions>
<v-btn color="cancel" @click="spaceUserEditDialogState = false">{{ $t('Cancel') }}</v-btn>
<v-btn color="save" prepend-icon="$save" @click="updateUserSpace(spaceUserEditDialogUserSpace)">{{ $t('Save') }}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<p class="text-h6 mt-3">{{ $t('Invites') }}
<v-btn size="small" class="float-right" prepend-icon="$create" color="create" @click="inviteLinkDialogObject = {} as InviteLink;inviteLinkDialogState = true">{{ $t('New') }}</v-btn>
<v-btn size="small" class="float-right" prepend-icon="$create" color="create">
{{ $t('New') }}
<model-editor-dialog model="InviteLink" @delete="deleteInviteLink" @create="item => spaceInviteLinks.push(item)" class="mt-2"></model-editor-dialog>
</v-btn>
</p>
<v-divider class="mb-3"></v-divider>
<v-data-table :items="spaceInviteLinks" :headers="inviteTableHeaders" density="compact" :hide-default-footer="spaceInviteLinks.length < 10">
<template #item.edit="{item}">
<v-btn icon="$copy" color="success" size="small" variant="tonal" @click="copyInviteLink(item)"></v-btn>
<v-btn icon="$edit" color="edit" size="small" variant="tonal" @click="inviteLinkDialogObject = Object.assign({}, item); inviteLinkDialogState = true"></v-btn>
<btn-copy size="small" :copy-value="inviteLinkUrl(item)" class="me-1"></btn-copy>
<v-btn color="edit" size="small">
<v-icon icon="$edit"></v-icon>
<model-editor-dialog model="InviteLink" :item="item" @delete="deleteInviteLink(item)" class="mt-2"></model-editor-dialog>
</v-btn>
</template>
</v-data-table>
<v-dialog v-model="inviteLinkDialogState" max-width="400px">
<v-card>
<v-card-title>{{ $t('Invites') }}</v-card-title>
<v-card-text>
<v-form>
<v-text-field :label="$t('Email')" v-model="inviteLinkDialogObject.email"></v-text-field>
<v-select :label="$t('Role')" :items="groups" item-value="id" item-title="name" return-object v-model="inviteLinkDialogObject.group"></v-select>
<v-date-input :label="$t('Valid Until')" v-model="inviteLinkDialogObject.validUntil"></v-date-input>
<v-textarea :label="$t('Note')" v-model="inviteLinkDialogObject.internalNote"></v-textarea>
<v-checkbox :label="$t('Reusable')" v-model="inviteLinkDialogObject.reusable"></v-checkbox>
</v-form>
</v-card-text>
<v-card-actions>
<v-btn color="cancel" @click="inviteLinkDialogState = false">{{ $t('Cancel') }}</v-btn>
<v-btn color="save" prepend-icon="$save" @click="saveInviteLink(inviteLinkDialogObject)" :loading="inviteLinkDialogLoading">
<span v-if="inviteLinkDialogObject.id == undefined">{{ $t('Create') }}</span>
<span v-if="inviteLinkDialogObject.id != undefined">{{ $t('Update') }}</span>
</v-btn>
<v-btn color="delete" prepend-icon="$delete" @click="deleteInviteLink(inviteLinkDialogObject)" v-if="inviteLinkDialogObject.id != undefined">{{ $t('Delete') }}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-form>
</template>
@@ -82,21 +47,15 @@ import {ApiApi, Group, InviteLink, UserSpace} from "@/openapi";
import {ErrorMessageType, PreparedMessage, useMessageStore} from "@/stores/MessageStore";
import {useI18n} from "vue-i18n";
import {DateTime} from "luxon";
import {VDateInput} from 'vuetify/labs/VDateInput' //TODO remove once component is out of labs
import {useClipboard} from "@vueuse/core"; //TODO remove once component is out of labs
import {useClipboard} from "@vueuse/core";
import ModelEditorDialog from "@/components/dialogs/ModelEditorDialog.vue";
import BtnCopy from "@/components/buttons/BtnCopy.vue";
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
const {t} = useI18n()
const spaceUserSpaces = ref([] as UserSpace[])
const spaceInviteLinks = ref([] as InviteLink[])
const groups = ref([] as Group[])
const spaceUserEditDialogState = ref(false)
const spaceUserEditDialogUserSpace = ref({} as UserSpace)
const inviteLinkDialogState = ref(false)
const inviteLinkDialogObject = ref({} as InviteLink)
const inviteLinkDialogLoading = ref(false)
const userTableHeaders = [
{title: t('Username'), key: 'user.username'},
@@ -114,12 +73,6 @@ const inviteTableHeaders = [
onMounted(() => {
const api = new ApiApi()
api.apiGroupList().then(r => {
groups.value = r
}).catch(err => {
useMessageStore().addError(ErrorMessageType.FETCH_ERROR, err)
})
api.apiUserSpaceList().then(r => {
spaceUserSpaces.value = r.results
}).catch(err => {
@@ -134,75 +87,27 @@ onMounted(() => {
})
/**
* update user space in DB and list on client
* @param userSpace UserSpace object to update
* delete userspace from client list (database handled by editor)
* @param userSpace UserSpace object that was deleted
*/
function updateUserSpace(userSpace: UserSpace) {
const api = new ApiApi()
api.apiUserSpacePartialUpdate({id: userSpace.id!, patchedUserSpace: userSpace}).then(r => {
spaceUserSpaces.value.splice(spaceUserSpaces.value.indexOf(userSpace), 1, r)
useMessageStore().addPreparedMessage(PreparedMessage.UPDATE_SUCCESS)
}).catch(err => {
useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err)
})
function deleteUserSpace(userSpace: UserSpace) {
spaceUserSpaces.value.splice(spaceUserSpaces.value.indexOf(userSpace) - 1, 1)
}
/**
* create or update the invite link, refresh invite link list on client
* @param inviteLink InviteLink object to update
*/
function saveInviteLink(inviteLink: InviteLink) {
const api = new ApiApi()
inviteLinkDialogLoading.value = true
if (inviteLink.id == undefined) {
api.apiInviteLinkCreate({inviteLink: inviteLink}).then(r => {
inviteLinkDialogState.value = false
spaceInviteLinks.value.push(r)
useMessageStore().addPreparedMessage(PreparedMessage.CREATE_SUCCESS)
}).catch(err => {
useMessageStore().addError(ErrorMessageType.CREATE_ERROR, err)
}).finally(() => {
inviteLinkDialogLoading.value = false
})
} else {
api.apiInviteLinkUpdate({inviteLink: inviteLink, id: inviteLink.id}).then(r => {
inviteLinkDialogState.value = false
spaceInviteLinks.value.splice(spaceInviteLinks.value.indexOf(inviteLink), 1, r)
useMessageStore().addPreparedMessage(PreparedMessage.UPDATE_SUCCESS)
}).catch(err => {
useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err)
}).finally(() => {
inviteLinkDialogLoading.value = false
})
}
}
/**
* delete invite link from database and client
* @param inviteLink InviteLink object to delete
* delete invite link from client list (database handled by editor)
* @param inviteLink InviteLink object that was deleted
*/
function deleteInviteLink(inviteLink: InviteLink) {
const api = new ApiApi()
api.apiInviteLinkDestroy({id: inviteLink.id}).then(r => {
inviteLinkDialogState.value = false
spaceInviteLinks.value.splice(spaceInviteLinks.value.indexOf(inviteLink) - 1, 1)
useMessageStore().addPreparedMessage(PreparedMessage.DELETE_SUCCESS)
}).catch(err => {
useMessageStore().addError(ErrorMessageType.UPDATE_ERROR, err)
})
spaceInviteLinks.value.splice(spaceInviteLinks.value.indexOf(inviteLink) - 1, 1)
}
/**
* copy invite link with url to clipboard
* @param inviteLink InviteLink object to copy
* returns url for invite link
* @param inviteLink InviteLink object to create url for
*/
function copyInviteLink(inviteLink: InviteLink) {
const {copy} = useClipboard()
copy(`${location.protocol}//${location.host}/invite/${inviteLink.uuid}`)
function inviteLinkUrl(inviteLink: InviteLink) {
return `${location.protocol}//${location.host}/invite/${inviteLink.uuid}`
}
</script>

View File

@@ -175,6 +175,7 @@
"OnHand_help": "",
"Open": "",
"Options": "",
"Owner": "",
"Page": "",
"Parameter": "",
"Parent": "",
@@ -237,6 +238,7 @@
"Single": "",
"Size": "",
"Sort_by_new": "",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Starting_Day": "",

View File

@@ -168,6 +168,7 @@
"OnHand_help": "Храната е в инвентара и няма да бъде добавена автоматично към списък за пазаруване. Състоянието на ръка се споделя с пазаруващите потребители.",
"Open": "Отвори",
"Options": "Настроики",
"Owner": "",
"Page": "Страница",
"Parameter": "Параметър",
"Parent": "Родител",
@@ -230,6 +231,7 @@
"Single": "Единичен",
"Size": "Размер",
"Sort_by_new": "Сортиране по ново",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Starting_Day": "Начален ден от седмицата",

View File

@@ -237,6 +237,7 @@
"Options": "",
"OrderInformation": "",
"Original_Text": "",
"Owner": "",
"Page": "",
"Parameter": "",
"Parent": "",
@@ -315,6 +316,7 @@
"Size": "",
"Social_Authentication": "",
"Sort_by_new": "Ordenar a partir del més nou",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Space_Cosmetic_Settings": "",

View File

@@ -235,6 +235,7 @@
"Options": "Možnosti",
"OrderInformation": "Položky jsou seřazeny podle čísel od malých po velké.",
"Original_Text": "Původní text",
"Owner": "",
"Page": "Stránka",
"Parameter": "Parametr",
"Parent": "Nadřazená",
@@ -311,6 +312,7 @@
"Size": "Velikost",
"Social_Authentication": "Přihlašování pomocí účtů sociálních sítí",
"Sort_by_new": "Seřadit od nejnovějšího",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Space_Cosmetic_Settings": "Některá kosmetická nastavení mohou měnit správci prostoru a budou mít přednost před nastavením klienta pro daný prostor.",

View File

@@ -220,6 +220,7 @@
"Options": "Indstillinger",
"OrderInformation": "Objekter er rangeret fra små til store tal.",
"Original_Text": "Original tekst",
"Owner": "",
"Page": "Side",
"Parameter": "Parameter",
"Parent": "Forælder",
@@ -290,6 +291,7 @@
"Size": "Størrelse",
"Social_Authentication": "Social authenticering",
"Sort_by_new": "Sorter efter nylige",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Split_All_Steps": "Opdel rækker i separate trin.",

View File

@@ -239,6 +239,7 @@
"Options": "Optionen",
"OrderInformation": "Die Objekte sind von kleinen zu großen Zahlen geordnet.",
"Original_Text": "Originaler Text",
"Owner": "Besitzer",
"Page": "Seite",
"Parameter": "Parameter",
"Parent": "Eltern",
@@ -317,6 +318,7 @@
"Size": "Größe",
"Social_Authentication": "Authentifizierung über ein soziales Netzwerk",
"Sort_by_new": "Nach Neueste sortieren",
"SpaceMemberHelp": "Füge Benutzer hinzu indem du Einladungen erstellst und Sie an die gewünschte Person sendest.",
"SpaceMembers": "Space Mitglieder",
"SpaceSettings": "Space Einstellungen",
"Space_Cosmetic_Settings": "Einige optische Einstellungen können von Administratoren des Bereichs geändert werden und setzen die Client-Einstellungen für diesen Bereich außer Kraft.",

View File

@@ -212,6 +212,7 @@
"Open_Data_Slug": "Αναγνωριστικό (Slug) Open Data",
"Options": "Επιλογές",
"Original_Text": "Αρχικό κείμενο",
"Owner": "",
"Page": "Σελίδα",
"Parameter": "Παράμετρος",
"Parent": "Γονέας",
@@ -282,6 +283,7 @@
"Size": "Μέγεθος",
"Social_Authentication": "Ταυτοποίηση μέσω κοινωνικών δικτύων",
"Sort_by_new": "Ταξινόμηση κατά νέο",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Split_All_Steps": "Διαχωρισμός όλων των γραμμών σε χωριστά βήματα.",

View File

@@ -167,6 +167,7 @@
"Instruction_Replace": "Instruction Replace",
"Instructions": "Instructions",
"Internal": "Internal",
"Invite_Link": "Invite Link",
"Invites": "Invites",
"Key_Ctrl": "Ctrl",
"Key_Shift": "Shift",
@@ -238,6 +239,7 @@
"Options": "Options",
"OrderInformation": "Objects are ordered from small to large numbers.",
"Original_Text": "Original Text",
"Owner": "Owner",
"Page": "Page",
"Parameter": "Parameter",
"Parent": "Parent",
@@ -285,6 +287,7 @@
"Remove_nutrition_recipe": "Delete nutrition from recipe",
"Reset": "Reset",
"Reset_Search": "Reset Search",
"Role": "Role",
"Root": "Root",
"Save": "Save",
"Save_and_View": "Save & View",
@@ -317,6 +320,7 @@
"Size": "Size",
"Social_Authentication": "Social Authentication",
"Sort_by_new": "Sort by new",
"SpaceMemberHelp": "Add users to your space by creating an Invite Link and sending it to the person you want to add.",
"SpaceMembers": "Space Members",
"SpaceSettings": "Space Settings",
"Space_Cosmetic_Settings": "Some cosmetic settings can be changed by space administrators and will override client settings for that space.",

View File

@@ -238,6 +238,7 @@
"Options": "Opciones",
"OrderInformation": "Los objetos están ordenados en orden numérico creciente.",
"Original_Text": "Texto original",
"Owner": "",
"Page": "Página",
"Parameter": "Parametro",
"Parent": "Padre",
@@ -314,6 +315,7 @@
"Size": "Tamaño",
"Social_Authentication": "Autenticación Social",
"Sort_by_new": "Ordenar por novedades",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Space_Cosmetic_Settings": "Algunos ajustes de apariencia pueden ser cambiados por los administradores del espacio y anularán los ajustes del cliente para ese espacio.",

View File

@@ -113,6 +113,7 @@
"Nutrition": "Ravitsemus",
"Ok": "Avaa",
"Open": "Avaa",
"Owner": "",
"Parameter": "Parametri",
"Parent": "Yläluokka",
"Period": "Jakso",
@@ -158,6 +159,7 @@
"Show_as_header": "Näytä otsikkona",
"Size": "Koko",
"Sort_by_new": "Lajittele uusien mukaan",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Starting_Day": "Viikon aloituspäivä",

View File

@@ -237,6 +237,7 @@
"Options": "Options",
"OrderInformation": "Les objects sont classés du plus petit au plus grand.",
"Original_Text": "Texte dorigine",
"Owner": "",
"Page": "Page",
"Parameter": "Paramètre",
"Parent": "Parent",
@@ -315,6 +316,7 @@
"Size": "Taille",
"Social_Authentication": "Authentification Sociale",
"Sort_by_new": "Trier par nouveautés",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Space_Cosmetic_Settings": "Certains paramètres cosmétiques peuvent être modifiés par un administrateur de l'espace et seront prioritaires sur les paramètres des utilisateurs pour cet espace.",

View File

@@ -238,6 +238,7 @@
"Options": "אפשרויות",
"OrderInformation": "המוצרים מוצגים מהמספר הקטן לגדול.",
"Original_Text": "כיתוב מקורי",
"Owner": "",
"Page": "עמוד",
"Parameter": "פרמטר",
"Parent": "הורה",
@@ -316,6 +317,7 @@
"Size": "גודל",
"Social_Authentication": "אימות חברתי",
"Sort_by_new": "סדר ע\"י חדש",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Space_Cosmetic_Settings": "חלק מהגדרות הקוסמטיות יכולות להיות מעודכנות על ידי מנהל המרחב וידרסו את הגדרות הקליינט עבור מרחב זה.",

View File

@@ -214,6 +214,7 @@
"Options": "Opciók",
"OrderInformation": "Az objektumok a kis számoktól a nagy számok felé rendezettek.",
"Original_Text": "Eredeti szöveg",
"Owner": "",
"Page": "Oldal",
"Parameter": "Paraméter",
"Parent": "Szülő",
@@ -283,6 +284,7 @@
"Single": "Egyetlen",
"Size": "Méret",
"Sort_by_new": "Rendezés legújabbak szerint",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Split_All_Steps": "Ossza fel az összes sort különálló lépésekbe.",

View File

@@ -68,6 +68,7 @@
"Nutrition": "",
"Ok": "",
"Open": "",
"Owner": "",
"Parent": "Ծնող",
"Plural": "",
"Preferences": "",
@@ -99,6 +100,7 @@
"Show_as_header": "Ցույց տալ որպես խորագիր",
"Size": "",
"Sort_by_new": "Տեսակավորել ըստ նորերի",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Step": "",

View File

@@ -194,6 +194,7 @@
"OnHand_help": "",
"Open": "Membuka",
"Options": "",
"Owner": "",
"Page": "",
"Parameter": "Parameter",
"Parent": "Induk",
@@ -260,6 +261,7 @@
"Size": "Ukuran",
"Social_Authentication": "",
"Sort_by_new": "Urutkan berdasarkan baru",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Starting_Day": "",

View File

@@ -237,6 +237,7 @@
"Options": "",
"OrderInformation": "",
"Original_Text": "",
"Owner": "",
"Page": "",
"Parameter": "",
"Parent": "",
@@ -314,6 +315,7 @@
"Size": "",
"Social_Authentication": "",
"Sort_by_new": "",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Space_Cosmetic_Settings": "",

View File

@@ -200,6 +200,7 @@
"Open": "Apri",
"Options": "Opzioni",
"Original_Text": "Testo originale",
"Owner": "",
"Page": "Pagina",
"Parameter": "Parametro",
"Parent": "Primario",
@@ -268,6 +269,7 @@
"Size": "Dimensione",
"Social_Authentication": "Autenticazione social",
"Sort_by_new": "Prima i nuovi",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Split_All_Steps": "Divide tutte le righe in step separati.",

View File

@@ -218,6 +218,7 @@
"Options": "",
"OrderInformation": "",
"Original_Text": "",
"Owner": "",
"Page": "",
"Parameter": "",
"Parent": "",
@@ -288,6 +289,7 @@
"Size": "",
"Social_Authentication": "",
"Sort_by_new": "Rūšiuoti pagal naujumą",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Split_All_Steps": "",

View File

@@ -210,6 +210,7 @@
"Open_Data_Slug": "Åpne data Slug",
"Options": "",
"Original_Text": "Orginal tekst",
"Owner": "",
"Page": "",
"Parameter": "Parameter",
"Parent": "Forelder",
@@ -280,6 +281,7 @@
"Size": "Størrelse",
"Social_Authentication": "",
"Sort_by_new": "Sorter etter nyest",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Split_All_Steps": "",

View File

@@ -214,6 +214,7 @@
"Open_Data_Slug": "Open Data Slug",
"Options": "Opties",
"Original_Text": "Originele tekst",
"Owner": "",
"Page": "Pagina",
"Parameter": "Parameter",
"Parent": "Ouder",
@@ -284,6 +285,7 @@
"Size": "Grootte",
"Social_Authentication": "Authenticeren met sociale media-account",
"Sort_by_new": "Sorteer op nieuw",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Split_All_Steps": "Splits alle rijen in aparte stappen.",

View File

@@ -239,6 +239,7 @@
"Options": "Opcje",
"OrderInformation": "Obiekty są uporządkowane od małych do dużych liczb.",
"Original_Text": "Tekst oryginalny",
"Owner": "",
"Page": "Strona",
"Parameter": "Parametr",
"Parent": "Nadrzędny",
@@ -317,6 +318,7 @@
"Size": "Rozmiar",
"Social_Authentication": "Uwierzytelnianie społecznościowe",
"Sort_by_new": "Sortuj według nowych",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Space_Cosmetic_Settings": "Administratorzy przestrzeni mogą zmienić niektóre ustawienia kosmetyczne, które zastąpią ustawienia klienta dla tej przestrzeni.",

View File

@@ -163,6 +163,7 @@
"OnHand_help": "",
"Open": "Abrir",
"Original_Text": "Texto original",
"Owner": "",
"Page": "Página",
"Parameter": "Parâmetro",
"Parent": "Parente",
@@ -224,6 +225,7 @@
"Show_as_header": "Mostrar como cabeçalho",
"Size": "Tamanho",
"Sort_by_new": "Ordenar por mais recente",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Starting_Day": "Dia de início da semana",

View File

@@ -227,6 +227,7 @@
"Open_Data_Slug": "Identificador de Dados Abertos",
"Options": "Opções",
"Original_Text": "Texto Original",
"Owner": "",
"Page": "Página",
"Parameter": "Parâmetro",
"Parent": "Pai",
@@ -301,6 +302,7 @@
"Single": "Simples",
"Size": "Tamanho",
"Sort_by_new": "Ordenar por novos",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"StartDate": "Data Início",

View File

@@ -204,6 +204,7 @@
"Open": "Deschide",
"Options": "Opțiuni",
"Original_Text": "Text original",
"Owner": "",
"Page": "Pagină",
"Parameter": "Parametru",
"Parent": "Părinte",
@@ -272,6 +273,7 @@
"Size": "Marime",
"Social_Authentication": "Autentificare socială",
"Sort_by_new": "Sortare după nou",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Split_All_Steps": "Împărțiți toate rândurile în pași separați.",

View File

@@ -153,6 +153,7 @@
"OnHand": "В Наличии",
"Open": "Открыть",
"Options": "Опции",
"Owner": "",
"Page": "Страница",
"Parameter": "Параметр",
"Parent": "Родитель",
@@ -209,6 +210,7 @@
"Show_as_header": "Показывать как заголовок",
"Size": "Размер",
"Sort_by_new": "Сортировка по новизне",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Starting_Day": "Начальный день недели",

View File

@@ -147,6 +147,7 @@
"Open": "Odpri",
"Open_Data_Import": "Open Data Uvoz",
"Open_Data_Slug": "Open Data Identifikator",
"Owner": "",
"Parameter": "Parameter",
"Parent": "Starš",
"Period": "Obdobje",
@@ -199,6 +200,7 @@
"Show_as_header": "Prikaži kot glavo",
"Size": "Velikost",
"Sort_by_new": "Razvrsti po novih",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Starting_Day": "Začetni dan v tednu",

View File

@@ -239,6 +239,7 @@
"Options": "Val",
"OrderInformation": "Objekt är sorterade från små till stora siffror.",
"Original_Text": "Original Text",
"Owner": "",
"Page": "Sida",
"Parameter": "Parameter",
"Parent": "Förälder",
@@ -317,6 +318,7 @@
"Size": "Storlek",
"Social_Authentication": "Social autentisering",
"Sort_by_new": "Sortera efter ny",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Space_Cosmetic_Settings": "Vissa kosmetiska inställningar kan ändras av hushålls-administratörer och skriver över klientinställningar för det hushållet.",

View File

@@ -238,6 +238,7 @@
"Options": "Seçenekler",
"OrderInformation": "Nesneler küçükten büyüğe doğru sıralanır.",
"Original_Text": "Orijinal Metin",
"Owner": "",
"Page": "Sayfa",
"Parameter": "Parametre",
"Parent": "Üst Öğe",
@@ -316,6 +317,7 @@
"Size": "Boyut",
"Social_Authentication": "Sosyal Kimlik Doğrulama",
"Sort_by_new": "Yeniye göre sırala",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Space_Cosmetic_Settings": "Bazı kozmetik ayarlar alan yöneticileri tarafından değiştirilebilir ve o alanın istemci ayarlarını geçersiz kılar.",

View File

@@ -181,6 +181,7 @@
"Open": "Відкрити",
"Options": "",
"Original_Text": "Оригінальний текст",
"Owner": "",
"Page": "",
"Parameter": "Параметр",
"Parent": "Батько",
@@ -245,6 +246,7 @@
"Single": "",
"Size": "Розмір",
"Sort_by_new": "",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Starting_Day": "Початковий день тижня",

View File

@@ -233,6 +233,7 @@
"Options": "选项",
"OrderInformation": "对象按照从小到大的顺序排列。",
"Original_Text": "原文",
"Owner": "",
"Page": "页",
"Parameter": "范围",
"Parent": "父级",
@@ -310,6 +311,7 @@
"Size": "大小",
"Social_Authentication": "社交认证",
"Sort_by_new": "按新旧排序",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Space_Cosmetic_Settings": "空间管理员可以更改某些装饰设置,并将覆盖该空间的客户端设置。",

View File

@@ -44,6 +44,7 @@
"Nutrition": "",
"Ok": "",
"Open": "",
"Owner": "",
"Plural": "",
"Preferences": "",
"Preparation": "",
@@ -69,6 +70,7 @@
"Show_as_header": "顯示為標題",
"Size": "",
"Sort_by_new": "按最新排序",
"SpaceMemberHelp": "",
"SpaceMembers": "",
"SpaceSettings": "",
"Step": "",