Browse Source

Merge branch 'develop' into feat/gui-v2-formula-options

pull/2998/head
Wing-Kam Wong 2 years ago
parent
commit
76bbb45a89
  1. 1
      packages/nc-gui-v2/components/smartsheet-column/EditOrAdd.vue
  2. 80
      packages/nc-gui-v2/components/smartsheet-column/LookupOptions.vue
  3. 5
      packages/nc-gui-v2/components/smartsheet/VirtualCell.vue
  4. 2
      packages/nc-gui-v2/components/tabs/auth/user-management/UsersModal.vue
  5. 4
      packages/nc-gui-v2/components/virtual-cell/BelongsTo.vue
  6. 4
      packages/nc-gui-v2/components/virtual-cell/Formula.vue
  7. 4
      packages/nc-gui-v2/components/virtual-cell/HasMany.vue
  8. 210
      packages/nc-gui-v2/components/virtual-cell/Lookup.vue
  9. 4
      packages/nc-gui-v2/components/virtual-cell/ManyToMany.vue
  10. 4
      packages/nc-gui-v2/components/virtual-cell/Rollup.vue
  11. 3
      packages/nc-gui/components/utils/Language.vue
  12. 522
      packages/nc-gui/lang/ar.json
  13. 3
      packages/nc-gui/plugins/i18n.js
  14. 1
      scripts/cypress/integration/common/6d_language_validation.js

1
packages/nc-gui-v2/components/smartsheet-column/EditOrAdd.vue

@ -92,6 +92,7 @@ watchEffect(() => {
<SmartsheetColumnDurationOptions v-if="formState.uidt === UITypes.Duration" /> <SmartsheetColumnDurationOptions v-if="formState.uidt === UITypes.Duration" />
<SmartsheetColumnRatingOptions v-if="formState.uidt === UITypes.Rating" /> <SmartsheetColumnRatingOptions v-if="formState.uidt === UITypes.Rating" />
<SmartsheetColumnCheckboxOptions v-if="formState.uidt === UITypes.Checkbox" /> <SmartsheetColumnCheckboxOptions v-if="formState.uidt === UITypes.Checkbox" />
<SmartsheetColumnLookupOptions v-if="formState.uidt === UITypes.Lookup" />
<div> <div>
<div <div

80
packages/nc-gui-v2/components/smartsheet-column/LookupOptions.vue

@ -0,0 +1,80 @@
<script setup lang="ts">
import { UITypes, isSystemColumn } from 'nocodb-sdk'
import { useColumnCreateStoreOrThrow } from '#imports'
import { MetaInj } from '~/context'
const { formState, validateInfos, onDataTypeChange, setAdditionalValidations } = $(useColumnCreateStoreOrThrow())
const { tables } = $(useProject())
const meta = $(inject(MetaInj))
const { metas } = $(useMetas())
setAdditionalValidations({
fk_relation_column_id: [{ required: true, message: 'Required' }],
fk_lookup_column_id: [{ required: true, message: 'Required' }],
})
if (!formState.fk_relation_column_id) formState.fk_relation_column_id = null
if (!formState.fk_lookup_column_id) formState.fk_lookup_column_id = null
const relationNames = {
mm: 'Many To Many',
hm: 'Has Many',
bt: 'Belongs To',
}
const refTables = $computed(() => {
if (!tables || !tables.length) {
return []
}
return meta.columns
.filter((c) => c.uidt === UITypes.LinkToAnotherRecord && c.colOptions.type !== 'bt' && !c.system)
.map((c) => ({
col: c.colOptions,
column: c,
...tables.find((t) => t.id === c.colOptions.fk_related_model_id),
}))
.filter((table) => table.col.fk_related_model_id === table.id && !table.mm)
})
const columns = $computed(() => {
const selectedTable = refTables.find((t) => t.column.id === formState.fk_relation_column_id)
if (!selectedTable?.id) {
return []
}
return metas[selectedTable.id].columns.filter((c) => !isSystemColumn(c))
})
</script>
<template>
<div class="p-4 w-full flex flex-col border-2 mb-2 mt-4">
<div class="w-full flex flex-row space-x-2">
<a-form-item class="flex w-1/2 pb-2" :label="$t('labels.childTable')" v-bind="validateInfos.fk_relation_column_id">
<a-select v-model:value="formState.fk_relation_column_id" size="small" @change="onDataTypeChange">
<a-select-option v-for="(table, index) in refTables" :key="index" :value="table.col.fk_column_id">
<div class="flex flex-row items-center space-x-0.5 h-full">
<div class="font-weight-bold text-[0.7rem]">{{ table.column.title }}</div>
<div class="text-[0.5rem]">({{ relationNames[table.col.type] }} {{ table.title || table.table_name }})</div>
</div>
</a-select-option>
</a-select>
</a-form-item>
<a-form-item class="flex w-1/2" :label="$t('labels.childColumn')" v-bind="validateInfos.fk_lookup_column_id">
<a-select
v-model:value="formState.fk_lookup_column_id"
name="fk_lookup_column_id"
size="small"
@change="onDataTypeChange"
>
<a-select-option v-for="(column, index) in columns" :key="index" :value="column.id">
{{ column.title }}
</a-select-option>
</a-select>
</a-form-item>
</div>
</div>
</template>
<style scoped></style>

5
packages/nc-gui-v2/components/smartsheet/VirtualCell.vue

@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ColumnType } from 'nocodb-sdk' import type { ColumnType } from 'nocodb-sdk'
import { provide, useVirtualCell } from '#imports' import { provide, useVirtualCell } from '#imports'
import { ColumnInj } from '~/context' import { ColumnInj, ValueInj } from '~/context'
import { NavigateDir } from '~/lib' import { NavigateDir } from '~/lib'
interface Props { interface Props {
@ -14,7 +14,7 @@ const { column, modelValue: value } = defineProps<Props>()
const emit = defineEmits(['update:modelValue', 'navigate']) const emit = defineEmits(['update:modelValue', 'navigate'])
provide(ColumnInj, column) provide(ColumnInj, column)
provide('value', value) provide(ValueInj, value)
const { isLookup, isBt, isRollup, isMm, isHm, isFormula, isCount } = useVirtualCell(column) const { isLookup, isBt, isRollup, isMm, isHm, isFormula, isCount } = useVirtualCell(column)
</script> </script>
@ -31,6 +31,7 @@ const { isLookup, isBt, isRollup, isMm, isHm, isFormula, isCount } = useVirtualC
<VirtualCellRollup v-else-if="isRollup" /> <VirtualCellRollup v-else-if="isRollup" />
<VirtualCellFormula v-else-if="isFormula" /> <VirtualCellFormula v-else-if="isFormula" />
<VirtualCellCount v-else-if="isCount" /> <VirtualCellCount v-else-if="isCount" />
<VirtualCellLookup v-else-if="isLookup" />
</div> </div>
</template> </template>

2
packages/nc-gui-v2/components/tabs/auth/user-management/UsersModal.vue

@ -41,7 +41,7 @@ const validators = computed(() => {
emails: [ emails: [
{ {
validator: (rule: any, value: string, callback: (errMsg?: string) => void) => { validator: (rule: any, value: string, callback: (errMsg?: string) => void) => {
if (value.length === 0) { if (!value || value.length === 0) {
callback('Email is required') callback('Email is required')
return return
} }

4
packages/nc-gui-v2/components/virtual-cell/BelongsTo.vue

@ -1,11 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ColumnType } from 'nocodb-sdk' import type { ColumnType } from 'nocodb-sdk'
import ItemChip from './components/ItemChip.vue' import ItemChip from './components/ItemChip.vue'
import { ColumnInj } from '~/context' import { ColumnInj, ValueInj } from '~/context'
import { useBelongsTo } from '#imports' import { useBelongsTo } from '#imports'
const column = inject(ColumnInj) const column = inject(ColumnInj)
const value = inject('value') const value = inject(ValueInj)
const active = false const active = false
const localState = null const localState = null

4
packages/nc-gui-v2/components/virtual-cell/Formula.vue

@ -1,12 +1,12 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, useProject } from '#imports' import { computed, useProject } from '#imports'
import { ColumnInj } from '~/context' import { ColumnInj, ValueInj } from '~/context'
import { handleTZ } from '~/utils/dateTimeUtils' import { handleTZ } from '~/utils/dateTimeUtils'
import { replaceUrlsWithLink } from '~/utils/urlUtils' import { replaceUrlsWithLink } from '~/utils/urlUtils'
const column = inject(ColumnInj) const column = inject(ColumnInj)
const value = inject('value') const value = inject(ValueInj)
const { isPg } = useProject() const { isPg } = useProject()

4
packages/nc-gui-v2/components/virtual-cell/HasMany.vue

@ -1,11 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ColumnType } from 'nocodb-sdk' import type { ColumnType } from 'nocodb-sdk'
import ItemChip from './components/ItemChip.vue' import ItemChip from './components/ItemChip.vue'
import { ColumnInj } from '~/context' import { ColumnInj, ValueInj } from '~/context'
import { useHasMany } from '#imports' import { useHasMany } from '#imports'
const column = inject(ColumnInj) const column = inject(ColumnInj)
const value = inject('value') const value = inject(ValueInj)
const active = false const active = false
const { childMeta, loadChildMeta, primaryValueProp } = useHasMany(column as ColumnType) const { childMeta, loadChildMeta, primaryValueProp } = useHasMany(column as ColumnType)

210
packages/nc-gui-v2/components/virtual-cell/Lookup.vue

@ -1,183 +1,59 @@
<script> <script lang="ts" setup>
/* import { RelationTypes, UITypes, isVirtualCol } from 'nocodb-sdk' import type { ColumnType, LinkToAnotherRecordType, LookupType } from 'nocodb-sdk'
import TableCell from '../Cell' import { RelationTypes, isVirtualCol, UITypes } from 'nocodb-sdk'
import ItemChip from '~/components/project/spreadsheet/components/virtualCell/components/ItemChip' import { useColumn } from '~/composables'
export default { import { ColumnInj, MetaInj, ReadonlyInj, ValueInj } from '~/context'
name: 'LookupCell',
components: {
TableCell,
// ListChildItemsModal,
ItemChip,
},
props: {
meta: [Object],
metas: [Object],
column: [Object],
nodes: [Object],
row: [Object],
api: [Object, Function],
sqlUi: [Object, Function],
active: Boolean,
isNew: Boolean,
isForm: Boolean,
value: [Object, Array, String, Number],
},
data: () => ({
UITypes,
lookupListModal: false,
lookupTableMeta: null,
lookupColumnMeta: null,
isVirtualCol,
RelationTypes,
}),
computed: {
virtualCell() {
return this.lookupColumnMeta && isVirtualCol(this.lookupColumnMeta)
? () => import('~/components/project/spreadsheet/components/VirtualCell')
: 'div'
},
// todo : optimize
lookupApi() {
// return this.column && this.$ncApis.get({
// env: this.nodes.env,
// dbAlias: this.nodes.dbAlias,
// table: this.column.lk.ltn
// })
},
lookUpMeta() {
// return this.metas ? this.metas[this.column.lk.ltn] : this.$store.state.meta.metas[this.column.lk.ltn]
},
assocMeta() { const { metas, getMeta } = useMetas()
// return this.column.lk.type === 'mm' && (this.metas ? this.metas[this.column.lk.vtn] : this.$store.state.meta.metas[this.column.lk.vtn])
}, provide(ReadonlyInj, true)
lookUpColumnAlias() {
if (!this.lookUpMeta || !this.column.lk.lcn) { const column = inject(ColumnInj) as ColumnType & { colOptions: LookupType }
return const meta = inject(MetaInj)
} const value = inject(ValueInj)
return (this.lookUpMeta.columns.find((cl) => cl.column_name === this.column.lk.lcn) || {}).title const arrValue = Array.isArray(value) ? value : [value]
},
lookUpColumn() { const relationColumn = meta?.value.columns?.find((c) => c.id === column.colOptions.fk_relation_column_id) as ColumnType & {
if (!this.lookUpMeta || !this.column.lk.lcn) { colOptions: LinkToAnotherRecordType
return
} }
return this.lookUpMeta.columns.find((cl) => cl.column_name === this.column.lk.lcn) || {} await getMeta(relationColumn.colOptions.fk_related_model_id as string)
}, const lookupTableMeta = metas?.value[relationColumn.colOptions.fk_related_model_id as string]
localValueObj() {}, const lookupColumn = lookupTableMeta?.columns?.find((c) => c.id === column.colOptions.fk_lookup_column_id) as ColumnType
localValue() {
return this.value && (Array.isArray(this.value) ? this.value : [this.value]) provide(MetaInj, ref(lookupTableMeta))
},
queryParams() {},
},
created() {
this.loadLookupMeta()
this.loadLookupColumnMeta()
},
methods: {
async loadLookupColumnMeta() {
const relationColumn = this.meta.columns.find((c) => c.id === this.column.colOptions.fk_relation_column_id)
this.lookupTableMeta = await this.$store.dispatch('meta/ActLoadMeta', { id: relationColumn.colOptions.fk_related_model_id })
this.lookupColumnMeta = this.lookupTableMeta.columns.find((c) => c.id === this.column.colOptions.fk_lookup_column_id)
},
async loadLookupMeta() {}, const lookupColumnMetaProps = useColumn(lookupColumn)
showLookupListModal() {
this.lookupListModal = true
},
},
} */
</script> </script>
<template> <template>
<div class="d-flex flex-wrap wrapper"> <div class="w-full h-full flex gap-1">
<!-- <template v-if="lookupColumnMeta"> <template v-if="lookupColumn">
<template v-if="isVirtualCol(lookupColumnMeta)"> <!-- Render virtual cell -->
<div v-if="isVirtualCol(lookupColumn)">
<template <template
:is="virtualCell" v-if="lookupColumn.uidt === UITypes.LinkToAnotherRecord && lookupColumn.colOptions.type === RelationTypes.BELONGS_TO"
v-if="
lookupColumnMeta.uidt === UITypes.LinkToAnotherRecord &&
lookupColumnMeta.colOptions.type === RelationTypes.BELONGS_TO &&
Array.isArray(value)
"
> >
<div <SmartsheetVirtualCell
:is="virtualCell" v-for="(v, i) of arrValue"
v-for="(v, i) in value"
:key="i" :key="i"
:is-public="true" :edit-enabled="false"
:metas="metas" :model-value="v"
:is-locked="true" :column="lookupColumn"
:column="lookupColumnMeta"
:row="{ [lookupColumnMeta.title]: v }"
:nodes="nodes"
:meta="lookupTableMeta"
:sql-ui="sqlUi"
/>
</template>
<div
:is="virtualCell"
v-else
:is-public="true"
:metas="metas"
:is-locked="true"
:column="lookupColumnMeta"
:row="{ [lookupColumnMeta.title]: value }"
:nodes="nodes"
:meta="lookupTableMeta"
:sql-ui="sqlUi"
/> />
</template> </template>
<SmartsheetVirtualCell v-else :edit-enabled="false" :model-value="arrValue" :column="lookupColumn" />
</div>
<!-- Render normal cell -->
<template v-else> <template v-else>
<template v-if="localValue"> <!-- For attachment cell avoid adding chip style -->
<ItemChip <div v-for="(v, i) in arrValue" :key="i"
v-for="(value, i) in localValue" :class="{'bg-gray-100 px-2 rounded-full':!lookupColumnMetaProps.isAttachment}">
:key="i" <SmartsheetCell :model-value="v" :column="lookupColumn" :edit-enabled="false" />
style="margin: 1.5px" </div>
:active="active"
:value="value"
:readonly="true"
>
<TableCell
:is-locked="true"
:column="lookupColumnMeta"
:meta="lookupTableMeta"
:db-alias="nodes.dbAlias"
:value="value"
:sql-ui="sqlUi"
/>
</ItemChip>
</template> </template>
</template> </template>
</template> -->
</div> </div>
</template> </template>
<style scoped lang="scss">
.wrapper {
flex-wrap: wrap;
}
</style>
<!--
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
-->

4
packages/nc-gui-v2/components/virtual-cell/ManyToMany.vue

@ -1,11 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import type { ColumnType } from 'nocodb-sdk' import type { ColumnType } from 'nocodb-sdk'
import ItemChip from './components/ItemChip.vue' import ItemChip from './components/ItemChip.vue'
import { ColumnInj } from '~/context' import { ColumnInj, ValueInj } from '~/context'
import { useManyToMany } from '#imports' import { useManyToMany } from '#imports'
const column = inject(ColumnInj) const column = inject(ColumnInj)
const value = inject('value') const value = inject(ValueInj)
const active = false const active = false
const isLocked = false const isLocked = false

4
packages/nc-gui-v2/components/virtual-cell/Rollup.vue

@ -1,5 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
const value = inject('value') import { ValueInj } from '~/context'
const value = inject(ValueInj)
</script> </script>
<template> <template>

3
packages/nc-gui/components/utils/Language.vue

@ -42,6 +42,7 @@ export default {
name: 'Language', name: 'Language',
data: () => ({ data: () => ({
labels: { labels: {
ar: 'العربية',
bn: 'ব', bn: 'ব',
da: 'Dansk', da: 'Dansk',
de: 'Deutsch', de: 'Deutsch',
@ -99,7 +100,7 @@ export default {
document.body.style.direction = targetDirection document.body.style.direction = targetDirection
}, },
isRtlLang() { isRtlLang() {
return ['fa'].includes(this.language) return ['fa', 'ar'].includes(this.language)
}, },
changeLan(lan) { changeLan(lan) {
this.language = lan this.language = lan

522
packages/nc-gui/lang/ar.json

@ -0,0 +1,522 @@
{
"general": {
"home": "الرئيسية",
"load": "تحميل",
"open": "فتح",
"close": "إغلاق",
"yes": "نعم",
"no": "لا",
"ok": "حسنا",
"and": "و",
"or": "أو",
"add": "أضف",
"edit": "تحرير",
"remove": "إزالة",
"save": "حفظ",
"cancel": "إلغاء",
"submit": "إرسال",
"create": "إنشاء",
"insert": "إدراج",
"delete": "حذف",
"update": "تحديث",
"rename": "إعادة تسمية",
"reload": "تحديث",
"reset": "إعادة تعيين",
"install": "تثبيت",
"show": "عرض",
"hide": "إخفاء",
"showAll": "عرض الكل",
"hideAll": "إخفاء الكل",
"showMore": "عرض المزيد",
"showOptions": "إظهار الخيارات",
"hideOptions": "إخفاء الخيارات",
"showMenu": "إظهار القائمة",
"hideMenu": "إخفاء القائمة",
"addAll": "أضف الكل",
"removeAll": "إزالة الكل",
"signUp": "سجل",
"signIn": "تسجيل الدخول",
"signOut": "تسجيل الخروج",
"required": "مطلوب",
"preferred": "المفضل",
"mandatory": "إلزامي",
"loading": "تحميل ...",
"title": "العنوان",
"upload": "رفع",
"download": "تحميل",
"default": "افتراضي",
"more": "المزيد",
"less": "أقل",
"event": "حدث",
"condition": "شرط",
"after": "بعد",
"before": "قبل",
"search": "البحث",
"notification": "إشعار",
"reference": "مرجع",
"function": "وظيفة"
},
"objects": {
"project": "مشروع",
"projects": "مشاريعي",
"table": "جدول",
"tables": "جداول",
"field": "حقل",
"fields": "حقول",
"column": "عمود",
"columns": "أعمدة",
"page": "صفحة",
"pages": "صفحات",
"record": "سجل",
"records": "سجلات",
"webhook": "خطاف",
"webhooks": "الخطافات",
"view": "عرض",
"views": "مشاهدات",
"viewType": {
"grid": "شبكة",
"gallery": "معرض صور",
"form": "نموذج",
"kanban": "كانبان",
"calendar": "تقويم"
},
"user": "مستخدم",
"users": "مستخدمين",
"role": "دور",
"roles": "أدوار",
"roleType": {
"owner": "مالك",
"creator": "منشيء",
"editor": "محرر",
"commenter": "معلق",
"viewer": "مشاهد"
}
},
"datatype": {
"ID": "هوية",
"ForeignKey": "مفتاح خارجي",
"SingleLineText": "نص سطر واحد",
"LongText": "نص طويل",
"Attachment": "مرفق",
"Checkbox": "خانة اختيار",
"MultiSelect": "اختيار متعدد",
"SingleSelect": "اختيار واحد",
"Collaborator": "متعاون",
"Date": "تاريخ",
"Year": "سنة",
"Time": "وقت",
"PhoneNumber": "هاتف",
"Email": "بريد إلكتروني",
"URL": "URL",
"Number": "عدد",
"Decimal": "عشري",
"Currency": "عملة",
"Percent": "نسبة مؤية",
"Duration": "مدة",
"Rating": "تقييم",
"Formula": "معادلة",
"Rollup": "جمع البيانات",
"Count": "العد",
"Lookup": "مشاهدة بيانات",
"DateTime": "تاريخ وقت",
"CreateTime": "إنشاء وقت",
"LastModifiedTime": "وقت آخر تعديل",
"AutoNumber": "عدد تلقائي",
"Barcode": "رمز",
"Button": "أيقونة",
"Password": "كلمة مرور",
"relationProperties": {
"noAction": "لا يوجد إجراء",
"cascade": "تتالي",
"restrict": "تقييد",
"setNull": "تعيين فارغ",
"setDefault": "تعيين افتراضي"
}
},
"filterOperation": {
"isEqual": "يساوي",
"isNotEqual": "لا يساوي",
"isLike": "هو مثل",
"isNot like": "ليس مثل",
"isEmpty": "فارغ",
"isNotEmpty": "ليس فارغ",
"isNull": "is null",
"isNotNull": "is not null"
},
"title": {
"newProj": "مشروع جديد",
"myProject": "مشاريعي",
"formTitle": "عنوان النموذج",
"collabView": "عرض تعاوني",
"lockedView": "عرض مغلق",
"personalView": "عرض شخصي",
"appStore": "متجر التطبيقات",
"teamAndAuth": "الفريق والمصادقة",
"rolesUserMgmt": "الأدوار وإدارة المستخدمين",
"userMgmt": "إدارة المستخدمين",
"apiTokenMgmt": "إدارة رموز API",
"rolesMgmt": "إدارة الأدوار",
"projMeta": "البيانات الوصفية للمشروع",
"metaMgmt": "إدارة ميتا",
"metadata": "البيانات الوصفية",
"exportImportMeta": "تصدير / استيراد Metadata",
"uiACL": "إدارة الوصل لـ UI",
"metaOperations": "عمليات البيانات الوصفية",
"audit": "تدقيق",
"auditLogs": "سجل التدقيق",
"sqlMigrations": "مهاجر SQL",
"dbCredentials": "بيانات اعتماد قاعدة البيانات",
"advancedParameters": "طبقة المقابس الآمنة والمعلمات المتقدمة",
"headCreateProject": "إنشاء مشروع | نوكودب",
"headLogin": "تسجيل الدخول | نوكودب",
"resetPassword": "إعادة تعيين كلمة المرور",
"teamAndSettings": "الفريق والإعدادات",
"apiDocs": "مستندات API",
"importFromAirtable": "استيراد من Airtable"
},
"labels": {
"notifyVia": "إعلام عبر",
"projName": "اسم المشروع",
"tableName": "اسم الجدول",
"viewName": "عرض الاسم",
"viewLink": "عرض الرابط",
"columnName": "اسم العمود",
"columnType": "نوع العمود",
"roleName": "اسم الدور",
"roleDescription": "وصف الدور",
"databaseType": "اكتب في قاعدة البيانات",
"lengthValue": "الطول / القيمة",
"dbType": "نوع قاعدة البيانات",
"sqliteFile": "ملف SQLite",
"hostAddress": "عنوان المضيف",
"port": "رقم المنفذ",
"username": "اسم المستخدم",
"password": "كلمة المرور",
"schemaName": "اسم المخطط",
"action": "إجراء",
"actions": "إجراءات",
"operation": "عملية",
"operationType": "نوع العملية",
"operationSubType": "نوع العملية الفرعية",
"description": "وصف",
"authentication": "مصادقة",
"token": "Token",
"where": "أين",
"cache": "ذاكرة التخزين المؤقت",
"chat": "دردشة",
"email": "البريد الالكتروني",
"storage": "التخزين",
"uiAcl": "UI-ACL",
"models": "نماذج",
"syncState": "حالة المزامنة",
"created": "إنشاء",
"sqlOutput": "إخراج SQL",
"addOption": "إضافة خيار",
"aggregateFunction": "وظيفة التجميع",
"database": "قاعدة البيانات",
"dbCreateIfNotExists": "قاعدة البيانات: إنشاء إذا لم يكن موجودا",
"clientKey": "مفتاح العميل",
"clientCert": "شهادة العميل",
"serverCA": "خادم CA",
"requriedCa": "مطلوب-CA",
"requriedIdentity": "مطلوب-الهوية",
"inflection": {
"tableName": "انعطاف-اسم الجدول",
"columnName": "انعطاف-اسم العمود"
},
"community": {
"starUs1": "نجمه",
"starUs2": "نحن على Github",
"bookDemo": "احجز ديمو مجاني",
"getAnswered": "احصل على إجابات لأسئلتك",
"joinDiscord": "انضم إلى Discord",
"joinCommunity": "انضم إلى مجتمع NocoDB",
"joinReddit": "انضم إلى /r/NocodB",
"followNocodb": "تابع NocoDB"
},
"docReference": "مرجع الوثيقة",
"selectUserRole": "حدد دور المستخدم",
"childTable": "جدول فرعي",
"childColumn": "عمود فرعي",
"onUpdate": "عند التحديث",
"onDelete": "عند الحذف"
},
"activity": {
"createProject": "إنشاء مشروع",
"importProject": "استيراد مشروع",
"searchProject": "البحث عن مشروع",
"editProject": "تحرير المشروع",
"stopProject": "وقف المشروع",
"startProject": "بدء المشروع",
"restartProject": "إعادة تشغيل المشروع",
"deleteProject": "حذف المشروع",
"refreshProject": "تحديث المشاريع",
"saveProject": "حفظ المشروع",
"createProjectExtended": {
"extDB": "إنشاء عن طريق ربط <br> قاعدة بيانات خارجية",
"excel": "إنشاء مشروع من Excel",
"template": "إنشاء مشروع من قالب"
},
"OkSaveProject": "موافق وحفظ المشروع",
"upgrade": {
"available": "ترقية متوفرة",
"releaseNote": "ملاحظات الإصدار",
"howTo": "كيفية الترقية ؟"
},
"translate": "مساعدة ترجمة",
"account": {
"authToken": "نسخ Auth Token",
"swagger": "مستند Swagger APIs",
"projInfo": "نسخ معلومات المشروع",
"themes": "مظاهر"
},
"sort": "فرز",
"addSort": "إضافة خيار فرز",
"filter": "تصفية",
"addFilter": "إضافة تصفية",
"share": "مشاركة",
"shareBase": {
"disable": "تعطيل قاعدة مشتركة",
"enable": "أي شخص لديه الرابط",
"link": "رابط قاعدة مشتركة"
},
"invite": "دعوة",
"inviteMore": "دعوة المزيد",
"inviteTeam": "دعوة فريق",
"inviteToken": "رمز دعوة",
"newUser": "مستخدم جديد",
"editUser": "تحرير مستخدم",
"deleteUser": "إزالة المستخدم من المشروع",
"resendInvite": "إعادة إرسال دعوة البريد الإلكتروني",
"copyInviteURL": "نسخ رابط الدعوة",
"newRole": "دور جديد",
"reloadRoles": "إعادة تحميل الأدوار",
"nextPage": "الصفحة التالية",
"prevPage": "الصفحة السابقة",
"nextRecord": "السجل التالي",
"previousRecord": "السجل السابق",
"copyApiURL": "نسخ رابط API",
"createTable": "إنشاء جدول",
"refreshTable": "تحديث الجدول",
"renameTable": "إعادة تسمية الجدول",
"deleteTable": "حذف الجدول",
"addField": "إضافة حقل جديد إلى هذا الجدول",
"setPrimary": "تعيين كقيمة أساسية",
"addRow": "إضافة صف جديد",
"saveRow": "حفظ الصف",
"insertRow": "إدراج صف جديد",
"deleteRow": "حذف الصف",
"deleteSelectedRow": "حذف الصفوف المحددة",
"importExcel": "استيراد Excel",
"importCSV": "استيراد CSV",
"downloadCSV": "تحميل كـ CSV",
"uploadCSV": "رفع كـ CSV",
"import": "استيراد",
"importMetadata": "استيراد البيانات الوصفية",
"exportMetadata": "تصدير البيانات الوصفية",
"clearMetadata": "مسح البيانات الوصفية",
"exportToFile": "تصدير إلى ملف",
"changePwd": "تغيير كلمة المرور",
"createView": "إنشاء طريقة عرض",
"shareView": "مشاركة عرض",
"listSharedView": "قائمة العرض المشتركة",
"ListView": "قائمة المشاهدات",
"copyView": "نسخ العرض",
"renameView": "إعادة تسمية عرض",
"deleteView": "حذف العرض",
"createGrid": "إنشاء عرض الشبكة",
"createGallery": "إنشاء عرض المعرض",
"createCalendar": "إنشاء عرض التقويم",
"createKanban": "إنشاء عرض كانبان",
"createForm": "إنشاء عرض النموذج",
"showSystemFields": "إظهار حقول النظام",
"copyUrl": "نسخ الرابط",
"openTab": "افتح علامة تبويب جديدة",
"iFrame": "انسخ كود HTML القابل للتضمين",
"addWebhook": "إضافة Webhook جديد",
"newToken": "إضافة Token جديد",
"exportZip": "تصدير الرمز البريدي",
"importZip": "استيراد الرمز البريدي",
"metaSync": "مزامنة الآن",
"settings": "الإعدادات",
"previewAs": "معاينة كـ",
"resetReview": "إعادة تعيين المعاينة",
"testDbConn": "اختبار اتصال قاعدة البيانات",
"removeDbFromEnv": "إزالة قاعدة البيانات من البيئة",
"editConnJson": "تحرير اتصال جسون",
"sponsorUs": "ادعمنا",
"sendEmail": "ارسل بريد الكتروني"
},
"tooltip": {
"saveChanges": "حفظ التغييرات",
"xcDB": "إنشاء مشروع جديد",
"extDB": "يدعم MySQL ، PostgreSQL ، SQL Server و SQLite",
"apiRest": "يمكن الوصول إليها عبر REST APIs",
"apiGQL": "يمكن الوصول إليها عبر GraphQL APIs",
"theme": {
"dark": "أنها لا تأتي باللون الأسود (^⇧B)",
"light": "هل تأتي باللون الأسود ؟ (^⇧B)"
},
"addTable": "إضافة جدول جديد",
"inviteMore": "دعوة المزيد من المستخدمين",
"toggleNavDraw": "تبديل درج التنقل",
"reloadApiToken": "إعادة تحميل رموز API",
"generateNewApiToken": "إنشاء رمز API جديد",
"addRole": "إضافة دور جديد",
"reloadList": "تحديث القائمة",
"metaSync": "مزامنة البيانات الوصفية",
"sqlMigration": "إعادة تحميل المهاجر",
"updateRestart": "التحديث وإعادة التشغيل",
"cancelReturn": "إلغاء والعودة",
"exportMetadata": "تصدير جميع البيانات الوصفية من الجداول الوصفية إلى الدليل الوصفي.",
"importMetadata": "استيراد كافة البيانات الوصفية من الدليل الوصفي إلى الجداول الوصفية.",
"clearMetadata": "امسح جميع البيانات الوصفية من جداول التعريف.",
"clientKey": "اختر .الملف الرئيسي",
"clientCert": "اختر .ملف الشهادة",
"clientCA": "حدد ملف CA"
},
"placeholder": {
"projName": "أدخل اسم المشروع",
"password": {
"enter": "أدخل كلمة المرور",
"current": "كلمة المرور الحالية",
"new": "كلمة مرور جديدة",
"save": "حفظ كلمة المرور",
"confirm": "تأكيد كلمة المرور الجديدة"
},
"searchProjectTree": "جداول البحث",
"searchFields": "حقول البحث",
"searchColumn": "بحث {بحث} عمود",
"searchApps": "تطبيقات البحث",
"searchModels": "نماذج البحث",
"noItemsFound": "لم يتم العثور على عناصر",
"defaultValue": "القيمة الافتراضية",
"filterByEmail": "تصفية عن طريق البريد الإلكتروني"
},
"msg": {
"info": {
"footerInfo": "الصفوف لكل صفحة",
"upload": "حدد الملف المراد رفعه",
"upload_sub": "أو سحب وإسقاط الملف",
"excelSupport": "المدعومة: .xls, .xlsx, .xlsm, .ods, .ots",
"excelURL": "أدخل رابط ملف Excel",
"csvURL": "أدخل رابط ملف CSV",
"footMsg": "# من الصفوف لتحليل لاستنتاج نوع البيانات",
"excelImport": "sheet(s) قابل للاستيراد",
"exportMetadata": "هل تريد تصدير البيانات الوصفية من الجداول الوصفية؟",
"importMetadata": "هل تريد استيراد البيانات الوصفية من الجداول الوصفية؟",
"clearMetadata": "هل تريد مسح البيانات الوصفية من الجداول الوصفية؟",
"projectEmptyMessage": "ابدأ بإنشاء مشروع جديد",
"stopProject": "هل تريد إيقاف المشروع؟",
"startProject": "هل تريد أن تبدأ المشروع؟",
"restartProject": "هل تريد إعادة تشغيل المشروع؟",
"deleteProject": "هل تريد حذف المشروع؟",
"shareBasePrivate": "إنشاء قاعدة للقراءة فقط قابلة للمشاركة بشكل عام",
"shareBasePublic": "يمكن لأي شخص لديه الرابط على الانترنت مشاهدته",
"userInviteNoSMTP": "يبدو أنك لم تقم بتكوين الارسال بعد! يرجى نسخ رابط الدعوة أعلاه وإرساله إلى",
"dragDropHide": "سحب وإسقاط الحقول هنا لإخفاء",
"formInput": "أدخل تسمية إدخال علامة",
"formHelpText": "أضف نص المساعدة",
"onlyCreator": "مرئية فقط للمنشيء",
"formDesc": "إضافة وصف النموذج",
"beforeEnablePwd": "تقييد الوصول بكلمة مرور",
"afterEnablePwd": "الوصول مقيد بكلمة مرور",
"privateLink": "تتم مشاركة هذا العرض عبر رابط خاص",
"privateLinkAdditionalInfo": "يمكن للأشخاص الذين لديهم رابط خاص رؤية الخلايا المرئية فقط في طريقة العرض هذه",
"afterFormSubmitted": "بعد تقديم النموذج",
"apiOptions": "الوصول للمشروع عبر",
"submitAnotherForm": "إظهار زر 'إرسال نموذج آخر'",
"showBlankForm": "إظهار نموذج فارغ بعد 5 ثوان",
"emailForm": "راسلني بالبريد عبر",
"showSysFields": "إظهار حقول النظام",
"filterAutoApply": "تطبيق تلقائي",
"showMessage": "اعرض هذه الرسالة",
"viewNotShared": "لم تتم مشاركة العرض الحالي!",
"showAllViews": "عرض جميع المشاهدات المشتركة لهذا الجدول",
"collabView": "يمكن للمتعاونين الذين لديهم أذونات تحرير أو أعلى تغيير تكوين العرض.",
"lockedView": "لا يمكن لأحد تحرير تكوين العرض حتى يتم إلغاء قفله.",
"personalView": "فقط يمكنك تحرير تكوين العرض. يتم إخفاء طريقة العرض الشخصية للمتعاونين الآخرين بشكل افتراضي.",
"ownerDesc": "يمكن إضافة / إزالة المنشئين. وتحرير كامل هياكل قاعدة البيانات والحقول.",
"creatorDesc": "يمكن تحرير كامل هيكل قاعدة البيانات والقيم.",
"editorDesc": "يمكن تحرير السجلات ولكن لا يمكن تغيير بنية قاعدة البيانات/الحقول.",
"commenterDesc": "يمكن العرض والتعليق على السجلات ولكن لا يمكن تحرير أي شيء",
"viewerDesc": "يمكن عرض السجلات ولكن لا يمكن تحرير أي شيء",
"addUser": "إضافة مستخدم جديد",
"staticRoleInfo": "لا يمكن تحرير الأدوار المحددة للنظام",
"exportZip": "تصدير مشروع ميتا لملف مضغوط وتحميله",
"importZip": "استيراد مشروع ميتا لملف مضغوط وإعادة التشغيل.",
"importText": "استيراد مشروع nocoDB عن طريق رفع ملف مضغوط",
"metaNoChange": "لم يتم تحديد أي تغيير",
"sqlMigration": "سيتم إنشاء عمليات ترحيل المخطط تلقائيا. إنشاء جدول وتحديث هذه الصفحة.",
"dbConnectionStatus": "التحقق من صحة البيئة",
"dbConnected": "كان الاتصال ناجحا",
"notifications": {
"no_new": "لا إخطارات جديدة",
"clear": "واضح"
},
"sponsor": {
"header": "يمكنك مساعدتنا!",
"message": "نحن فريق صغير يعمل بدوام كامل لجعل NocoDB مفتوح المصدر. ونحن نعتقد أن أداة مثل NocoDB يجب أن تكون متاحة بحرية لكل من يريد حل مشكله على شبكة الإنترنت."
},
"loginMsg": "تسجيل الدخول إلى NocoDB",
"passwordRecovery": {
"message_1": "يرجى تقديم عنوان البريد الإلكتروني الذي استخدمته عند التسجيل.",
"message_2": "سوف نرسل لك رسالة بريد إلكتروني تحتوي على رابط لإعادة تعيين كلمة المرور الخاصة بك.",
"success": "يرجى التحقق من بريدك الإلكتروني لإعادة تعيين كلمة المرور"
},
"signUp": {
"superAdmin": "سوف تكون'المشرف سوبر'",
"alreadyHaveAccount": "لديك حساب بالفعل ؟",
"workEmail": "أدخل بريدك الإلكتروني للعمل",
"enterPassword": "أدخل كلمة المرور",
"forgotPassword": "نسيت كلمة المرور ؟",
"dontHaveAccount": "ليس لديك حساب ؟"
},
"addView": {
"grid": "إضافة عرض الشبكة",
"gallery": "إضافة عرض المعرض",
"form": "إضافة عرض النموذج",
"kanban": "إضافة عرض كانبان",
"calendar": "إضافة طريقة عرض التقويم"
},
"tablesMetadataInSync": "تزامن البيانات الوصفية للجداول",
"addMultipleUsers": "يمكنك إضافة أكثر من فاصلة (,) لفصل الإيميلات",
"enterTableName": "أدخل اسم الجدول",
"addDefaultColumns": "إضافة الأعمدة الافتراضية",
"tableNameInDb": "اسم الجدول كما تم حفظه في قاعدة البيانات"
},
"error": {
"searchProject": "البحث عن {بحث} لم يتم العثور على نتائج",
"invalidChar": "حرف غير صالح في مسار المجلد.",
"invalidDbCredentials": "بيانات اعتماد قاعدة بيانات غير صالحة.",
"unableToConnectToDb": "غير قادر على الاتصال بقاعدة البيانات ، يرجى التحقق من قاعدة البيانات الخاصة بك.",
"userDoesntHaveSufficientPermission": "المستخدم غير موجود أو لديه إذن كاف لإنشاء مخطط.",
"dbConnectionStatus": "معلمات قاعدة البيانات غير صالحة",
"dbConnectionFailed": "فشل الاتصال:",
"signUpRules": {
"emailReqd": "البريد الالكتروني مطلوب",
"emailInvalid": "يجب أن يكون البريد الإلكتروني صالحا",
"passwdRequired": "كلمة المرور مطلوبة",
"passwdLength": "يجب أن تكون كلمة المرور الخاصة بك 8 أحرف على الأقل",
"passwdMismatch": "كلمات المرور غير متطابقة"
}
},
"toast": {
"exportMetadata": "تصدير البيانات الوصفية للمشروع بنجاح",
"importMetadata": "البيانات الوصفية للمشروع تم استيرادها بنجاح",
"clearMetadata": "مسح البيانات الوصفية للمشروع بنجاح",
"stopProject": "توقف المشروع بنجاح",
"startProject": "بدأ المشروع بنجاح",
"restartProject": "إعادة تشغيل المشروع بنجاح",
"deleteProject": "تم حذف المشروع بنجاح",
"authToken": "تم نسخ رمز المصادقة للحافظة",
"projInfo": "تم نسخ معلومات المشروع للحافظة",
"inviteUrlCopy": "تم نسخ رابط الدعوة للحافظة",
"createView": "تم إنشاء العرض بنجاح",
"formEmailSMTP": "يرجى تفعيل SMTP لتمكين إشعار البريد الإلكتروني",
"collabView": "تحولت بنجاح إلى عرض تعاوني",
"lockedView": "تم التبديل بنجاح إلى العرض المقفل",
"futureRelease": "قريبا!"
}
}
}

3
packages/nc-gui/plugins/i18n.js

@ -46,7 +46,8 @@ export default ({ app, store }) => {
fa: require('~/lang/fa.json'), fa: require('~/lang/fa.json'),
tr: require('~/lang/tr.json'), tr: require('~/lang/tr.json'),
hi: require('~/lang/hi.json'), hi: require('~/lang/hi.json'),
bn: require('~/lang/bn.json') bn: require('~/lang/bn.json'),
ar: require('~/lang/ar.json')
} }
}) })

1
scripts/cypress/integration/common/6d_language_validation.js

@ -44,6 +44,7 @@ export const genTest = (apiType, dbType) => {
}; };
let langMenu = [ let langMenu = [
"ar.json",
"bn.json", "bn.json",
"da.json", "da.json",
"de.json", "de.json",

Loading…
Cancel
Save