Browse Source

Merge branch 'develop' into test/fix-multi-field-editor-test

pull/8522/head
Raju Udava 6 months ago
parent
commit
584dbda697
  1. 2
      packages/nc-gui/components/shared-view/Calendar.vue
  2. 2
      packages/nc-gui/components/shared-view/Gallery.vue
  3. 1
      packages/nc-gui/components/shared-view/Grid.vue
  4. 2
      packages/nc-gui/components/shared-view/Kanban.vue
  5. 2
      packages/nc-gui/components/shared-view/Map.vue
  6. 8
      packages/nc-gui/components/smartsheet/expanded-form/Comments.vue
  7. 50
      packages/nc-gui/components/smartsheet/expanded-form/index.vue
  8. 3
      packages/nc-gui/components/smartsheet/grid/Table.vue
  9. 6
      packages/nc-gui/components/smartsheet/header/Cell.vue
  10. 4
      packages/nc-gui/components/smartsheet/header/VirtualCell.vue
  11. 246
      packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue
  12. 1
      packages/nc-gui/components/smartsheet/toolbar/ColumnFilterMenu.vue
  13. 9
      packages/nc-gui/components/smartsheet/toolbar/FieldListAutoCompleteDropdown.vue
  14. 11
      packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue
  15. 4
      packages/nc-gui/components/tabs/Smartsheet.vue
  16. 14
      packages/nc-gui/composables/useViewColumns.ts
  17. 2
      packages/nc-gui/composables/useViewFilters.ts
  18. 7
      packages/nc-gui/lang/ar.json
  19. 7
      packages/nc-gui/lang/bn_IN.json
  20. 5
      packages/nc-gui/lang/cs.json
  21. 7
      packages/nc-gui/lang/da.json
  22. 7
      packages/nc-gui/lang/de.json
  23. 12
      packages/nc-gui/lang/en.json
  24. 11
      packages/nc-gui/lang/es.json
  25. 9
      packages/nc-gui/lang/eu.json
  26. 7
      packages/nc-gui/lang/fa.json
  27. 7
      packages/nc-gui/lang/fi.json
  28. 351
      packages/nc-gui/lang/fr.json
  29. 7
      packages/nc-gui/lang/he.json
  30. 7
      packages/nc-gui/lang/hi.json
  31. 7
      packages/nc-gui/lang/hr.json
  32. 7
      packages/nc-gui/lang/id.json
  33. 9
      packages/nc-gui/lang/it.json
  34. 7
      packages/nc-gui/lang/ja.json
  35. 5
      packages/nc-gui/lang/ko.json
  36. 7
      packages/nc-gui/lang/lv.json
  37. 7
      packages/nc-gui/lang/nl.json
  38. 7
      packages/nc-gui/lang/no.json
  39. 5
      packages/nc-gui/lang/pl.json
  40. 9
      packages/nc-gui/lang/pt.json
  41. 7
      packages/nc-gui/lang/pt_BR.json
  42. 7
      packages/nc-gui/lang/ru.json
  43. 7
      packages/nc-gui/lang/sk.json
  44. 7
      packages/nc-gui/lang/sl.json
  45. 7
      packages/nc-gui/lang/sv.json
  46. 7
      packages/nc-gui/lang/th.json
  47. 5
      packages/nc-gui/lang/tr.json
  48. 7
      packages/nc-gui/lang/uk.json
  49. 7
      packages/nc-gui/lang/vi.json
  50. 21
      packages/nc-gui/lang/zh-Hans.json
  51. 7
      packages/nc-gui/lang/zh-Hant.json
  52. 2
      packages/nocodb/src/app.module.ts
  53. 6
      packages/nocodb/src/controllers/auth/ui/emailTemplates/invite.ts
  54. 4
      packages/nocodb/src/controllers/auth/ui/emailTemplates/verify.ts
  55. 4
      packages/nocodb/src/filters/global-exception/global-exception.filter.ts
  56. 3
      packages/nocodb/src/helpers/isDisposableEmail.ts
  57. 13
      packages/nocodb/src/interface/Jobs.ts
  58. 6
      packages/nocodb/src/modules/global/global.module.ts
  59. 6
      packages/nocodb/src/modules/jobs/fallback/fallback-queue.service.ts
  60. 13
      packages/nocodb/src/modules/jobs/jobs-service.interface.ts
  61. 5
      packages/nocodb/src/modules/jobs/jobs.controller.ts
  62. 2
      packages/nocodb/src/modules/jobs/jobs.module.ts
  63. 5
      packages/nocodb/src/modules/jobs/jobs/at-import/at-import.controller.ts
  64. 3
      packages/nocodb/src/modules/jobs/jobs/export-import/duplicate.controller.ts
  65. 13
      packages/nocodb/src/modules/jobs/jobs/export-import/duplicate.processor.ts
  66. 64
      packages/nocodb/src/modules/jobs/jobs/export-import/import.service.ts
  67. 8
      packages/nocodb/src/modules/jobs/jobs/health-check.processor.ts
  68. 5
      packages/nocodb/src/modules/jobs/jobs/meta-sync/meta-sync.controller.ts
  69. 5
      packages/nocodb/src/modules/jobs/jobs/source-create/source-create.controller.ts
  70. 3
      packages/nocodb/src/modules/jobs/jobs/source-delete/source-delete.controller.ts
  71. 24
      packages/nocodb/src/modules/jobs/jobs/webhook-handler/webhook-handler.processor.ts
  72. 6
      packages/nocodb/src/services/base-users/ui/emailTemplates/invite.ts
  73. 4
      packages/nocodb/src/services/base-users/ui/emailTemplates/verify.ts
  74. 10
      packages/nocodb/src/services/columns.service.ts
  75. 61
      packages/nocodb/src/services/hook-handler.service.ts
  76. 2
      tests/playwright/pages/Dashboard/ViewSidebar/index.ts
  77. 9
      tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts

2
packages/nc-gui/components/shared-view/Calendar.vue

@ -11,8 +11,6 @@ provide(MetaInj, meta)
provide(ActiveViewInj, sharedView) provide(ActiveViewInj, sharedView)
provide(FieldsInj, ref(meta.value?.columns || []))
provide(IsPublicInj, ref(true)) provide(IsPublicInj, ref(true))
useProvideViewColumns(sharedView, meta, () => reloadEventHook?.trigger(), true) useProvideViewColumns(sharedView, meta, () => reloadEventHook?.trigger(), true)

2
packages/nc-gui/components/shared-view/Gallery.vue

@ -11,8 +11,6 @@ provide(MetaInj, meta)
provide(ActiveViewInj, sharedView) provide(ActiveViewInj, sharedView)
provide(FieldsInj, ref(meta.value?.columns || []))
provide(IsPublicInj, ref(true)) provide(IsPublicInj, ref(true))
useProvideViewColumns(sharedView, meta, () => reloadEventHook?.trigger(), true) useProvideViewColumns(sharedView, meta, () => reloadEventHook?.trigger(), true)

1
packages/nc-gui/components/shared-view/Grid.vue

@ -18,7 +18,6 @@ provide(ReloadViewDataHookInj, reloadEventHook)
provide(ReadonlyInj, ref(true)) provide(ReadonlyInj, ref(true))
provide(MetaInj, meta) provide(MetaInj, meta)
provide(ActiveViewInj, sharedView) provide(ActiveViewInj, sharedView)
provide(FieldsInj, columns)
provide(IsPublicInj, ref(true)) provide(IsPublicInj, ref(true))
provide(IsLockedInj, isLocked) provide(IsLockedInj, isLocked)

2
packages/nc-gui/components/shared-view/Kanban.vue

@ -11,8 +11,6 @@ provide(MetaInj, meta)
provide(ActiveViewInj, sharedView) provide(ActiveViewInj, sharedView)
provide(FieldsInj, ref(meta.value?.columns || []))
provide(IsPublicInj, ref(true)) provide(IsPublicInj, ref(true))
useProvideViewColumns(sharedView, meta, () => reloadEventHook?.trigger(), true) useProvideViewColumns(sharedView, meta, () => reloadEventHook?.trigger(), true)

2
packages/nc-gui/components/shared-view/Map.vue

@ -11,8 +11,6 @@ provide(MetaInj, meta)
provide(ActiveViewInj, sharedView) provide(ActiveViewInj, sharedView)
provide(FieldsInj, ref(meta.value?.columns || []))
provide(IsPublicInj, ref(true)) provide(IsPublicInj, ref(true))
useProvideViewColumns(sharedView, meta, () => reloadEventHook?.trigger(), true) useProvideViewColumns(sharedView, meta, () => reloadEventHook?.trigger(), true)

8
packages/nc-gui/components/smartsheet/expanded-form/Comments.vue

@ -166,10 +166,10 @@ watch(commentsWrapperEl, () => {
<div v-else ref="commentsWrapperEl" class="flex flex-col h-full py-1 nc-scrollbar-thin"> <div v-else ref="commentsWrapperEl" class="flex flex-col h-full py-1 nc-scrollbar-thin">
<div v-for="log of comments" :key="log.id"> <div v-for="log of comments" :key="log.id">
<div class="group gap-3 overflow-hidden hover:bg-gray-200 flex items-start px-3 pt-3 pb-4"> <div class="group gap-3 overflow-hidden hover:bg-gray-200 flex items-start px-3 pt-3 pb-4">
<GeneralUserIcon size="medium" :name="log.display_name" :email="log.user" class="mt-0.5" /> <GeneralUserIcon size="medium" :name="log.display_name" :email="log.user" class="mt-0.7" />
<div class="flex-1 flex flex-col gap-1 max-w-[calc(100%_-_24px)]"> <div class="flex-1 flex flex-col gap-0.5 max-w-[calc(100%_-_24px)]">
<div class="w-full flex justify-between gap-3 min-h-7"> <div class="w-full flex justify-between gap-3 min-h-7">
<div class="flex items-start max-w-[calc(100%_-_40px)]"> <div class="flex items-center max-w-[calc(100%_-_40px)]">
<div class="w-full flex flex-wrap items-center"> <div class="w-full flex flex-wrap items-center">
<NcTooltip class="truncate max-w-42 mr-2" show-on-truncate-only> <NcTooltip class="truncate max-w-42 mr-2" show-on-truncate-only>
<template #title> <template #title>
@ -389,7 +389,7 @@ watch(commentsWrapperEl, () => {
.ant-tabs-nav { .ant-tabs-nav {
@apply px-3; @apply px-3;
.ant-tabs-nav-list { .ant-tabs-nav-list {
@apply w-[calc(100%_-_24px)] gap-6; @apply w-full gap-6;
.ant-tabs-tab { .ant-tabs-tab {
@apply flex-1 flex items-center justify-center pt-3 pb-2.5; @apply flex-1 flex items-center justify-center pt-3 pb-2.5;

50
packages/nc-gui/components/smartsheet/expanded-form/index.vue

@ -562,7 +562,7 @@ export default {
<div <div
class="flex min-h-7 flex-shrink-0 w-full items-center nc-expanded-form-header relative p-4 xs:(px-2 py-0 min-h-[48px]) justify-between" class="flex min-h-7 flex-shrink-0 w-full items-center nc-expanded-form-header relative p-4 xs:(px-2 py-0 min-h-[48px]) justify-between"
> >
<div class="flex-1 flex gap-3 lg:w-100 <lg:max-w-[calc(100%_-_178px)] xs:(max-w-[calc(100%_-_44px)])"> <div class="flex-1 flex gap-4 lg:w-100 <lg:max-w-[calc(100%_-_178px)] xs:(max-w-[calc(100%_-_44px)])">
<div class="flex gap-2"> <div class="flex gap-2">
<NcTooltip v-if="props.showNextPrevIcons"> <NcTooltip v-if="props.showNextPrevIcons">
<template #title> {{ renderAltOrOptlKey() }} + </template> <template #title> {{ renderAltOrOptlKey() }} + </template>
@ -601,9 +601,9 @@ export default {
}" }"
> >
<div v-if="meta.title" class="flex items-center gap-2 px-2 py-1 rounded-lg bg-gray-100 text-gray-800"> <div v-if="meta.title" class="flex items-center gap-2 px-2 py-1 rounded-lg bg-gray-100 text-gray-800">
<GeneralTableIcon :meta="meta" class="!text-gray-800" /> <GeneralTableIcon :meta="meta" class="!text-gray-800 !mx-0" />
<NcTooltip class="truncate max-w-[100px] xs:(max-w-[82px]) h-5" show-on-truncate-only> <NcTooltip class="truncate text-sm max-w-[100px] xs:(max-w-[82px]) align-middle" show-on-truncate-only>
<template #title> <template #title>
{{ meta.title }} {{ meta.title }}
</template> </template>
@ -627,6 +627,21 @@ export default {
</div> </div>
</div> </div>
<div class="flex gap-2"> <div class="flex gap-2">
<NcTooltip v-if="!isMobileMode && isUIAllowed('dataEdit')">
<template #title> {{ renderAltOrOptlKey() }} + S </template>
<NcButton
v-e="['c:row-expand:save']"
:disabled="changedColumns.size === 0 && !isUnsavedFormExist"
:loading="isSaving"
class="nc-expand-form-save-btn !xs:(text-base) !h-7 !px-2"
data-testid="nc-expanded-form-save"
type="primary"
size="xsmall"
@click="save"
>
<div class="xs:px-1">{{ newRecordSubmitBtnText ?? 'Save Record' }}</div>
</NcButton>
</NcTooltip>
<NcButton <NcButton
v-if="!isNew && rowId && !isMobileMode" v-if="!isNew && rowId && !isMobileMode"
:disabled="isLoading" :disabled="isLoading"
@ -645,21 +660,6 @@ export default {
{{ isRecordLinkCopied ? $t('labels.copiedRecordURL') : $t('labels.copyRecordURL') }} {{ isRecordLinkCopied ? $t('labels.copiedRecordURL') : $t('labels.copyRecordURL') }}
</div> </div>
</NcButton> </NcButton>
<NcTooltip v-if="!isMobileMode && isUIAllowed('dataEdit')">
<template #title> {{ renderAltOrOptlKey() }} + S </template>
<NcButton
v-e="['c:row-expand:save']"
:disabled="changedColumns.size === 0 && !isUnsavedFormExist"
:loading="isSaving"
class="nc-expand-form-save-btn !xs:(text-base) !h-7 !px-2"
data-testid="nc-expanded-form-save"
type="primary"
size="xsmall"
@click="save"
>
<div class="xs:px-1">{{ newRecordSubmitBtnText ?? 'Save Record' }}</div>
</NcButton>
</NcTooltip>
<NcDropdown v-if="!isNew && rowId && !isMobileMode" placement="bottomRight"> <NcDropdown v-if="!isNew && rowId && !isMobileMode" placement="bottomRight">
<NcButton type="text" size="xsmall" class="nc-expand-form-more-actions !w-7 !h-7" :disabled="isLoading"> <NcButton type="text" size="xsmall" class="nc-expand-form-more-actions !w-7 !h-7" :disabled="isLoading">
<GeneralIcon icon="threeDotVertical" class="text-md" :class="isLoading ? 'text-gray-300' : 'text-gray-700'" /> <GeneralIcon icon="threeDotVertical" class="text-md" :class="isLoading ? 'text-gray-300' : 'text-gray-700'" />
@ -730,7 +730,7 @@ export default {
> >
<div <div
ref="expandedFormScrollWrapper" ref="expandedFormScrollWrapper"
class="flex flex-col flex-grow gap-3 h-full max-h-full nc-scrollbar-thin items-center w-full p-4 xs:(px-4 pt-4 pb-2 gap-6) children:max-w-[588px] <lg:(children:max-w-[450px])" class="flex flex-col flex-grow gap-4 h-full max-h-full nc-scrollbar-thin items-center w-full p-4 xs:(px-4 pt-4 pb-2 gap-6) children:max-w-[588px] <lg:(children:max-w-[450px])"
> >
<div <div
v-for="(col, i) of fields" v-for="(col, i) of fields"
@ -1024,14 +1024,18 @@ export default {
} }
.nc-data-cell { .nc-data-cell {
box-shadow: 0 0 1px rgba(0, 0, 0, 0.1); @apply !rounded-lg;
&:hover, transition: all 0.3s;
&:hover {
@apply !border-1 !border-brand-400;
}
&:focus-within { &:focus-within {
box-shadow: 0 0 3px rgba(0, 0, 0, 0.1) !important; box-shadow: 0px 0px 0px 2px rgba(51, 102, 255, 0.24) !important;
} }
} }
.nc-data-cell:focus-within { .nc-data-cell:focus-within {
@apply !border-1 !border-brand-500 !rounded-lg; @apply !border-1 !border-brand-500;
} }
:deep(.nc-system-field input) { :deep(.nc-system-field input) {

3
packages/nc-gui/components/smartsheet/grid/Table.vue

@ -1136,6 +1136,9 @@ const calculateSlices = () => {
start: 0, start: 0,
end: 0, end: 0,
} }
// try again until the grid is rendered
setTimeout(calculateSlices, 100)
return return
} }

6
packages/nc-gui/components/smartsheet/header/Cell.vue

@ -99,7 +99,7 @@ const onClick = (e: Event) => {
:class="{ :class="{
'h-full': column, 'h-full': column,
'!text-gray-400': isKanban, '!text-gray-400': isKanban,
'flex-col !items-start justify-center': isExpandedForm && !isMobileMode, 'flex-col !items-start justify-center pt-0.5': isExpandedForm && !isMobileMode,
'cursor-pointer hover:bg-gray-100': isExpandedForm && !isMobileMode && isUIAllowed('fieldEdit'), 'cursor-pointer hover:bg-gray-100': isExpandedForm && !isMobileMode && isUIAllowed('fieldEdit'),
'bg-gray-100': isExpandedForm ? editColumnDropdown || isDropDownOpen : false, 'bg-gray-100': isExpandedForm ? editColumnDropdown || isDropDownOpen : false,
}" }"
@ -138,7 +138,7 @@ const onClick = (e: Event) => {
<NcTooltip <NcTooltip
v-if="column" v-if="column"
:class="{ :class="{
'cursor-pointer pt-0.25': !isForm && isUIAllowed('fieldEdit') && !hideMenu, 'cursor-pointer': !isForm && isUIAllowed('fieldEdit') && !hideMenu,
'cursor-default': isForm || !isUIAllowed('fieldEdit') || hideMenu, 'cursor-default': isForm || !isUIAllowed('fieldEdit') || hideMenu,
'truncate': !isForm, 'truncate': !isForm,
}" }"
@ -164,7 +164,7 @@ const onClick = (e: Event) => {
<GeneralIcon <GeneralIcon
v-if="isExpandedForm && !isMobileMode && isUIAllowed('fieldEdit')" v-if="isExpandedForm && !isMobileMode && isUIAllowed('fieldEdit')"
icon="arrowDown" icon="arrowDown"
class="flex-none text-grey h-full text-grey cursor-pointer ml-1 group-hover:visible" class="flex-none cursor-pointer ml-1 group-hover:visible w-4 h-4"
:class="{ :class="{
visible: editColumnDropdown || isDropDownOpen, visible: editColumnDropdown || isDropDownOpen,
invisible: !(editColumnDropdown || isDropDownOpen), invisible: !(editColumnDropdown || isDropDownOpen),

4
packages/nc-gui/components/smartsheet/header/VirtualCell.vue

@ -179,7 +179,7 @@ const onClick = (e: Event) => {
<div <div
class="flex items-center w-full h-full text-small text-gray-500 font-weight-medium group" class="flex items-center w-full h-full text-small text-gray-500 font-weight-medium group"
:class="{ :class="{
'flex-col !items-start justify-center': isExpandedForm, 'flex-col !items-start justify-center pt-0.5': isExpandedForm && !isMobileMode,
'bg-gray-100': isExpandedForm ? editColumnDropdown || isDropDownOpen : false, 'bg-gray-100': isExpandedForm ? editColumnDropdown || isDropDownOpen : false,
'cursor-pointer hover:bg-gray-100': isExpandedForm && !isMobileMode && isUIAllowed('fieldEdit'), 'cursor-pointer hover:bg-gray-100': isExpandedForm && !isMobileMode && isUIAllowed('fieldEdit'),
}" }"
@ -220,7 +220,7 @@ const onClick = (e: Event) => {
<GeneralIcon <GeneralIcon
v-if="isExpandedForm && !isMobileMode && isUIAllowed('fieldEdit')" v-if="isExpandedForm && !isMobileMode && isUIAllowed('fieldEdit')"
icon="arrowDown" icon="arrowDown"
class="flex-none h-full cursor-pointer ml-1 group-hover:visible" class="flex-none cursor-pointer ml-1 group-hover:visible w-4 h-4"
:class="{ :class="{
visible: editColumnDropdown || isDropDownOpen, visible: editColumnDropdown || isDropDownOpen,
invisible: !(editColumnDropdown || isDropDownOpen), invisible: !(editColumnDropdown || isDropDownOpen),

246
packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue

@ -11,6 +11,7 @@ interface Props {
modelValue?: undefined | Filter[] modelValue?: undefined | Filter[]
webHook?: boolean webHook?: boolean
draftFilter?: Partial<FilterType> draftFilter?: Partial<FilterType>
isOpen?: boolean
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
@ -27,6 +28,7 @@ const emit = defineEmits(['update:filtersLength', 'update:draftFilter', 'update:
const excludedFilterColUidt = [UITypes.QrCode, UITypes.Barcode] const excludedFilterColUidt = [UITypes.QrCode, UITypes.Barcode]
const draftFilter = useVModel(props, 'draftFilter', emit) const draftFilter = useVModel(props, 'draftFilter', emit)
const modelValue = useVModel(props, 'modelValue', emit) const modelValue = useVModel(props, 'modelValue', emit)
const { nestedLevel, parentId, autoSave, hookId, showLoading, webHook } = toRefs(props) const { nestedLevel, parentId, autoSave, hookId, showLoading, webHook } = toRefs(props)
@ -386,6 +388,15 @@ watch(
immediate: true, immediate: true,
}, },
) )
const addFilterBtnRef = ref()
watchEffect(() => {
if (props.isOpen && !nested.value && addFilterBtnRef.value) {
setTimeout(() => {
addFilterBtnRef.value?.$el?.focus()
}, 10)
}
})
</script> </script>
<template> <template>
@ -394,13 +405,63 @@ watch(
:class="{ :class="{
'max-h-[max(80vh,500px)] min-w-112 py-2 pl-4': !nested, 'max-h-[max(80vh,500px)] min-w-112 py-2 pl-4': !nested,
'w-full ': nested, 'w-full ': nested,
'py-4': !filters.length,
}" }"
> >
<div v-if="nested" class="flex w-full items-center mb-2">
<div :class="[`nc-filter-logical-op-level-${nestedLevel}`]"><slot name="start"></slot></div>
<div class="flex-grow"></div>
<NcDropdown :trigger="['hover']" overlay-class-name="nc-dropdown-filter-group-sub-menu">
<GeneralIcon icon="plus" class="cursor-pointer" />
<template #overlay>
<NcMenu>
<template v-if="isEeUI && !isPublic">
<template v-if="filtersCount < getPlanLimit(PlanLimitTypes.FILTER_LIMIT)">
<NcMenuItem @click.stop="addFilter()">
<div class="flex items-center gap-1">
<component :is="iconMap.plus" />
<!-- Add Filter -->
{{ $t('activity.addFilter') }}
</div>
</NcMenuItem>
<NcMenuItem v-if="nestedLevel < 5" @click.stop="addFilterGroup()">
<div class="flex items-center gap-1">
<!-- Add Filter Group -->
<component :is="iconMap.plusSquare" />
{{ $t('activity.addFilterGroup') }}
</div>
</NcMenuItem>
</template>
</template>
<template v-else>
<NcMenuItem @click.stop="addFilter()">
<div class="flex items-center gap-1">
<component :is="iconMap.plus" />
<!-- Add Filter -->
{{ $t('activity.addFilter') }}
</div>
</NcMenuItem>
<NcMenuItem v-if="!webHook && nestedLevel < 5" @click.stop="addFilterGroup()">
<div class="flex items-center gap-1">
<!-- Add Filter Group -->
<component :is="iconMap.plusSquare" />
{{ $t('activity.addFilterGroup') }}
</div>
</NcMenuItem>
</template>
</NcMenu>
</template>
</NcDropdown>
<div>
<slot name="end"></slot>
</div>
</div>
<div <div
v-if="filters && filters.length" v-if="filters && filters.length"
ref="wrapperDomRef" ref="wrapperDomRef"
class="flex flex-col gap-y-3 nc-filter-grid w-full" class="flex flex-col gap-y-1.5 nc-filter-grid w-full"
:class="{ 'max-h-420px nc-scrollbar-thin nc-filter-top-wrapper pr-4 my-2 py-1': !nested }" :class="{ 'max-h-420px nc-scrollbar-thin nc-filter-top-wrapper pr-4 my-2 py-1': !nested }"
@click.stop @click.stop
> >
@ -408,17 +469,29 @@ watch(
<template v-if="filter.status !== 'delete'"> <template v-if="filter.status !== 'delete'">
<template v-if="filter.is_group"> <template v-if="filter.is_group">
<div class="flex flex-col w-full gap-y-2"> <div class="flex flex-col w-full gap-y-2">
<div class="flex flex-row w-full justify-between items-center"> <div class="flex rounded-lg p-2 w-full border-1" :class="[`nc-filter-nested-level-${nestedLevel}`]">
<span v-if="!i" class="flex items-center ml-2">{{ $t('labels.where') }}</span> <LazySmartsheetToolbarColumnFilter
v-if="filter.id || filter.children || !autoSave"
:key="filter.id ?? i"
ref="localNestedFilters"
v-model="filter.children"
:nested-level="nestedLevel + 1"
:parent-id="filter.id"
:auto-save="autoSave"
:web-hook="webHook"
>
<template #start>
<span v-if="!i" class="flex items-center nc-filter-where-label ml-1">{{ $t('labels.where') }}</span>
<div v-else :key="`${i}nested`" class="flex nc-filter-logical-op"> <div v-else :key="`${i}nested`" class="flex nc-filter-logical-op">
<NcSelect <NcSelect
v-model:value="filter.logical_op" v-model:value="filter.logical_op"
v-e="['c:filter:logical-op:select']" v-e="['c:filter:logical-op:select']"
:dropdown-match-select-width="false" :dropdown-match-select-width="false"
class="min-w-20 capitalize" class="min-w-18 max-w-18 capitalize"
placeholder="Group op" placeholder="Group op"
dropdown-class-name="nc-dropdown-filter-logical-op-group" dropdown-class-name="nc-dropdown-filter-logical-op-group"
:disabled="visibleFilters.indexOf(filter) > 1 && !isLogicalOpChangeAllowed" :disabled="i > 1 && !isLogicalOpChangeAllowed"
:class="{ 'nc-disabled-logical-op': filter.readOnly || (i > 1 && !isLogicalOpChangeAllowed) }"
@click.stop @click.stop
@change="onLogicalOpUpdate(filter, i)" @change="onLogicalOpUpdate(filter, i)"
> >
@ -435,6 +508,8 @@ watch(
</a-select-option> </a-select-option>
</NcSelect> </NcSelect>
</div> </div>
</template>
<template #end>
<NcButton <NcButton
v-if="!filter.readOnly" v-if="!filter.readOnly"
:key="i" :key="i"
@ -446,33 +521,29 @@ watch(
> >
<component :is="iconMap.deleteListItem" /> <component :is="iconMap.deleteListItem" />
</NcButton> </NcButton>
</div> </template>
<div class="flex border-1 rounded-lg p-2 w-full" :class="nestedLevel % 2 !== 0 ? 'bg-white' : 'bg-gray-100'"> </LazySmartsheetToolbarColumnFilter>
<LazySmartsheetToolbarColumnFilter
v-if="filter.id || filter.children || !autoSave"
:key="filter.id ?? i"
ref="localNestedFilters"
v-model="filter.children"
:nested-level="nestedLevel + 1"
:parent-id="filter.id"
:auto-save="autoSave"
:web-hook="webHook"
/>
</div> </div>
</div> </div>
</template> </template>
<div v-else class="flex flex-row gap-x-2 w-full" :class="`nc-filter-wrapper-${filter.fk_column_id}`">
<span v-if="!i" class="flex items-center ml-2 mr-7.35">{{ $t('labels.where') }}</span> <div v-else class="flex flex-row gap-x-0 w-full nc-filter-wrapper" :class="`nc-filter-wrapper-${filter.fk_column_id}`">
<div v-if="!i" class="flex items-center !min-w-18 !max-w-18 pl-3 nc-filter-where-label">
{{ $t('labels.where') }}
</div>
<NcSelect <NcSelect
v-else v-else
v-model:value="filter.logical_op" v-model:value="filter.logical_op"
v-e="['c:filter:logical-op:select']" v-e="['c:filter:logical-op:select']"
:dropdown-match-select-width="false" :dropdown-match-select-width="false"
class="h-full !min-w-20 !max-w-20 capitalize" class="h-full !min-w-18 !max-w-18 capitalize"
hide-details hide-details
:disabled="filter.readOnly || (visibleFilters.indexOf(filter) > 1 && !isLogicalOpChangeAllowed)" :disabled="filter.readOnly || (visibleFilters.indexOf(filter) > 1 && !isLogicalOpChangeAllowed)"
dropdown-class-name="nc-dropdown-filter-logical-op" dropdown-class-name="nc-dropdown-filter-logical-op"
:class="{
'nc-disabled-logical-op': filter.readOnly || (visibleFilters.indexOf(filter) > 1 && !isLogicalOpChangeAllowed),
}"
@change="onLogicalOpUpdate(filter, i)" @change="onLogicalOpUpdate(filter, i)"
@click.stop @click.stop
> >
@ -488,6 +559,7 @@ watch(
</div> </div>
</a-select-option> </a-select-option>
</NcSelect> </NcSelect>
<SmartsheetToolbarFieldListAutoCompleteDropdown <SmartsheetToolbarFieldListAutoCompleteDropdown
:key="`${i}_6`" :key="`${i}_6`"
v-model="filter.fk_column_id" v-model="filter.fk_column_id"
@ -497,6 +569,7 @@ watch(
@click.stop @click.stop
@change="selectFilterField(filter, i)" @change="selectFilterField(filter, i)"
/> />
<NcSelect <NcSelect
v-model:value="filter.comparison_op" v-model:value="filter.comparison_op"
v-e="['c:filter:comparison-op:select']" v-e="['c:filter:comparison-op:select']"
@ -529,6 +602,7 @@ watch(
</NcSelect> </NcSelect>
<div v-if="['blank', 'notblank'].includes(filter.comparison_op)" class="flex flex-grow"></div> <div v-if="['blank', 'notblank'].includes(filter.comparison_op)" class="flex flex-grow"></div>
<NcSelect <NcSelect
v-else-if="isDateType(types[filter.fk_column_id])" v-else-if="isDateType(types[filter.fk_column_id])"
v-model:value="filter.comparison_sub_op" v-model:value="filter.comparison_sub_op"
@ -567,6 +641,7 @@ watch(
</a-select-option> </a-select-option>
</template> </template>
</NcSelect> </NcSelect>
<a-checkbox <a-checkbox
v-if="filter.field && types[filter.field] === 'boolean'" v-if="filter.field && types[filter.field] === 'boolean'"
v-model:checked="filter.value" v-model:checked="filter.value"
@ -583,6 +658,7 @@ watch(
@update-filter-value="(value) => updateFilterValue(value, filter, i)" @update-filter-value="(value) => updateFilterValue(value, filter, i)"
@click.stop @click.stop
/> />
<div v-else-if="!isDateType(types[filter.fk_column_id])" class="flex-grow"></div> <div v-else-if="!isDateType(types[filter.fk_column_id])" class="flex-grow"></div>
<NcButton <NcButton
@ -600,16 +676,16 @@ watch(
</template> </template>
</div> </div>
<template v-if="!nested">
<template v-if="isEeUI && !isPublic"> <template v-if="isEeUI && !isPublic">
<div <div
v-if="filtersCount < getPlanLimit(PlanLimitTypes.FILTER_LIMIT)" v-if="filtersCount < getPlanLimit(PlanLimitTypes.FILTER_LIMIT)"
ref="addFiltersRowDomRef"
class="flex gap-2" class="flex gap-2"
:class="{ :class="{
'mt-1 mb-2': filters.length, 'mt-1 mb-2': filters.length,
}" }"
> >
<NcButton size="small" type="text" class="!text-brand-500" @click.stop="addFilter()"> <NcButton :ref="addFilterBtnRef" size="small" type="text" class="nc-btn-focus" @click.stop="addFilter()">
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
<component :is="iconMap.plus" /> <component :is="iconMap.plus" />
<!-- Add Filter --> <!-- Add Filter -->
@ -617,7 +693,7 @@ watch(
</div> </div>
</NcButton> </NcButton>
<NcButton v-if="nestedLevel < 5" type="text" size="small" @click.stop="addFilterGroup()"> <NcButton v-if="nestedLevel < 5" class="nc-btn-focus" type="text" size="small" @click.stop="addFilterGroup()">
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
<!-- Add Filter Group --> <!-- Add Filter Group -->
<component :is="iconMap.plus" /> <component :is="iconMap.plus" />
@ -626,6 +702,7 @@ watch(
</NcButton> </NcButton>
</div> </div>
</template> </template>
<template v-else> <template v-else>
<div <div
ref="addFiltersRowDomRef" ref="addFiltersRowDomRef"
@ -634,7 +711,7 @@ watch(
'mt-1 mb-2': filters.length, 'mt-1 mb-2': filters.length,
}" }"
> >
<NcButton size="small" type="text" class="!text-brand-500" @click.stop="addFilter()"> <NcButton ref="addFilterBtnRef" class="nc-btn-focus" size="small" type="text" @click.stop="addFilter()">
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
<component :is="iconMap.plus" /> <component :is="iconMap.plus" />
<!-- Add Filter --> <!-- Add Filter -->
@ -642,7 +719,13 @@ watch(
</div> </div>
</NcButton> </NcButton>
<NcButton v-if="!webHook && nestedLevel < 5" type="text" size="small" @click.stop="addFilterGroup()"> <NcButton
v-if="!webHook && nestedLevel < 5"
class="nc-btn-focus"
type="text"
size="small"
@click.stop="addFilterGroup()"
>
<div class="flex items-center gap-1"> <div class="flex items-center gap-1">
<!-- Add Filter Group --> <!-- Add Filter Group -->
<component :is="iconMap.plus" /> <component :is="iconMap.plus" />
@ -651,6 +734,7 @@ watch(
</NcButton> </NcButton>
</div> </div>
</template> </template>
</template>
<div <div
v-if="!filters.length" v-if="!filters.length"
class="flex flex-row text-gray-400 mt-2" class="flex flex-row text-gray-400 mt-2"
@ -666,7 +750,7 @@ watch(
</div> </div>
</template> </template>
<style scoped> <style scoped lang="scss">
.nc-filter-item-remove-btn { .nc-filter-item-remove-btn {
@apply text-gray-600 hover:text-gray-800; @apply text-gray-600 hover:text-gray-800;
} }
@ -680,6 +764,112 @@ watch(
} }
:deep(.ant-select-selector) { :deep(.ant-select-selector) {
@apply !min-h-8.25; @apply !min-h-8;
}
.nc-disabled-logical-op :deep(.ant-select-arrow) {
@apply hidden;
}
.nc-filter-wrapper {
@apply bg-white !rounded-lg border-1px border-[#E7E7E9];
& > * {
@apply !border-none;
}
& > * > :deep(.ant-select-selector) {
border: none !important;
box-shadow: none !important;
}
& > :not(:last-child):not(:empty) {
border-right: 1px solid #eee !important;
border-bottom-right-radius: 0 !important;
border-top-right-radius: 0 !important;
}
& > :not(:first-child) {
border-bottom-left-radius: 0 !important;
border-top-left-radius: 0 !important;
}
& > :last-child {
@apply relative;
&::after {
content: '';
@apply absolute h-full w-1px bg-[#eee] -left-1px top-0;
}
}
:deep(::placeholder) {
@apply text-sm tracking-normal;
}
:deep(::-ms-input-placeholder) {
@apply text-sm tracking-normal;
}
:deep(input) {
@apply text-sm;
}
:deep(.nc-select:not(.nc-disabled-logical-op):hover) {
&,
.ant-select-selector {
@apply bg-gray-50;
}
}
}
.nc-filter-nested-level-0 {
@apply bg-[#f9f9fa];
}
.nc-filter-nested-level-1,
.nc-filter-nested-level-3 {
@apply bg-gray-[#f4f4f5];
}
.nc-filter-nested-level-2,
.nc-filter-nested-level-4 {
@apply bg-gray-[#e7e7e9];
}
.nc-filter-logical-op-level-3,
.nc-filter-logical-op-level-5 {
:deep(.nc-select.ant-select .ant-select-selector) {
@apply border-[#d9d9d9];
}
}
.nc-filter-where-label {
@apply text-gray-400;
}
:deep(.ant-select-disabled.ant-select:not(.ant-select-customize-input) .ant-select-selector) {
@apply bg-transparent text-gray-400;
}
:deep(.nc-filter-logical-op .nc-select.ant-select .ant-select-selector) {
@apply shadow-none;
}
:deep(.nc-select-expand-btn) {
@apply text-gray-500;
}
.menu-filter-dropdown {
input:not(:disabled),
select:not(:disabled),
.ant-select:not(.ant-select-disabled) {
@apply text-[#4A5268];
}
}
.nc-filter-input-wrapper :deep(input) {
@apply !px-2;
}
.nc-btn-focus:focus {
@apply !text-brand-500 !shadow-none;
} }
</style> </style>

1
packages/nc-gui/components/smartsheet/toolbar/ColumnFilterMenu.vue

@ -86,6 +86,7 @@ eventBus.on(async (event, column: ColumnType) => {
:auto-save="true" :auto-save="true"
data-testid="nc-filter-menu" data-testid="nc-filter-menu"
@update:filters-length="filtersLength = $event" @update:filters-length="filtersLength = $event"
:is-open="open"
> >
</SmartsheetToolbarColumnFilter> </SmartsheetToolbarColumnFilter>
</template> </template>

9
packages/nc-gui/components/smartsheet/toolbar/FieldListAutoCompleteDropdown.vue

@ -63,14 +63,15 @@ const options = computed<SelectProps['options']>(() =>
return !isVirtualSystemField return !isVirtualSystemField
} }
}) })
)?.map((c: ColumnType) => ({ )
// sort and keep system columns at the end
?.sort((field1, field2) => +isSystemColumn(field2) - +isSystemColumn(field1))
?.map((c: ColumnType) => ({
value: c.id, value: c.id,
label: c.title, label: c.title,
icon: h( icon: h(
isVirtualCol(c) ? resolveComponent('SmartsheetHeaderVirtualCellIcon') : resolveComponent('SmartsheetHeaderCellIcon'), isVirtualCol(c) ? resolveComponent('SmartsheetHeaderVirtualCellIcon') : resolveComponent('SmartsheetHeaderCellIcon'),
{ { columnMeta: c },
columnMeta: c,
},
), ),
c, c,
})), })),

11
packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue

@ -11,8 +11,6 @@ const reloadViewMetaHook = inject(ReloadViewMetaHookInj, undefined)!
const reloadViewDataHook = inject(ReloadViewDataHookInj, undefined)! const reloadViewDataHook = inject(ReloadViewDataHookInj, undefined)!
const rootFields = inject(FieldsInj)
const { isMobileMode } = useGlobal() const { isMobileMode } = useGlobal()
const isLocked = inject(IsLockedInj, ref(false)) const isLocked = inject(IsLockedInj, ref(false))
@ -23,7 +21,6 @@ const { $api, $e } = useNuxtApp()
const { const {
showSystemFields, showSystemFields,
sortedAndFilteredFields,
fields, fields,
filteredFieldList, filteredFieldList,
filterQuery, filterQuery,
@ -48,14 +45,6 @@ eventBus.on((event) => {
} }
}) })
watch(
sortedAndFilteredFields,
(v) => {
if (rootFields) rootFields.value = v || []
},
{ immediate: true },
)
const numberOfHiddenFields = computed(() => filteredFieldList.value?.filter((field) => !field.show)?.length) const numberOfHiddenFields = computed(() => filteredFieldList.value?.filter((field) => !field.show)?.length)
const gridDisplayValueField = computed(() => { const gridDisplayValueField = computed(() => {

4
packages/nc-gui/components/tabs/Smartsheet.vue

@ -16,8 +16,6 @@ useSidebar('nc-right-sidebar')
const activeTab = toRef(props, 'activeTab') const activeTab = toRef(props, 'activeTab')
const fields = ref<ColumnType[]>([])
const route = useRoute() const route = useRoute()
const meta = computed<TableType | undefined>(() => { const meta = computed<TableType | undefined>(() => {
@ -50,7 +48,6 @@ provide(IsLockedInj, isLocked)
provide(ReloadViewDataHookInj, reloadViewDataEventHook) provide(ReloadViewDataHookInj, reloadViewDataEventHook)
provide(ReloadViewMetaHookInj, reloadViewMetaEventHook) provide(ReloadViewMetaHookInj, reloadViewMetaEventHook)
provide(OpenNewRecordFormHookInj, openNewRecordFormHook) provide(OpenNewRecordFormHookInj, openNewRecordFormHook)
provide(FieldsInj, fields)
provide(IsFormInj, isForm) provide(IsFormInj, isForm)
provide(TabMetaInj, activeTab) provide(TabMetaInj, activeTab)
provide( provide(
@ -60,6 +57,7 @@ provide(
useExpandedFormDetachedProvider() useExpandedFormDetachedProvider()
useProvideViewColumns(activeView, meta, () => reloadViewDataEventHook?.trigger()) useProvideViewColumns(activeView, meta, () => reloadViewDataEventHook?.trigger())
useProvideViewGroupBy(activeView, meta, xWhere) useProvideViewGroupBy(activeView, meta, xWhere)
useProvideSmartsheetLtarHelpers(meta) useProvideSmartsheetLtarHelpers(meta)

14
packages/nc-gui/composables/useViewColumns.ts

@ -6,9 +6,11 @@ const [useProvideViewColumns, useViewColumns] = useInjectionState(
( (
view: Ref<ViewType | undefined>, view: Ref<ViewType | undefined>,
meta: Ref<TableType | undefined> | ComputedRef<TableType | undefined>, meta: Ref<TableType | undefined> | ComputedRef<TableType | undefined>,
reloadData?: () => void, reloadData?: (params?: { shouldShowLoading?: boolean }) => void,
isPublic = false, isPublic = false,
) => { ) => {
const rootFields = ref<ColumnType[]>([])
const fields = ref<Field[]>() const fields = ref<Field[]>()
const filterQuery = ref('') const filterQuery = ref('')
@ -356,6 +358,16 @@ const [useProvideViewColumns, useViewColumns] = useInjectionState(
} }
} }
watch(
sortedAndFilteredFields,
(v) => {
if (rootFields) rootFields.value = v || []
},
{ immediate: true },
)
provide(FieldsInj, rootFields)
return { return {
fields, fields,
loadViewColumns, loadViewColumns,

2
packages/nc-gui/composables/useViewFilters.ts

@ -188,7 +188,7 @@ export function useViewFilters(
comparison_op: comparisonOpList(options.value?.[0].uidt as UITypes).filter((compOp) => comparison_op: comparisonOpList(options.value?.[0].uidt as UITypes).filter((compOp) =>
isComparisonOpAllowed({ fk_column_id: options.value?.[0].id }, compOp), isComparisonOpAllowed({ fk_column_id: options.value?.[0].id }, compOp),
)?.[0].value as FilterType['comparison_op'], )?.[0].value as FilterType['comparison_op'],
value: '', value: null,
status: 'create', status: 'create',
logical_op: logicalOps.size === 1 ? logicalOps.values().next().value : 'and', logical_op: logicalOps.size === 1 ? logicalOps.values().next().value : 'and',
} }

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

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "اسم الجدول", "tableName": "اسم الجدول",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty", "parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed", "duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "{value} cannot be empty.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project not accessible", "projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Failed to copy to clipboard", "copyToClipboardError": "Failed to copy to clipboard",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/bn_IN.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Table name", "tableName": "Table name",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty", "parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed", "duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "{value} cannot be empty.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project not accessible", "projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Failed to copy to clipboard", "copyToClipboardError": "Failed to copy to clipboard",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

5
packages/nc-gui/lang/cs.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Akceptované typy souborů jsou .xls, .xlsx, .xlsm, .ods, .ots.", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Akceptované typy souborů jsou .xls, .xlsx, .xlsm, .ods, .ots.",
"parameterKeyCannotBeEmpty": "Klíč parametru nesmí být prázdný", "parameterKeyCannotBeEmpty": "Klíč parametru nesmí být prázdný",
"duplicateParameterKeysAreNotAllowed": "Duplicitní klíče parametrů nejsou povoleny", "duplicateParameterKeysAreNotAllowed": "Duplicitní klíče parametrů nejsou povoleny",
"fieldRequired": "{value} nemůže být prázdný.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Projekt není přístupný", "projectNotAccessible": "Projekt není přístupný",
"copyToClipboardError": "Nepodařilo se zkopírovat do schránky", "copyToClipboardError": "Nepodařilo se zkopírovat do schránky",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/da.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Tabelnavn.", "tableName": "Tabelnavn.",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "De accepterede filtyper er .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "De accepterede filtyper er .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameternøglen kan ikke være tom", "parameterKeyCannotBeEmpty": "Parameternøglen kan ikke være tom",
"duplicateParameterKeysAreNotAllowed": "Det er ikke tilladt at duplikere parameternøgler", "duplicateParameterKeysAreNotAllowed": "Det er ikke tilladt at duplikere parameternøgler",
"fieldRequired": "{value} kan ikke være tom.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Projektet er ikke tilgængeligt", "projectNotAccessible": "Projektet er ikke tilgængeligt",
"copyToClipboardError": "Kopiering til udklipsholderen mislykkedes", "copyToClipboardError": "Kopiering til udklipsholderen mislykkedes",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/de.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Tabellenname", "tableName": "Tabellenname",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Neue Ansicht erstellen", "createView": "Ansicht erstellen",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Die akzeptierten Dateitypen sind .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Die akzeptierten Dateitypen sind .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameterschlüssel darf nicht leer sein", "parameterKeyCannotBeEmpty": "Parameterschlüssel darf nicht leer sein",
"duplicateParameterKeysAreNotAllowed": "Doppelte Parameterschlüssel sind nicht erlaubt", "duplicateParameterKeysAreNotAllowed": "Doppelte Parameterschlüssel sind nicht erlaubt",
"fieldRequired": "{value} kann nicht leer sein.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Projekt nicht zugänglich", "projectNotAccessible": "Projekt nicht zugänglich",
"copyToClipboardError": "Kopieren in die Zwischenablage fehlgeschlagen", "copyToClipboardError": "Kopieren in die Zwischenablage fehlgeschlagen",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

12
packages/nc-gui/lang/en.json

@ -589,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Table name", "tableName": "Table name",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create view", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -756,7 +756,7 @@
"selectField": "Select a field", "selectField": "Select a field",
"selectFieldLabel": "Make changes to field properties by selecting a field from the list" "selectFieldLabel": "Make changes to field properties by selecting a field from the list"
}, },
"appearanceSettings": "Appearance settings", "appearanceSettings": "Appearance Settings",
"backgroundColor": "Background Color", "backgroundColor": "Background Color",
"hideNocodbBranding": "Hide NocoDB Branding", "hideNocodbBranding": "Hide NocoDB Branding",
"showOnConditions": "Show on condtions", "showOnConditions": "Show on condtions",
@ -919,7 +919,7 @@
"clearMetadata": "Clear Metadata", "clearMetadata": "Clear Metadata",
"exportToFile": "Export to file", "exportToFile": "Export to file",
"changePwd": "Change Password", "changePwd": "Change Password",
"createView": "Create a View", "createView": "Create View",
"shareView": "Share View", "shareView": "Share View",
"findRowByCodeScan": "Find record by scan", "findRowByCodeScan": "Find record by scan",
"fillByCodeScan": "Fill by scan", "fillByCodeScan": "Fill by scan",
@ -1015,7 +1015,7 @@
"group": "Group" "group": "Group"
}, },
"tooltip": { "tooltip": {
"reachedSourceLimit": "Limited to 10 data sources per base", "reachedSourceLimit": "Limited to only one data source for the moment",
"saveChanges": "Save changes", "saveChanges": "Save changes",
"xcDB": "Create a new base", "xcDB": "Create a new base",
"extDB": "Supports MySQL, PostgreSQL, SQL Server & SQLite", "extDB": "Supports MySQL, PostgreSQL, SQL Server & SQLite",
@ -1286,7 +1286,7 @@
"afterEnablePwd": "Access is password restricted", "afterEnablePwd": "Access is password restricted",
"privateLink": "This view is shared via a private link", "privateLink": "This view is shared via a private link",
"privateLinkAdditionalInfo": "People with private link can only see cells visible in this view", "privateLinkAdditionalInfo": "People with private link can only see cells visible in this view",
"postFormSubmissionSettings": "Post form submission settings", "postFormSubmissionSettings": "Post Form Submission Settings",
"apiOptions": "Access Base via", "apiOptions": "Access Base via",
"submitAnotherForm": "Show 'Submit Another Form' button", "submitAnotherForm": "Show 'Submit Another Form' button",
"showBlankForm": "Show a blank form after 5 seconds", "showBlankForm": "Show a blank form after 5 seconds",
@ -1498,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty", "parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed", "duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "This field cannot be empty.", "fieldRequired": "{value} cannot be empty.",
"projectNotAccessible": "Base not accessible", "projectNotAccessible": "Base not accessible",
"copyToClipboardError": "Failed to copy to clipboard", "copyToClipboardError": "Failed to copy to clipboard",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

11
packages/nc-gui/lang/es.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Token sin título", "untitledToken": "Token sin título",
"tableName": "Nombre de la tabla", "tableName": "Nombre de la tabla",
"dashboardName": "Nombre del panel", "dashboardName": "Nombre del panel",
"createView": "Crear una vista", "createView": "Crear Vista",
"creatingView": "Creando Vista", "creatingView": "Creando Vista",
"duplicateView": "Duplicar vista", "duplicateView": "Duplicar vista",
"duplicateGridView": "Duplicar vista en cuadrcula", "duplicateGridView": "Duplicar vista en cuadrcula",
@ -917,7 +919,7 @@
"clearMetadata": "Limpiar metadatos", "clearMetadata": "Limpiar metadatos",
"exportToFile": "Exportar a archivo", "exportToFile": "Exportar a archivo",
"changePwd": "Cambia la contraseña", "changePwd": "Cambia la contraseña",
"createView": "Crear una Vista", "createView": "Crear vista",
"shareView": "Compartir vista", "shareView": "Compartir vista",
"findRowByCodeScan": "Find row by scan", "findRowByCodeScan": "Find row by scan",
"fillByCodeScan": "Rellenar por escaneo", "fillByCodeScan": "Rellenar por escaneo",
@ -1013,7 +1015,7 @@
"group": "Group" "group": "Group"
}, },
"tooltip": { "tooltip": {
"reachedSourceLimit": "Limited to 10 data sources per base", "reachedSourceLimit": "Limitado a una única fuente de datos por el momento",
"saveChanges": "Guardar cambios", "saveChanges": "Guardar cambios",
"xcDB": "Crear un nuevo proyecto", "xcDB": "Crear un nuevo proyecto",
"extDB": "Soporta MySQL, PostgreSQL, SQL Server y SQLite", "extDB": "Soporta MySQL, PostgreSQL, SQL Server y SQLite",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Los tipos de archivo aceptados son .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Los tipos de archivo aceptados son .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "La clave del parámetro no puede estar vacía", "parameterKeyCannotBeEmpty": "La clave del parámetro no puede estar vacía",
"duplicateParameterKeysAreNotAllowed": "No se permiten claves de parámetros duplicadas", "duplicateParameterKeysAreNotAllowed": "No se permiten claves de parámetros duplicadas",
"fieldRequired": "{value} no puede estar vacía.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Proyecto no accesible", "projectNotAccessible": "Proyecto no accesible",
"copyToClipboardError": "Fallo al copiar al portapapeles", "copyToClipboardError": "Fallo al copiar al portapapeles",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

9
packages/nc-gui/lang/eu.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Taularen izena", "tableName": "Taularen izena",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -917,7 +919,7 @@
"clearMetadata": "Clear Metadata", "clearMetadata": "Clear Metadata",
"exportToFile": "Export to file", "exportToFile": "Export to file",
"changePwd": "Change Password", "changePwd": "Change Password",
"createView": "Create a View", "createView": "Create View",
"shareView": "Share View", "shareView": "Share View",
"findRowByCodeScan": "Find row by scan", "findRowByCodeScan": "Find row by scan",
"fillByCodeScan": "Fill by scan", "fillByCodeScan": "Fill by scan",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty", "parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed", "duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "{value} cannot be empty.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project not accessible", "projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Failed to copy to clipboard", "copyToClipboardError": "Failed to copy to clipboard",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/fa.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "نام جدول", "tableName": "نام جدول",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "نوع فایل های مورد قبول .xls, .xlsx, .xlm, .ods, .ots هستند", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "نوع فایل های مورد قبول .xls, .xlsx, .xlm, .ods, .ots هستند",
"parameterKeyCannotBeEmpty": "کلید پارامتر نمیتواند خالی باشد", "parameterKeyCannotBeEmpty": "کلید پارامتر نمیتواند خالی باشد",
"duplicateParameterKeysAreNotAllowed": "کلید های پارامتر تکراری مجاز نیستند", "duplicateParameterKeysAreNotAllowed": "کلید های پارامتر تکراری مجاز نیستند",
"fieldRequired": "{value} نمیتواند خالی باشد.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project not accessible", "projectNotAccessible": "Project not accessible",
"copyToClipboardError": "کپی به کلیپ برد ناموفق", "copyToClipboardError": "کپی به کلیپ برد ناموفق",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/fi.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Taulukon nimi", "tableName": "Taulukon nimi",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Hyväksytyt tiedostotyypit ovat .xls, .xlsx, .xlsm, .ods, .ots ja .xlsx.", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Hyväksytyt tiedostotyypit ovat .xls, .xlsx, .xlsm, .ods, .ots ja .xlsx.",
"parameterKeyCannotBeEmpty": "Parametriavain ei voi olla tyhjä", "parameterKeyCannotBeEmpty": "Parametriavain ei voi olla tyhjä",
"duplicateParameterKeysAreNotAllowed": "Parametrin kaksoisavaimet eivät ole sallittuja", "duplicateParameterKeysAreNotAllowed": "Parametrin kaksoisavaimet eivät ole sallittuja",
"fieldRequired": "{value} ei voi olla tyhjä.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Hankkeeseen ei pääse käsiksi", "projectNotAccessible": "Hankkeeseen ei pääse käsiksi",
"copyToClipboardError": "Kopiointi leikepöydälle epäonnistui", "copyToClipboardError": "Kopiointi leikepöydälle epäonnistui",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

351
packages/nc-gui/lang/fr.json

@ -10,7 +10,7 @@
"connect": "Connecter", "connect": "Connecter",
"buttonActionTypes": { "buttonActionTypes": {
"open_external_url": "Ouvrir le lien externe", "open_external_url": "Ouvrir le lien externe",
"delete_record": "Supprimer la ligne", "delete_record": "Supprimer l'enregistrement",
"update_record": "Mettre à jour l'enregistrement", "update_record": "Mettre à jour l'enregistrement",
"open_layout": "Ouvrir la mise en page" "open_layout": "Ouvrir la mise en page"
}, },
@ -39,7 +39,7 @@
} }
}, },
"general": { "general": {
"role": "Role", "role": "Rôle",
"general": "Général", "general": "Général",
"quit": "Quitter", "quit": "Quitter",
"home": "Accueil", "home": "Accueil",
@ -197,7 +197,7 @@
"paste": "Coller", "paste": "Coller",
"restore": "Restaurer", "restore": "Restaurer",
"replace": "Remplacer", "replace": "Remplacer",
"banner": "Banner", "banner": "Bandeau",
"logo": "Logo", "logo": "Logo",
"dropdown": "Liste déroulante", "dropdown": "Liste déroulante",
"list": "Liste", "list": "Liste",
@ -293,7 +293,7 @@
"Formula": "Formule", "Formula": "Formule",
"Rollup": "Synthèse", "Rollup": "Synthèse",
"Count": "Compteur", "Count": "Compteur",
"Lookup": "Consulter", "Lookup": "Lookup",
"DateTime": "Date et heure", "DateTime": "Date et heure",
"CreatedTime": "Date de création", "CreatedTime": "Date de création",
"LastModifiedTime": "Dernière modification", "LastModifiedTime": "Dernière modification",
@ -320,9 +320,9 @@
"isNotNull": "est non null" "isNotNull": "est non null"
}, },
"title": { "title": {
"renameBase": "Rename Base", "renameBase": "Renommer la Base",
"renameWorkspace": "Renommer l'espace de travail", "renameWorkspace": "Renommer l'espace de travail",
"renamingWorkspace": "Renaming Workspace", "renamingWorkspace": "Renommer l'espace de travail",
"renamingBase": "Renommer la Base", "renamingBase": "Renommer la Base",
"sso": "Authentification (SSO)", "sso": "Authentification (SSO)",
"docs": "Documents", "docs": "Documents",
@ -354,7 +354,7 @@
"manyToMany": "Plusieurs à plusieurs", "manyToMany": "Plusieurs à plusieurs",
"oneToOne": "Un à un", "oneToOne": "Un à un",
"virtualRelation": "Virtual Relation", "virtualRelation": "Virtual Relation",
"linkMore": "Link More", "linkMore": "Lier plus",
"linkMoreRecords": "Lier plus d'enregistrements", "linkMoreRecords": "Lier plus d'enregistrements",
"linkRecords": "Lier les enregistrements", "linkRecords": "Lier les enregistrements",
"downloadFile": "Télécharger le fichier", "downloadFile": "Télécharger le fichier",
@ -378,7 +378,7 @@
"formTitle": "Intitulé du formulaire", "formTitle": "Intitulé du formulaire",
"collaborative": "Collaboratif", "collaborative": "Collaboratif",
"locked": "Verrouillé", "locked": "Verrouillé",
"personal": "Personal", "personal": "Personnels",
"appStore": "Magasin d'applications", "appStore": "Magasin d'applications",
"teamAndAuth": "Équipe & Authentification", "teamAndAuth": "Équipe & Authentification",
"rolesUserMgmt": "Gestion des utilisateurs & rôles", "rolesUserMgmt": "Gestion des utilisateurs & rôles",
@ -436,54 +436,56 @@
"switchLanguage": "Changer de langue", "switchLanguage": "Changer de langue",
"renameFile": "Renommer le fichier", "renameFile": "Renommer le fichier",
"links": { "links": {
"noAction": "No Action", "noAction": "Aucune action",
"cascade": "Cascade", "cascade": "Cascade",
"restrict": "Restrict", "restrict": "Restreindre",
"setNull": "Définir NULL", "setNull": "Définir NULL",
"setDefault": "Définir à la valeur par défaut" "setDefault": "Définir à la valeur par défaut"
}, },
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here", "selectFieldsFromRightPannelToAddHere": "Sélectionnez les champs du panneau de droite à ajouter ici",
"noOptionsFound": "No options found", "noOptionsFound": "Aucune option trouvée",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?", "surveyFormSubmitConfirmMsg": "Êtes-vous sûr de vouloir envoyer ce formulaire ?",
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"today": "Today", "connectionDetails": "Connection Details",
"workspace": "Workspace", "metaSync": "Meta Sync",
"today": "Aujourd'hui",
"workspace": "Espace de travail",
"txt": "TXT Record value", "txt": "TXT Record value",
"transferOwnership": "Transfer Ownership", "transferOwnership": "Définir un nouveau propriétaire",
"recentActivity": "Recent Activity", "recentActivity": "Activité récente",
"goToMembers": "Go to Members", "goToMembers": "Aller aux membres",
"addMember": "Ajouter un membre", "addMember": "Ajouter un membre",
"numberOfMembers": "No. Members", "numberOfMembers": "Nombre de membres",
"numberOfBases": "No. Bases", "numberOfBases": "Nombre de bases",
"numberOfRecords": "No. Records", "numberOfRecords": "Nombre d'enregistrements",
"workspaceName": "Workspace Name", "workspaceName": "Nom de l'espace de travail",
"workspaceWithoutOwner": "Workspace without Owners", "workspaceWithoutOwner": "Espace de travail sans propriétaire",
"inviteUsersToWorkspace": "Invite Users to Workspace", "inviteUsersToWorkspace": "Inviter des utilisateurs à l'espace de travail",
"selectWorkspace": "-select workspaces to invite to-", "selectWorkspace": "-select workspaces to invite to-",
"addMembersToOrganization": "Ajouter des membres à l'organisation", "addMembersToOrganization": "Ajouter des membres à l'organisation",
"memberIn": "Member in:", "memberIn": "Member in:",
"assignAs": "Assign as", "assignAs": "Assign as",
"signOutUser": "Sign out user", "signOutUser": "Déconnecter l'utilisateur",
"signOutUsers": "Sign out users", "signOutUsers": "Déconnecter les utilisateurs",
"deactivateUser": "Deactivate User", "deactivateUser": "Désactiver l'utilisateur",
"deactivateUsers": "Deactivate Users", "deactivateUsers": "Désactiver les utilisateurs",
"lastActive": "Last Active", "lastActive": "Last Active",
"dateAdded": "Date ajoutée", "dateAdded": "Date ajoutée",
"uploadImage": "Upload Image", "uploadImage": "Charger une image",
"organizationProfile": "Organisation Profile", "organizationProfile": "Profil de l'organisation",
"organizationImage": "Organisation Image", "organizationImage": "Image de l'organisation",
"organizationName": "Organisation Name", "organizationName": "Nom de l'organisation",
"activeDomains": "Active Domains", "activeDomains": "Active Domains",
"domains": "Domains", "domains": "Domains",
"disablePublicSharing": "Disable Public Sharing", "disablePublicSharing": "Désactiver le partage public",
"shareSettings": "Share Settings", "shareSettings": "Partager les paramètres",
"deleteUserAndData": "Delete User and their data", "deleteUserAndData": "Supprimer l'utilisateur et ses données",
"userOptions": "User Options", "userOptions": "Options de l'utilisateur",
"deleteThisOrganization": "Delete this Organisation", "deleteThisOrganization": "Supprimer cette organisation",
"dangerZone": "Dangerzone", "dangerZone": "Dangerzone",
"selectYear": "Select Year", "selectYear": "Sélectionnez une Année",
"save": "Enregistrer", "save": "Enregistrer",
"cancel": "Annuler", "cancel": "Annuler",
"metadataUrl": "URL des métadonnées", "metadataUrl": "URL des métadonnées",
@ -496,13 +498,13 @@
"adminPanel": "Panneau d'administration", "adminPanel": "Panneau d'administration",
"moveWorkspaceToOrg": "Déplacer l'espace de travail vers l'organisation", "moveWorkspaceToOrg": "Déplacer l'espace de travail vers l'organisation",
"ssoSettings": "Paramètres SSO", "ssoSettings": "Paramètres SSO",
"addDomain": "Add Domain", "addDomain": "Ajouter le domaine",
"domain": "Domain", "domain": "Domaine",
"settings": "Réglages", "settings": "Réglages",
"workspaces": "Espaces de travail", "workspaces": "Espaces de travail",
"back": "Précédent", "back": "Précédent",
"dashboard": "Tableau de bord", "dashboard": "Tableau de bord",
"organizeBy": "Organize by", "organizeBy": "Organiser en fonction de",
"previous": "Précédent", "previous": "Précédent",
"nextMonth": "Mois suivant", "nextMonth": "Mois suivant",
"previousMonth": "Mois précédent", "previousMonth": "Mois précédent",
@ -587,7 +589,7 @@
"untitledToken": "Jeton sans titre", "untitledToken": "Jeton sans titre",
"tableName": "Nom du tableau", "tableName": "Nom du tableau",
"dashboardName": "Nom du tableau de bord", "dashboardName": "Nom du tableau de bord",
"createView": "Créer une vue", "createView": "Créer vue",
"creatingView": "Création de la vue", "creatingView": "Création de la vue",
"duplicateView": "Dupliquer la vue", "duplicateView": "Dupliquer la vue",
"duplicateGridView": "Dupliquer la vue Grille", "duplicateGridView": "Dupliquer la vue Grille",
@ -717,7 +719,7 @@
"hasMany": "a plusieurs", "hasMany": "a plusieurs",
"belongsTo": "appartient à", "belongsTo": "appartient à",
"manyToMany": "ont des relations nombreuses et variées", "manyToMany": "ont des relations nombreuses et variées",
"oneToOne": "have one to one relation", "oneToOne": "a une relation 1-1",
"extraConnectionParameters": "Paramètres de connexion supplémentaires", "extraConnectionParameters": "Paramètres de connexion supplémentaires",
"commentsOnly": "Commentaires uniquement", "commentsOnly": "Commentaires uniquement",
"documentation": "Documentation", "documentation": "Documentation",
@ -738,7 +740,7 @@
"includeView": "Inclure la vue", "includeView": "Inclure la vue",
"includeWebhook": "Inclure le Webhook", "includeWebhook": "Inclure le Webhook",
"zoomInToViewColumns": "Zoom in to view columns", "zoomInToViewColumns": "Zoom in to view columns",
"embedInSite": "Embed this view in your site", "embedInSite": "Intégrer cette vue dans votre site",
"titleRequired": "le titre est obligatoire.", "titleRequired": "le titre est obligatoire.",
"sourceNameRequired": "Le nom de la source est obligatoire", "sourceNameRequired": "Le nom de la source est obligatoire",
"changeWsName": "Changer le nom de l'espace de travail", "changeWsName": "Changer le nom de l'espace de travail",
@ -750,7 +752,7 @@
"saveChanges": "Enregistrer les modifications", "saveChanges": "Enregistrer les modifications",
"updatedField": "Champ mis à jour", "updatedField": "Champ mis à jour",
"deletedField": "Champ supprimé", "deletedField": "Champ supprimé",
"incompleteConfiguration": "Incomplete configuration", "incompleteConfiguration": "Configuration incomplète",
"selectField": "Sélectionner un champ", "selectField": "Sélectionner un champ",
"selectFieldLabel": "Begin by selecting a field to customise its properties and structure." "selectFieldLabel": "Begin by selecting a field to customise its properties and structure."
}, },
@ -758,8 +760,8 @@
"backgroundColor": "Couleur d'arrière-plan", "backgroundColor": "Couleur d'arrière-plan",
"hideNocodbBranding": "Masquer la marque NocoDB", "hideNocodbBranding": "Masquer la marque NocoDB",
"showOnConditions": "Show on conditions", "showOnConditions": "Show on conditions",
"showFieldOnConditionsMet": "Shows field only when conditions are met", "showFieldOnConditionsMet": "Montre le champ uniquement lorsque les conditions sont réunies",
"limitOptions": "Limit options", "limitOptions": "Limiter les options",
"limitOptionsSubtext": "Limit options visible to users by selecting available options", "limitOptionsSubtext": "Limit options visible to users by selecting available options",
"clearSelection": "Effacer la sélection" "clearSelection": "Effacer la sélection"
}, },
@ -771,17 +773,17 @@
"newWorkspace": "Nouvel espace de travail", "newWorkspace": "Nouvel espace de travail",
"addDomain": "Add Domain", "addDomain": "Add Domain",
"addMembers": "Ajouter des membres", "addMembers": "Ajouter des membres",
"enterEmail": "Enter email addresses", "enterEmail": "Entrez les adresses e-mail",
"inviteToBase": "Invite to Base", "inviteToBase": "Inviter à la base",
"inviteToWorkspace": "Invite to Workspace", "inviteToWorkspace": "Inviter à l'espace de travail",
"addMember": "Add Member to Base", "addMember": "Ajouter un membre à la Base",
"noRange": "Calendar view requires a date range", "noRange": "La vue calendrier nécessite une plage de dates",
"goToToday": "Go to Today", "goToToday": "Aller à aujourd'hui",
"toggleSidebar": "Toggle Sidebar", "toggleSidebar": "Activer/désactiver la barre latérale",
"addEndDate": "Add end date", "addEndDate": "Ajouter une date de fin",
"withEndDate": "with end date", "withEndDate": "avec la date de fin",
"calendar": "Calendrier", "calendar": "Calendrier",
"viewSettings": "View settings", "viewSettings": "Afficher les paramètres",
"googleOAuth": "Google OAuth", "googleOAuth": "Google OAuth",
"registerOIDC": "Register OIDC Identity Provider", "registerOIDC": "Register OIDC Identity Provider",
"registerSAML": "Register SAML Identity Provider", "registerSAML": "Register SAML Identity Provider",
@ -789,27 +791,27 @@
"copyIFrameCode": "Copier le code IFrame", "copyIFrameCode": "Copier le code IFrame",
"onCondition": "On Condition", "onCondition": "On Condition",
"bulkDownload": "Bulk Download", "bulkDownload": "Bulk Download",
"attachFile": "Attach File", "attachFile": "Joindre un fichier",
"viewAttachment": "View Attachments", "viewAttachment": "Voir les pièces jointes",
"attachmentDrop": "Cliquez ou déposez un fichier dans la cellule", "attachmentDrop": "Cliquez ou déposez un fichier dans la cellule",
"addFiles": "Ajouter un ou des fichier(s)", "addFiles": "Ajouter un ou des fichier(s)",
"hideInUI": "Masquer dans l'interface", "hideInUI": "Masquer dans l'interface",
"addBase": "Add Base", "addBase": "Ajouter une base",
"addParameter": "Ajouter un paramètre", "addParameter": "Ajouter un paramètre",
"submitAnotherForm": "Soumettre un autre formulaire", "submitAnotherForm": "Soumettre un autre formulaire",
"dragAndDropFieldsHereToAdd": "Drag and drop fields here to add", "dragAndDropFieldsHereToAdd": "Glissez et déposez les champs ici pour ajouter",
"editSource": "Edit Data Source", "editSource": "Modifier la source de données",
"enterText": "Enter text", "enterText": "Saisir texte",
"okEditBase": "Ok & Edit Base", "okEditBase": "Ok & Edit Base",
"showInUI": "Afficher dans l'interface utilisateur", "showInUI": "Afficher dans l'interface utilisateur",
"outOfSync": "Out of sync", "outOfSync": "Out of sync",
"newSource": "Nouvelle source de données", "newSource": "Nouvelle source de données",
"newWebhook": "New Webhook", "newWebhook": "Nouveau Webhook",
"enablePublicAccess": "Activer l'accès public", "enablePublicAccess": "Activer l'accès public",
"doYouWantToSaveTheChanges": "Voulez-vous enregistrer les modifications ?", "doYouWantToSaveTheChanges": "Voulez-vous enregistrer les modifications ?",
"editingAccess": "Accès en modification", "editingAccess": "Accès en modification",
"enabledPublicViewing": "Activer l'affichage anonyme", "enabledPublicViewing": "Activer l'affichage anonyme",
"restrictAccessWithPassword": "Restrict access with password", "restrictAccessWithPassword": "Restreindre l'accès avec un mot de passe",
"manageProjectAccess": "Gérer l'accès à la base", "manageProjectAccess": "Gérer l'accès à la base",
"allowDownload": "Autoriser le téléchargement", "allowDownload": "Autoriser le téléchargement",
"surveyMode": "Mode Sondage", "surveyMode": "Mode Sondage",
@ -887,7 +889,7 @@
"previousRecord": "Ligne précédente", "previousRecord": "Ligne précédente",
"copyApiURL": "Copier l'URL de l'API", "copyApiURL": "Copier l'URL de l'API",
"createTable": "Créer une nouvelle table", "createTable": "Créer une nouvelle table",
"createDashboard": "Create Dashboard", "createDashboard": "Créer un tableau de bord",
"createWorkspace": "Créer un espace de travail", "createWorkspace": "Créer un espace de travail",
"refreshTable": "Actualiser le tableau", "refreshTable": "Actualiser le tableau",
"renameTable": "Renommer la table", "renameTable": "Renommer la table",
@ -895,7 +897,7 @@
"deleteTable": "Supprimer la table", "deleteTable": "Supprimer la table",
"addField": "Ajouter un nouveau champ à ce tableau", "addField": "Ajouter un nouveau champ à ce tableau",
"setDisplay": "Définir comme valeur d'affichage", "setDisplay": "Définir comme valeur d'affichage",
"addRow": "Ajouter une nouvelle ligne", "addRow": "Ajouter un nouvel enregistrement",
"saveRow": "Enregistrer", "saveRow": "Enregistrer",
"saveAndExit": "Enregistrer et quitter", "saveAndExit": "Enregistrer et quitter",
"saveAndStay": "Enregistrer et rester", "saveAndStay": "Enregistrer et rester",
@ -917,7 +919,7 @@
"clearMetadata": "Effacer les métadonnées", "clearMetadata": "Effacer les métadonnées",
"exportToFile": "Exporter vers le fichier", "exportToFile": "Exporter vers le fichier",
"changePwd": "Changer le mot de passe", "changePwd": "Changer le mot de passe",
"createView": "Créer une vue", "createView": "Créer vue",
"shareView": "Partager la vue", "shareView": "Partager la vue",
"findRowByCodeScan": "Find row by scan", "findRowByCodeScan": "Find row by scan",
"fillByCodeScan": "Remplir avec un scanner", "fillByCodeScan": "Remplir avec un scanner",
@ -972,10 +974,10 @@
"markAllAsRead": "Tout marquer comme lu", "markAllAsRead": "Tout marquer comme lu",
"column": { "column": {
"delete": "Supprimer le champ", "delete": "Supprimer le champ",
"addNumber": "Add Number Field", "addNumber": "Ajouter un champ de type numérique",
"addSingleLineText": "Add SingleLineText Field", "addSingleLineText": "Ajouter un champ de type texte sur une ligne",
"addLongText": "Add LongText Field", "addLongText": "Ajouter un champ de type texte long",
"addOther": "Add Other Field" "addOther": "Ajouter un autre champ"
}, },
"erd": { "erd": {
"showColumns": "Afficher les colonnes", "showColumns": "Afficher les colonnes",
@ -999,17 +1001,17 @@
}, },
"toggleMobileMode": "(Dés-)activer le mode Mobile", "toggleMobileMode": "(Dés-)activer le mode Mobile",
"startCommenting": "Commencez à commenter !", "startCommenting": "Commencez à commenter !",
"clearForm": "Clear Form", "clearForm": "Vider le formulaire",
"addFieldFromFormView": "Add Field", "addFieldFromFormView": "Ajouter un champ",
"selectAllFields": "Select all fields", "selectAllFields": "Sélectionner tous les champs",
"preFilledFields": { "preFilledFields": {
"title": "Enable Pre-fill", "title": "Autoriser le pré-remplissage",
"default": "Default", "default": "Valeur par défaut",
"locked": "Lock pre-filled fields as read-only", "locked": "Mettre les champs préremplis en lecture seule",
"hidden": "Hide pre-filled fields", "hidden": "Masquer les champs préremplis",
"lockedFieldTooltip": "Pre-filled value" "lockedFieldTooltip": "Valeur préremplie"
}, },
"getPreFilledLink": "Get Pre-filled Link", "getPreFilledLink": "Obtenir un lien prérempli",
"group": "Grouper par" "group": "Grouper par"
}, },
"tooltip": { "tooltip": {
@ -1024,7 +1026,7 @@
"light": "Jour (^⇧B)" "light": "Jour (^⇧B)"
}, },
"addTable": "Ajouter un nouveau tableau", "addTable": "Ajouter un nouveau tableau",
"addDashboard": "Add new Dashboard", "addDashboard": "Ajouter un nouveau tableau de bord",
"inviteMore": "Inviter plus d'utilisateurs", "inviteMore": "Inviter plus d'utilisateurs",
"toggleNavDraw": "Afficher ou masquer le panneau de navigation", "toggleNavDraw": "Afficher ou masquer le panneau de navigation",
"reloadApiToken": "Recharger les jetons API", "reloadApiToken": "Recharger les jetons API",
@ -1041,9 +1043,9 @@
"clientKey": "Selectionner un fichier .key", "clientKey": "Selectionner un fichier .key",
"clientCert": "Selectionner un fichier .cert", "clientCert": "Selectionner un fichier .cert",
"clientCA": "Selectionner un fichier d'authentification", "clientCA": "Selectionner un fichier d'authentification",
"changeIconColour": "Change icon colour", "changeIconColour": "Changer la couleur de l'icône",
"preFillFormInfo": "Generate share form URL with pre-filled field data. To get a pre-filled link, make sure you’ve filled the necessary fields in the form view builder.", "preFillFormInfo": "Generate share form URL with pre-filled field data. To get a pre-filled link, make sure you’ve filled the necessary fields in the form view builder.",
"surveyFormInfo": "Form mode with one field per page" "surveyFormInfo": "Mode formulaire avec un champ par page (enquête)"
}, },
"placeholder": { "placeholder": {
"selectSlackChannels": "Sélectionnez les canaux Slack", "selectSlackChannels": "Sélectionnez les canaux Slack",
@ -1052,14 +1054,14 @@
"selectMattermostChannels": "Sélectionnez les canaux Mattermost", "selectMattermostChannels": "Sélectionnez les canaux Mattermost",
"webhookTitle": "Titre du Webhook", "webhookTitle": "Titre du Webhook",
"barcodeColumn": "Sélectionnez un champ pour la valeur du code-barres", "barcodeColumn": "Sélectionnez un champ pour la valeur du code-barres",
"notFoundContent": "No valid field Type can be found.", "notFoundContent": "Aucun type de champ valide ne peut être trouvé.",
"selectBarcodeFormat": "Select a Barcode format", "selectBarcodeFormat": "Sélectionnez un format de code-barres",
"projName": "Saisir le nom du projet", "projName": "Saisir le nom du projet",
"selectGroupField": "Choisir un champ de regroupement", "selectGroupField": "Choisir un champ de regroupement",
"selectGroupFieldNotFound": "No Single Select Field can be found. Please create one first.", "selectGroupFieldNotFound": "Aucun champ de sélection en liste ne peut être trouvé. Veuillez en créer un d'abord.",
"selectGeoField": "Select a GeoData Field", "selectGeoField": "Sélectionnez un champ de type GeoData",
"notSelected": "-not selected-", "notSelected": "-non sélectionné-",
"selectGeoFieldNotFound": "No GeoData Field can be found. Please create one first.", "selectGeoFieldNotFound": "Aucun champ de type GeoData n'a été trouvé. Veuillez en créer un d'abord.",
"password": { "password": {
"enter": "Saisir le mot de passe", "enter": "Saisir le mot de passe",
"current": "Mot de passe actuel", "current": "Mot de passe actuel",
@ -1067,8 +1069,8 @@
"save": "Enregistrer le mot de passe", "save": "Enregistrer le mot de passe",
"confirm": "Confirmer le nouveau mot de passe" "confirm": "Confirmer le nouveau mot de passe"
}, },
"selectAColumnForTheQRCodeValue": "Select a field for the QR code value", "selectAColumnForTheQRCodeValue": "Sélectionnez un champ contenant la valeur du QR code",
"allowNegativeNumbers": "Allow negative numbers", "allowNegativeNumbers": "Autoriser les nombres négatifs",
"searchProjectTree": "Chercher un tableau", "searchProjectTree": "Chercher un tableau",
"searchFields": "Champ de recherche", "searchFields": "Champ de recherche",
"searchColumn": "Recherche {recherche} colonne", "searchColumn": "Recherche {recherche} colonne",
@ -1090,20 +1092,21 @@
"decimal8": "1,00000000", "decimal8": "1,00000000",
"value": "Valeur", "value": "Valeur",
"key": "Clé", "key": "Clé",
"createTable": "Create your First Table!", "createTable": "Créez votre première table !",
"createTableLabel": "Create your first table effortlessly, from scratch, or by importing/connecting to an external database.", "createTableLabel": "Create your first table effortlessly, from scratch, or by importing/connecting to an external database.",
"noTokenCreated": "No API Tokens created", "noTokenCreated": "Aucun jeton d'API créé",
"noTokenCreatedLabel": "Begin by creating API tokens to unlock advanced functionalities.", "noTokenCreatedLabel": "Begin by creating API tokens to unlock advanced functionalities.",
"inviteYourTeam": "Invite your team", "inviteYourTeam": "Invitez votre équipe",
"inviteYourTeamLabel": "Streamline collaboration and productivity with your team – start by inviting them to join your workspace.", "inviteYourTeamLabel": "Streamline collaboration and productivity with your team – start by inviting them to join your workspace.",
"searchOptions": "Search options" "searchOptions": "Options de recherche"
}, },
"msg": { "msg": {
"controlOrgAppearance": "Control your organisations name and appearance.", "formulaNotSupported": "This function is unavailable for your database",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "controlOrgAppearance": "Contrôlez le nom et l'apparence de vos organisations.",
"addCompanyDomains": "Ajoutez des domaines pour restreindre l'accès aux utilisateurs non souhaités.",
"restrictUsersFromSharing": "Empêcher les utilisateurs de partager leurs bases publiquement.", "restrictUsersFromSharing": "Empêcher les utilisateurs de partager leurs bases publiquement.",
"selectUsersToBeRemoved": "Select users to be removed and deleted from all organisation workspaces.", "selectUsersToBeRemoved": "Sélectionnez les utilisateurs à supprimer et à supprimer de tous les espaces de travail de l'organisation.",
"deleteOrganization": "Delete all users, bases and data related to this organization", "deleteOrganization": "Supprimer tous les utilisateurs, bases et données liées à cette organisation",
"clickToCopyFieldId": "Cliquer pour copier l'ID du champ", "clickToCopyFieldId": "Cliquer pour copier l'ID du champ",
"enterPassword": "Saisir le mot de passe", "enterPassword": "Saisir le mot de passe",
"bySigningUp": "En vous inscrivant, vous acceptez les", "bySigningUp": "En vous inscrivant, vous acceptez les",
@ -1112,79 +1115,79 @@
"thisSharedViewIsProtected": "Cette vue partagée est protégée", "thisSharedViewIsProtected": "Cette vue partagée est protégée",
"successfullySubmittedFormData": "Données du formulaire soumises avec succès", "successfullySubmittedFormData": "Données du formulaire soumises avec succès",
"formViewNotSupportedOnMobile": "L'affichage des formulaires n'est pas pris en charge sur les téléphones portables", "formViewNotSupportedOnMobile": "L'affichage des formulaires n'est pas pris en charge sur les téléphones portables",
"newFormWillBeLoaded": "New form will be loaded after {seconds} seconds", "newFormWillBeLoaded": "Un nouveau formulaire sera chargé après {seconds} secondes",
"optimizedQueryDisabled": "Optimized query is disabled", "optimizedQueryDisabled": "Optimized query is disabled",
"optimizedQueryEnabled": "Optimized query is enabled", "optimizedQueryEnabled": "Optimized query is enabled",
"lookupNonBtWarning": "Lookup field is not supported for non-Belongs to relation", "lookupNonBtWarning": "Lookup field is not supported for non-Belongs to relation",
"invalidTime": "Invalid Time", "invalidTime": "Invalid Time",
"linkColumnClearNotSupportedYet": "You don't have any supported links for Lookup", "linkColumnClearNotSupportedYet": "Vous n'avez aucun lien défini pour ajouter un champ Lookup",
"recordCouldNotBeFound": "Record could not be found", "recordCouldNotBeFound": "L'enregistrement n'a pas pu être trouvé",
"invalidPhoneNumber": "Numéro de téléphone invalide", "invalidPhoneNumber": "Numéro de téléphone invalide",
"pageSizeChanged": "Page size changed", "pageSizeChanged": "Taille de la page modifiée",
"errorLoadingData": "Erreur de chargement des données", "errorLoadingData": "Erreur de chargement des données",
"webhookBodyMsg1": "Use context variable", "webhookBodyMsg1": "Utiliser une variable de contexte",
"webhookBodyMsg2": "body", "webhookBodyMsg2": "corps du message",
"webhookBodyMsg3": "to refer the record under consideration", "webhookBodyMsg3": "to refer the record under consideration",
"formula": { "formula": {
"hintStart": "Hint: Use {placeholder1} to reference fields, e.g: {placeholder2}. For more, please check out", "hintStart": "Astuce : Utilisez {placeholder1} pour référencer des champs, par exemple: {placeholder2}. Pour en savoir plus, veuillez vérifier",
"hintEnd": "Formulas.", "hintEnd": "Expressions.",
"noSuggestedFormulaFound": "No suggested formula found", "noSuggestedFormulaFound": "Aucune formule suggérée trouvée",
"typeIsExpected": "{calleeName} requires a {type} at position {position}", "typeIsExpected": "{calleeName} requires a {type} at position {position}",
"numericTypeIsExpected": "Numeric type is expected", "numericTypeIsExpected": "Un type numérique est attendu",
"stringTypeIsExpected": "String type is expected", "stringTypeIsExpected": "Un type texte est attendu",
"operationNotAvailable": "{operation} operation not available", "operationNotAvailable": "Opération {operation} non disponible",
"cantSaveFieldFormulaInvalid": "Impossible d'enregistrer le champ car la formule n'est pas valide", "cantSaveFieldFormulaInvalid": "Impossible d'enregistrer le champ car la formule n'est pas valide",
"notSupportedToReferenceColumn": "Not supported to reference field {columnName}", "notSupportedToReferenceColumn": "Not supported to reference field {columnName}",
"typeIsExpectedButFound": "Le type {type} est attendu, mais le type {found} est trouvé", "typeIsExpectedButFound": "Le type {type} est attendu, mais le type {found} est trouvé",
"requiredArgumentsFormula": "{calleeName} requires {requiredArguments} arguments", "requiredArgumentsFormula": "{calleeName} nécessite les arguments {requiredArguments}",
"minRequiredArgumentsFormula": "{calleeName} required minimum {minRequiredArguments} arguments", "minRequiredArgumentsFormula": "{calleeName} required minimum {minRequiredArguments} arguments",
"maxRequiredArgumentsFormula": "{calleeName} required maximum {maxRequiredArguments} arguments", "maxRequiredArgumentsFormula": "{calleeName} required maximum {maxRequiredArguments} arguments",
"functionNotAvailable": "La fonction {function} n'est pas disponible", "functionNotAvailable": "La fonction {function} n'est pas disponible",
"firstParamWeekDayHaveDate": "The first parameter of WEEKDAY() should have date value", "firstParamWeekDayHaveDate": "Le premier paramètre de la fonction WEEKDAY() doit avoir une valeur de type date",
"secondParamWeekDayHaveDate": "The second parameter of WEEKDAY() should have the value either \"sunday\", \"monday\", \"tuesday\", \"wednesday\", \"thursday\", \"friday\" or \"saturday\"", "secondParamWeekDayHaveDate": "Le second paramètre de WEEKDAY() doit avoir la valeur \"dimanche\", \"lundi\", \"mardi\", \"mercredi\", \"jeudi\", \"vendredi\" ou \"samedi\"",
"firstParamDateAddHaveDate": "The first parameter of DATEADD() should have date value", "firstParamDateAddHaveDate": "Le premier paramètre de la fonction WEEKDAY() doit avoir une valeur de type date",
"secondParamDateAddHaveNumber": "The second parameter of DATEADD() should have numeric value", "secondParamDateAddHaveNumber": "Le deuxième paramètre de la fonction DATEADD() doit avoir une valeur numérique",
"thirdParamDateAddHaveDate": "The third parameter of DATEADD() should have the value either \"day\", \"week\", \"month\" or \"year\"", "thirdParamDateAddHaveDate": "Le troisième paramètre de DATEADD() doit avoir la valeur \"day\", \"week\", \"month\" ou \"year\"",
"firstParamDateDiffHaveDate": "The first parameter of DATEDIFF() should have date value", "firstParamDateDiffHaveDate": "Le premier paramètre de la fonction DATEDIFF() doit avoir une valeur de type date",
"secondParamDateDiffHaveDate": "The second parameter of DATEDIFF() should have date value", "secondParamDateDiffHaveDate": "Le second paramètre de la fonction DATEDIFF() doit avoir une valeur de type date",
"thirdParamDateDiffHaveDate": "The third parameter of DATETIME_DIFF() should have value either \"milliseconds\", \"ms\", \"seconds\", \"s\", \"minutes\", \"m\", \"hours\", \"h\", \"days\", \"d\", \"weeks\", \"w\", \"months\", \"M\", \"quarters\", \"Q\", \"years\", or \"y\"", "thirdParamDateDiffHaveDate": "Le troisième paramètre de la fonction DATETIME_DIFF() doit avoir la valeur \"millisecondes\", \"ms\", \"secondes\", \"s\", \"s\", \"s\", \"minutes\", \"m\", \"hours\", \"h\", \"days\", \"d\", \"weeks\", \"w\", \"months\", \"M\", \"quarters\", \"Q\", \"years\", ou \"y\"",
"columnNotAvailable": "Field {columnName} is not available", "columnNotAvailable": "Le champ {columnName} n'est pas disponible",
"cantSaveCircularReference": "Can’t save field because it causes a circular reference", "cantSaveCircularReference": "Impossible d'enregistrer le champ car il provoque une référence circulaire",
"columnWithTypeFoundButExpected": "Field {columnName} with {columnType} type is found but {expectedType} type is expected", "columnWithTypeFoundButExpected": "Le champ {columnName} avec le type {columnType} est trouvé mais le type {expectedType} est attendu",
"columnNotMatchedWithType": "{columnName} is not matched with {columnType}" "columnNotMatchedWithType": "{columnName} ne correspond pas au type {columnType}"
}, },
"selectOption": { "selectOption": {
"cantBeNull": "Select options can't be null", "cantBeNull": "Select options can't be null",
"multiSelectCantHaveCommas": "MultiSelect fields can't have commas(',')", "multiSelectCantHaveCommas": "MultiSelect fields can't have commas(',')",
"cantHaveDuplicates": "Select options can't have duplicates", "cantHaveDuplicates": "Select options can't have duplicates",
"createNewOptionNamed": "Create new option named" "createNewOptionNamed": "Créer une nouvelle option nommée"
}, },
"plsEnterANumber": "Veuillez saisir un nombre", "plsEnterANumber": "Veuillez saisir un nombre",
"plsInputEmail": "Veuillez saisir un e-mail", "plsInputEmail": "Veuillez saisir un e-mail",
"invalidDate": "Invalid date", "invalidDate": "Date non valide",
"invalidLocale": "Invalid locale", "invalidLocale": "Langue invalide",
"invalidCurrencyCode": "Code de devise invalide", "invalidCurrencyCode": "Code de devise invalide",
"postgresHasItsOwnCurrencySettings": "Le type 'money' de PostgreSQL a ses propres paramètres de devise", "postgresHasItsOwnCurrencySettings": "Le type 'money' de PostgreSQL a ses propres paramètres de devise",
"validColumnsForBarCode": "The valid Field Types for a Barcode Field are: Number, Single Line Text, Long Text, Phone Number, URL, Email, Decimal. Please create one first.", "validColumnsForBarCode": "Les types de champs valides pour un champ de code-barres sont : Numéro, Texte à une seule ligne, Texte Long, Numéro de Téléphone, URL, Email, Décimal. Veuillez en créer un d'abord.",
"hm": { "hm": {
"title": "Has Many Relation", "title": "Relation 1-n",
"tooltip_desc": "A single record from table ", "tooltip_desc": "Un seul enregistrement de la table ",
"tooltip_desc2": " peut être lié avec plusieurs enregistrements de la table " "tooltip_desc2": " peut être lié avec plusieurs enregistrements de la table "
}, },
"mm": { "mm": {
"title": "Many to Many Relation", "title": "Relation n-n",
"tooltip_desc": "Multiple records from table ", "tooltip_desc": "Plusieurs enregistrements de la table ",
"tooltip_desc2": " can be linked with multiple records from table " "tooltip_desc2": " peut être lié avec plusieurs enregistrements de la table "
}, },
"bt": { "bt": {
"title": "Belongs to Relation", "title": "Relation appartient à",
"tooltip_desc": "A single record from table ", "tooltip_desc": "Un seul enregistrement de la table ",
"tooltip_desc2": " can be linked with a record from table " "tooltip_desc2": " peut être lié avec un enregistrement de la table "
}, },
"oo": { "oo": {
"title": "One to One Relation", "title": "One to One Relation",
"tooltip_desc": "A single record from table ", "tooltip_desc": "A single record from table ",
"tooltip_desc2": " can be linked with a single record from table " "tooltip_desc2": " peut être lié à un seul enregistrement de la table "
}, },
"clickLinkRecordsToAddLinkFromTable": "Il semble qu'aucun enregistrement n'ait encore été lié.", "clickLinkRecordsToAddLinkFromTable": "Il semble qu'aucun enregistrement n'ait encore été lié.",
"noRecordsLinked": "Aucun enregistrement lié", "noRecordsLinked": "Aucun enregistrement lié",
@ -1202,17 +1205,17 @@
"idColumnRequired": "ID field is required, you can rename this later if required.", "idColumnRequired": "ID field is required, you can rename this later if required.",
"length59Required": "The length exceeds the max 59 characters", "length59Required": "The length exceeds the max 59 characters",
"noNewNotifications": "You have no new notifications", "noNewNotifications": "You have no new notifications",
"noRecordFound": "Record not found", "noRecordFound": "Enregistrement non trouvé",
"noRecordsFound": "Aucun enregistrement trouvé", "noRecordsFound": "Aucun enregistrement trouvé",
"noRecordsMatchYourSearchQuery": "Aucun enregistrement ne correspond à votre recherche", "noRecordsMatchYourSearchQuery": "Aucun enregistrement ne correspond à votre recherche",
"rowDeleted": "Record deleted", "rowDeleted": "Enregistrement supprimé",
"saveChanges": "Do you want to save the changes?", "saveChanges": "Voulez-vous enregistrer les modifications ?",
"tooLargeFieldEntity": "The field is too large to be converted to {entity}", "tooLargeFieldEntity": "Le champ est trop grand pour être converti en {entity}",
"roleRequired": "Role required", "roleRequired": "Role required",
"warning": { "warning": {
"calendarNoFields": "Calendar view requires a date or date time field to be setup. Try setting up a calendar view after adding a date / date time field!", "calendarNoFields": "Calendar view requires a date or date time field to be setup. Try setting up a calendar view after adding a date / date time field!",
"kanbanNoFields": "Kanban view requires a single select field to be setup. Try setting up a kanban view after adding a single select field!", "kanbanNoFields": "Kanban view requires a single select field to be setup. Try setting up a kanban view after adding a single select field!",
"mapNoFields": "Map view requires a geo data field to be setup. Try setting up a map view after adding a geo data field!", "mapNoFields": "La vue cartographique nécessite un champ de données géographiques pour être configuré. Essayez de configurer une vue cartographique après avoir ajouté un champ de données géographiques !",
"dbValid": "Veuillez vous assurer que la base de données à laquelle vous essayez de vous connecter est valide ! Cette opération peut provoquer une perte de schéma !!", "dbValid": "Veuillez vous assurer que la base de données à laquelle vous essayez de vous connecter est valide ! Cette opération peut provoquer une perte de schéma !!",
"barcode": { "barcode": {
"renderError": "Erreur de code-barres - veuillez vérifier la compatibiltié entre la donnée d'entrée et le type de code-barres" "renderError": "Erreur de code-barres - veuillez vérifier la compatibiltié entre la donnée d'entrée et le type de code-barres"
@ -1220,24 +1223,24 @@
"nonEditableFields": { "nonEditableFields": {
"computedFieldUnableToClear": "Avertissement : Champ calculé - impossible d'effacer le texte", "computedFieldUnableToClear": "Avertissement : Champ calculé - impossible d'effacer le texte",
"qrFieldsCannotBeDirectlyChanged": "Attention : les champs QR code ne peuvent pas être modifiés directement.", "qrFieldsCannotBeDirectlyChanged": "Attention : les champs QR code ne peuvent pas être modifiés directement.",
"barcodeFieldsCannotBeDirectlyChanged": "Warning: Barcode fields cannot be directly changed." "barcodeFieldsCannotBeDirectlyChanged": "Attention : les champs code-barres ne peuvent pas être modifiés directement."
}, },
"duplicateProject": "Are you sure you want to duplicate the base?", "duplicateProject": "Êtes-vous sûr de vouloir dupliquer la base ?",
"duplicateTable": "Êtes-vous sûr de vouloir dupliquer la table ?", "duplicateTable": "Êtes-vous sûr de vouloir dupliquer la table ?",
"multiField": { "multiField": {
"fieldVisibility": "You cannot change visibility of a field that is being edited. Please save or discard changes first.", "fieldVisibility": "Vous ne pouvez pas modifier la visibilité d'un champ en cours de modification. Veuillez d'abord enregistrer ou annuler les modifications.",
"moveEditedField": "You cannot move field that is being edited. Either save or discard changes first", "moveEditedField": "Vous ne pouvez pas déplacer un champ en cours d'édition. Enregistrez ou annulez d'abord les modifications",
"moveDeletedField": "You cannot move field that is deleted. Either save or discard changes first" "moveDeletedField": "Vous ne pouvez pas déplacer un champ supprimé. Enregistrez ou annulez d'abord les modifications"
} }
}, },
"info": { "info": {
"enterWorkspaceName": "Enter workspace name", "enterWorkspaceName": "Entrez le nom de l'espace de travail",
"enterBaseName": "Enter base name", "enterBaseName": "Entrez le nom de base",
"idpPaste": "Paste these URL in your Identity Providers console", "idpPaste": "Paste these URL in your Identity Providers console",
"noSaml": "There are no configured SAML authentications.", "noSaml": "Il n'y a aucune authentification SAML configurée.",
"noOIDC": "There are no configured OpenID authentications.", "noOIDC": "Il n'y a aucune authentification OpenID configurée.",
"disabledAsViewLocked": "Désactivé car la vue est verrouillée", "disabledAsViewLocked": "Désactivé car la vue est verrouillée",
"basesMigrated": "Bases are migrated. Please try again.", "basesMigrated": "Les bases sont migrées. Veuillez réessayer.",
"pasteNotSupported": "L'opération de collage n'est pas prise en charge sur la cellule active", "pasteNotSupported": "L'opération de collage n'est pas prise en charge sur la cellule active",
"roles": { "roles": {
"orgCreator": "Le créateur peut créer de nouveaux projets et accéder à tout projet invité.", "orgCreator": "Le créateur peut créer de nouveaux projets et accéder à tout projet invité.",
@ -1277,7 +1280,7 @@
"formInput": "Entrer le libellé du formulaire", "formInput": "Entrer le libellé du formulaire",
"formHelpText": "Ajouter un texte d'aide", "formHelpText": "Ajouter un texte d'aide",
"onlyCreator": "Visible uniquement pour les créateurs", "onlyCreator": "Visible uniquement pour les créateurs",
"formTitle": "Add form Title", "formTitle": "Ajouter un titre au formulaire",
"formDesc": "Ajouter une description au formulaire", "formDesc": "Ajouter une description au formulaire",
"beforeEnablePwd": "Restreindre l’accès à l’aide d’un mot de passe", "beforeEnablePwd": "Restreindre l’accès à l’aide d’un mot de passe",
"afterEnablePwd": "L’accès est restreint par un mot de passe", "afterEnablePwd": "L’accès est restreint par un mot de passe",
@ -1290,7 +1293,7 @@
"emailForm": "Écrivez-moi à", "emailForm": "Écrivez-moi à",
"showSysFields": "Afficher les champs système", "showSysFields": "Afficher les champs système",
"filterAutoApply": "Appliquer automatiquement", "filterAutoApply": "Appliquer automatiquement",
"formDisplayMessage": "Display Message", "formDisplayMessage": "Afficher le message",
"viewNotShared": "La vue actuelle n'est pas partagée!", "viewNotShared": "La vue actuelle n'est pas partagée!",
"showAllViews": "Montrer toutes les vues partagées sur cette table", "showAllViews": "Montrer toutes les vues partagées sur cette table",
"collabView": "Les collaborateurs avec des autorisations d'édition ou plus peuvent modifier la configuration de la vue.", "collabView": "Les collaborateurs avec des autorisations d'édition ou plus peuvent modifier la configuration de la vue.",
@ -1344,8 +1347,8 @@
"addMultipleUsers": "Vous pouvez ajouter plusieurs courriels séparés par des virgules (,)", "addMultipleUsers": "Vous pouvez ajouter plusieurs courriels séparés par des virgules (,)",
"enterTableName": "Entrez le nom du tableau", "enterTableName": "Entrez le nom du tableau",
"enterLayoutName": "Enter Layout name", "enterLayoutName": "Enter Layout name",
"enterDashboardName": "Enter Dashboard name", "enterDashboardName": "Entrez le nom du tableau de bord",
"defaultColumns": "Default fields", "defaultColumns": "Champs par défaut",
"addDefaultColumns": "Ajouter des colonnes par défaut", "addDefaultColumns": "Ajouter des colonnes par défaut",
"tableNameInDb": "Nom de la table tel qu'enregistré dans la base de données", "tableNameInDb": "Nom de la table tel qu'enregistré dans la base de données",
"airtable": { "airtable": {
@ -1385,8 +1388,8 @@
"noMoreRecords": "Plus d'enregistrements", "noMoreRecords": "Plus d'enregistrements",
"tokenNameNotEmpty": "Token name should not be empty", "tokenNameNotEmpty": "Token name should not be empty",
"tokenNameMaxLength": "Token name should not be more than 255 characters", "tokenNameMaxLength": "Token name should not be more than 255 characters",
"dbNameRequired": "Database name is required", "dbNameRequired": "Le nom de la base de données est requis",
"wsNameRequired": "Workspace name required", "wsNameRequired": "Nom de l'espace de travail requis",
"wsNameMinLength": "Le nom de l'espace de travail doit comporter au moins 3 caractères", "wsNameMinLength": "Le nom de l'espace de travail doit comporter au moins 3 caractères",
"wsNameMaxLength": "Le nom de l'espace de travail doit comporter au plus 50 caractères", "wsNameMaxLength": "Le nom de l'espace de travail doit comporter au plus 50 caractères",
"wsDeleteDlg": "Supprimez cet espace de travail et tout son contenu.", "wsDeleteDlg": "Supprimez cet espace de travail et tout son contenu.",
@ -1398,25 +1401,25 @@
"thankYou": "Merci !", "thankYou": "Merci !",
"submittedFormData": "Vous avez soumis les données du formulaire avec succès.", "submittedFormData": "Vous avez soumis les données du formulaire avec succès.",
"editingSystemKeyNotSupported": "Editing system key not supported", "editingSystemKeyNotSupported": "Editing system key not supported",
"notAvailableAtTheMoment": "Not available at the moment", "notAvailableAtTheMoment": "Non disponible pour le moment",
"groupPasteIsNotSupportedOnLinksColumn": "Group paste operation is not supported on Links/LinkToAnotherRecord column", "groupPasteIsNotSupportedOnLinksColumn": "Group paste operation is not supported on Links/LinkToAnotherRecord column",
"groupClearIsNotSupportedOnLinksColumn": "Group clear operation is not supported on Links/LinkToAnotherRecord column", "groupClearIsNotSupportedOnLinksColumn": "Group clear operation is not supported on Links/LinkToAnotherRecord column",
"upgradeToEnterpriseEdition": "Upgrade to Enterprise Edition {extraInfo}", "upgradeToEnterpriseEdition": "Upgrade to Enterprise Edition {extraInfo}",
"thisFeatureIsOnlyAvailableInEnterpriseEdition": "This feature is only available in enterprise edition", "thisFeatureIsOnlyAvailableInEnterpriseEdition": "This feature is only available in enterprise edition",
"yourCurrentRoleIs": "Your current role is", "yourCurrentRoleIs": "Votre rôle actuel est",
"pleaseRequestAccessForView": "Please request for higher permission from the Admin / Base owner / Workspace owner to get access to this {viewName}", "pleaseRequestAccessForView": "Veuillez demander des droits plus élevés au propriétaire de l’Admin / Base / Espace de travail pour avoir accès à cette {viewName}",
"preventHideAllOptions": "You cannot hide all options if field is required" "preventHideAllOptions": "You cannot hide all options if field is required"
}, },
"error": { "error": {
"fetchingCalendarData": "Erreur lors de la récupération des données du calendrier", "fetchingCalendarData": "Erreur lors de la récupération des données du calendrier",
"fetchingActiveDates": "Error fetching active dates", "fetchingActiveDates": "Error fetching active dates",
"scopesRequired": "Scopes required", "scopesRequired": "Scopes required",
"domainRequired": "Domain name is required", "domainRequired": "Le nom de domaine est requis",
"authUrlRequired": "Auth URL is required", "authUrlRequired": "Auth URL is required",
"userNameAttributeRequired": "Username attribute is required", "userNameAttributeRequired": "Username attribute is required",
"clientIdRequired": "Client ID is required", "clientIdRequired": "L'ID du client est requis",
"issuerRequired": "Issuer is required", "issuerRequired": "Issuer is required",
"clientSecretRequired": "Client Secret is required", "clientSecretRequired": "Le client secret est requis",
"jwkUrlRequired": "JWK URL is required", "jwkUrlRequired": "JWK URL is required",
"tokenUrlRequired": "Token URL is required", "tokenUrlRequired": "Token URL is required",
"userInfoUrlRequired": "UserInfo URL is required", "userInfoUrlRequired": "UserInfo URL is required",
@ -1449,8 +1452,8 @@
"atLeastOneNumber": "Un chiffre", "atLeastOneNumber": "Un chiffre",
"atLeastOneSpecialChar": "Un caractère spécial", "atLeastOneSpecialChar": "Un caractère spécial",
"allowedSpecialCharList": "Liste des caractères spéciaux autorisés", "allowedSpecialCharList": "Liste des caractères spéciaux autorisés",
"invalidEmails": "Invalid emails", "invalidEmails": "E-mails non valides",
"invalidEmail": "Invalid Email" "invalidEmail": "Email non valide"
}, },
"invalidXml": "Invalid XML", "invalidXml": "Invalid XML",
"invalidURL": "URL invalide", "invalidURL": "URL invalide",
@ -1483,7 +1486,7 @@
"followingCharactersAreNotAllowed": "Les caractères suivants ne sont pas autorisés", "followingCharactersAreNotAllowed": "Les caractères suivants ne sont pas autorisés",
"columnNameRequired": "Nom de la colonne requis", "columnNameRequired": "Nom de la colonne requis",
"duplicateColumnName": "Duplicate field name", "duplicateColumnName": "Duplicate field name",
"duplicateSystemColumnName": "Name already used for system field", "duplicateSystemColumnName": "Nom déjà utilisé par un champ système",
"uiDataTypeRequired": "UI data type is required", "uiDataTypeRequired": "UI data type is required",
"columnNameExceedsCharacters": "The length of column name exceeds the max {value} characters", "columnNameExceedsCharacters": "The length of column name exceeds the max {value} characters",
"projectNameExceeds50Characters": "Le nom du projet dépasse les 50 caractères", "projectNameExceeds50Characters": "Le nom du projet dépasse les 50 caractères",
@ -1495,15 +1498,15 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Les types de fichiers acceptés sont .xls, .xlsx, .xlsm, .ods, .ots.", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Les types de fichiers acceptés sont .xls, .xlsx, .xlsm, .ods, .ots.",
"parameterKeyCannotBeEmpty": "La clé de paramètre ne peut pas être vide", "parameterKeyCannotBeEmpty": "La clé de paramètre ne peut pas être vide",
"duplicateParameterKeysAreNotAllowed": "Les doublons de clés de paramètres ne sont pas autorisés", "duplicateParameterKeysAreNotAllowed": "Les doublons de clés de paramètres ne sont pas autorisés",
"fieldRequired": "{value} ne peut pas être vide.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Projet non accessible", "projectNotAccessible": "Projet non accessible",
"copyToClipboardError": "Échec de la copie dans le presse-papiers", "copyToClipboardError": "Échec de la copie dans le presse-papiers",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Échec du collage à partir du presse-papiers",
"multiFieldSaveValidation": "Please complete the configuration of all fields before saving", "multiFieldSaveValidation": "Please complete the configuration of all fields before saving",
"somethingWentWrong": "Something went wrong", "somethingWentWrong": "Quelque chose n'a pas fonctionné",
"draggedContentIsNotTypeOfImage": "Dragged content is not type of image", "draggedContentIsNotTypeOfImage": "Dragged content is not type of image",
"fieldToParseImageData": "Field to parse image data", "fieldToParseImageData": "Field to parse image data",
"someOfTheRequiredFieldsAreEmpty": "Some of the required fields are empty" "someOfTheRequiredFieldsAreEmpty": "Certains des champs requis sont vides"
}, },
"toast": { "toast": {
"exportMetadata": "Les métadonnées de projet sont exportées avec succès", "exportMetadata": "Les métadonnées de projet sont exportées avec succès",
@ -1523,9 +1526,9 @@
"futureRelease": "Bientôt disponible !" "futureRelease": "Bientôt disponible !"
}, },
"success": { "success": {
"licenseKeyUpdated": "License Key Updated", "licenseKeyUpdated": "Clé de licence mise à jour",
"columnDuplicated": "Colonne dupliquée avec succès", "columnDuplicated": "Colonne dupliquée avec succès",
"rowDuplicatedWithoutSavedYet": "Row duplicated (not saved)", "rowDuplicatedWithoutSavedYet": "Enregistrement en double (non enregistré)",
"updatedUIACL": "Mise à jour réussie de l'ACL de l'interface utilisateur pour les tables", "updatedUIACL": "Mise à jour réussie de l'ACL de l'interface utilisateur pour les tables",
"pluginUninstalled": "Le plugin a été désinstallé avec succès", "pluginUninstalled": "Le plugin a été désinstallé avec succès",
"pluginSettingsSaved": "Les paramètres du plugin ont été enregistrés avec succès", "pluginSettingsSaved": "Les paramètres du plugin ont été enregistrés avec succès",

7
packages/nc-gui/lang/he.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "שם שולחן", "tableName": "שם שולחן",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty", "parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed", "duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "{value} cannot be empty.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project not accessible", "projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Failed to copy to clipboard", "copyToClipboardError": "Failed to copy to clipboard",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/hi.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Table name", "tableName": "Table name",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty", "parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed", "duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "{value} cannot be empty.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project not accessible", "projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Failed to copy to clipboard", "copyToClipboardError": "Failed to copy to clipboard",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/hr.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Tablica", "tableName": "Tablica",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Dozvoljeni tipovi datoteka su .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Dozvoljeni tipovi datoteka su .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Ključ parametra ne može biti prazan", "parameterKeyCannotBeEmpty": "Ključ parametra ne može biti prazan",
"duplicateParameterKeysAreNotAllowed": "Duplicirani ključevi parametara nisu dopušteni", "duplicateParameterKeysAreNotAllowed": "Duplicirani ključevi parametara nisu dopušteni",
"fieldRequired": "{value} ne može biti prazno.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project not accessible", "projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Kopiranje u međuspremnik nije uspjelo", "copyToClipboardError": "Kopiranje u međuspremnik nije uspjelo",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/id.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Nama meja", "tableName": "Nama meja",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Jenis file yang diterima adalah .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Jenis file yang diterima adalah .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Kunci parameter tidak boleh kosong", "parameterKeyCannotBeEmpty": "Kunci parameter tidak boleh kosong",
"duplicateParameterKeysAreNotAllowed": "Kunci parameter duplikat tidak diperbolehkan", "duplicateParameterKeysAreNotAllowed": "Kunci parameter duplikat tidak diperbolehkan",
"fieldRequired": "{value} tidak boleh kosong.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Proyek tidak dapat diakses", "projectNotAccessible": "Proyek tidak dapat diakses",
"copyToClipboardError": "Gagal menyalin ke papan klip", "copyToClipboardError": "Gagal menyalin ke papan klip",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

9
packages/nc-gui/lang/it.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Token senza titolo", "untitledToken": "Token senza titolo",
"tableName": "Nome della tabella", "tableName": "Nome della tabella",
"dashboardName": "Nome dashboard", "dashboardName": "Nome dashboard",
"createView": "Crea una vista", "createView": "Crea vista",
"creatingView": "Creazione vista", "creatingView": "Creazione vista",
"duplicateView": "Duplica vista", "duplicateView": "Duplica vista",
"duplicateGridView": "Duplica Visualizzazione Griglia", "duplicateGridView": "Duplica Visualizzazione Griglia",
@ -917,7 +919,7 @@
"clearMetadata": "Cancella metadati", "clearMetadata": "Cancella metadati",
"exportToFile": "Esporta su file", "exportToFile": "Esporta su file",
"changePwd": "Cambia password", "changePwd": "Cambia password",
"createView": "Crea una vista", "createView": "Crea vista",
"shareView": "Condividi vista", "shareView": "Condividi vista",
"findRowByCodeScan": "Find row by scan", "findRowByCodeScan": "Find row by scan",
"fillByCodeScan": "Riempi per scansione", "fillByCodeScan": "Riempi per scansione",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "I tipi di file accettati sono .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "I tipi di file accettati sono .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "La chiave del parametro non può essere vuota", "parameterKeyCannotBeEmpty": "La chiave del parametro non può essere vuota",
"duplicateParameterKeysAreNotAllowed": "Le chiavi dei parametri duplicate non sono consentite", "duplicateParameterKeysAreNotAllowed": "Le chiavi dei parametri duplicate non sono consentite",
"fieldRequired": "{value} non può essere vuoto.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Progetto non accessibile", "projectNotAccessible": "Progetto non accessibile",
"copyToClipboardError": "Non è riuscito a copiare negli appunti", "copyToClipboardError": "Non è riuscito a copiare negli appunti",
"pasteFromClipboardError": "Impossibile incollare dagli appunti", "pasteFromClipboardError": "Impossibile incollare dagli appunti",

7
packages/nc-gui/lang/ja.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "テーブルの名前", "tableName": "テーブルの名前",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "使用可能なファイル形式は、.xls、.xlsx、.xlsm、.ods、.ots です。", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "使用可能なファイル形式は、.xls、.xlsx、.xlsm、.ods、.ots です。",
"parameterKeyCannotBeEmpty": "パラメータキーは空にできません", "parameterKeyCannotBeEmpty": "パラメータキーは空にできません",
"duplicateParameterKeysAreNotAllowed": "パラメータキーの重複は許可されていません", "duplicateParameterKeysAreNotAllowed": "パラメータキーの重複は許可されていません",
"fieldRequired": "{value} を空にすることはできません。", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "このプロジェクトにはアクセスできません", "projectNotAccessible": "このプロジェクトにはアクセスできません",
"copyToClipboardError": "クリップボードへのコピーに失敗しました", "copyToClipboardError": "クリップボードへのコピーに失敗しました",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

5
packages/nc-gui/lang/ko.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "허용되는 파일 형식은 .xls, .xlsx, .xlsm, .ods, .ots입니다", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "허용되는 파일 형식은 .xls, .xlsx, .xlsm, .ods, .ots입니다",
"parameterKeyCannotBeEmpty": "매개 변수 키는 비워 둘 수 없습니다.", "parameterKeyCannotBeEmpty": "매개 변수 키는 비워 둘 수 없습니다.",
"duplicateParameterKeysAreNotAllowed": "중복 매개 변수 키는 허용되지 않습니다.", "duplicateParameterKeysAreNotAllowed": "중복 매개 변수 키는 허용되지 않습니다.",
"fieldRequired": "{value}은(는) 비워 둘 수 없습니다.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "프로젝트에 액세스할 수 없습니다.", "projectNotAccessible": "프로젝트에 액세스할 수 없습니다.",
"copyToClipboardError": "클립 보드에 복사할 수 없습니다.", "copyToClipboardError": "클립 보드에 복사할 수 없습니다.",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/lv.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Tabulas nosaukums", "tableName": "Tabulas nosaukums",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Pieņemtie failu tipi ir .xls, .xlsx, .xlsm, .ods, .ots.", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Pieņemtie failu tipi ir .xls, .xlsx, .xlsm, .ods, .ots.",
"parameterKeyCannotBeEmpty": "Parametra atslēga nedrīkst būt tukša", "parameterKeyCannotBeEmpty": "Parametra atslēga nedrīkst būt tukša",
"duplicateParameterKeysAreNotAllowed": "Parametru taustiņu dublēšanās nav atļauta", "duplicateParameterKeysAreNotAllowed": "Parametru taustiņu dublēšanās nav atļauta",
"fieldRequired": "{value} nevar būt tukšs.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Projekts nav pieejams", "projectNotAccessible": "Projekts nav pieejams",
"copyToClipboardError": "Neizdevās kopēt uz starpliktuvi", "copyToClipboardError": "Neizdevās kopēt uz starpliktuvi",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/nl.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Tabelnaam", "tableName": "Tabelnaam",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "De geaccepteerde bestandstypen zijn .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "De geaccepteerde bestandstypen zijn .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parametersleutel kan niet leeg zijn", "parameterKeyCannotBeEmpty": "Parametersleutel kan niet leeg zijn",
"duplicateParameterKeysAreNotAllowed": "Dubbele parametersleutels zijn niet toegestaan", "duplicateParameterKeysAreNotAllowed": "Dubbele parametersleutels zijn niet toegestaan",
"fieldRequired": "{value} kan niet leeg zijn.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project niet toegankelijk", "projectNotAccessible": "Project niet toegankelijk",
"copyToClipboardError": "Kopiëren naar klembord mislukt", "copyToClipboardError": "Kopiëren naar klembord mislukt",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/no.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Tabellnavn", "tableName": "Tabellnavn",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty", "parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed", "duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "{value} cannot be empty.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project not accessible", "projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Failed to copy to clipboard", "copyToClipboardError": "Failed to copy to clipboard",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

5
packages/nc-gui/lang/pl.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Dziś", "today": "Dziś",
"workspace": "Obszar roboczy", "workspace": "Obszar roboczy",
"txt": "Wartość rekordu TXT", "txt": "Wartość rekordu TXT",
@ -1099,6 +1101,7 @@
"searchOptions": "Opcje wyszukiwania" "searchOptions": "Opcje wyszukiwania"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Kontroluj nazwę i wygląd organizacji.", "controlOrgAppearance": "Kontroluj nazwę i wygląd organizacji.",
"addCompanyDomains": "Dodaj domeny firmy, aby ograniczyć dostęp od niechcianych użytkowników.", "addCompanyDomains": "Dodaj domeny firmy, aby ograniczyć dostęp od niechcianych użytkowników.",
"restrictUsersFromSharing": "Ogranicz użytkowników z możliwości publicznego udostępniania baz danych.", "restrictUsersFromSharing": "Ogranicz użytkowników z możliwości publicznego udostępniania baz danych.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Akceptowane typy plików to: .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Akceptowane typy plików to: .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Klucz parametru nie może być pusty", "parameterKeyCannotBeEmpty": "Klucz parametru nie może być pusty",
"duplicateParameterKeysAreNotAllowed": "Zduplikowane klucze parametrów są niedozwolone", "duplicateParameterKeysAreNotAllowed": "Zduplikowane klucze parametrów są niedozwolone",
"fieldRequired": "{value} nie może być puste.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Projekt niedostępny", "projectNotAccessible": "Projekt niedostępny",
"copyToClipboardError": "Nie udało się skopiować do schowka", "copyToClipboardError": "Nie udało się skopiować do schowka",
"pasteFromClipboardError": "Nie udało się wkleić ze schowka", "pasteFromClipboardError": "Nie udało się wkleić ze schowka",

9
packages/nc-gui/lang/pt.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Token sem título", "untitledToken": "Token sem título",
"tableName": "Nome da tabela", "tableName": "Nome da tabela",
"dashboardName": "Nome do painel", "dashboardName": "Nome do painel",
"createView": "Criar uma vista", "createView": "Criar Vista",
"creatingView": "Criando visualização", "creatingView": "Criando visualização",
"duplicateView": "Vista duplicada", "duplicateView": "Vista duplicada",
"duplicateGridView": "Vista duplicada em grelha", "duplicateGridView": "Vista duplicada em grelha",
@ -917,7 +919,7 @@
"clearMetadata": "Limpar Metadados", "clearMetadata": "Limpar Metadados",
"exportToFile": "Exportar para ficheiro", "exportToFile": "Exportar para ficheiro",
"changePwd": "Alterar a senha", "changePwd": "Alterar a senha",
"createView": "Criar uma vista", "createView": "Criar Vista",
"shareView": "Partilhar Vista", "shareView": "Partilhar Vista",
"findRowByCodeScan": "Find row by scan", "findRowByCodeScan": "Find row by scan",
"fillByCodeScan": "Fill by scan", "fillByCodeScan": "Fill by scan",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Os tipos de ficheiro aceites são .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Os tipos de ficheiro aceites são .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "A chave do parâmetro não pode estar vazia", "parameterKeyCannotBeEmpty": "A chave do parâmetro não pode estar vazia",
"duplicateParameterKeysAreNotAllowed": "Não são permitidas chaves de parâmetros duplicadas", "duplicateParameterKeysAreNotAllowed": "Não são permitidas chaves de parâmetros duplicadas",
"fieldRequired": "{value} não pode estar vazio.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Projecto não acessível", "projectNotAccessible": "Projecto não acessível",
"copyToClipboardError": "Falha na cópia para a prancheta", "copyToClipboardError": "Falha na cópia para a prancheta",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/pt_BR.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Nome da tabela", "tableName": "Nome da tabela",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Os tipos de ficheiro aceites são .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Os tipos de ficheiro aceites são .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "A chave do parâmetro não pode estar vazia", "parameterKeyCannotBeEmpty": "A chave do parâmetro não pode estar vazia",
"duplicateParameterKeysAreNotAllowed": "Não são permitidas chaves de parâmetros duplicadas", "duplicateParameterKeysAreNotAllowed": "Não são permitidas chaves de parâmetros duplicadas",
"fieldRequired": "{value} não pode estar vazio.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Projecto não acessível", "projectNotAccessible": "Projecto não acessível",
"copyToClipboardError": "Falha na cópia para a prancheta", "copyToClipboardError": "Falha na cópia para a prancheta",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/ru.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Название таблицы", "tableName": "Название таблицы",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Допустимые типы файлов: .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Допустимые типы файлов: .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Ключ параметра не может быть пустым", "parameterKeyCannotBeEmpty": "Ключ параметра не может быть пустым",
"duplicateParameterKeysAreNotAllowed": "Дублирование ключей параметров не допускается", "duplicateParameterKeysAreNotAllowed": "Дублирование ключей параметров не допускается",
"fieldRequired": "{value} не может быть пустым.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Проект недоступен", "projectNotAccessible": "Проект недоступен",
"copyToClipboardError": "Не удалось скопировать в буфер обмена", "copyToClipboardError": "Не удалось скопировать в буфер обмена",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/sk.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Názov tabuľky", "tableName": "Názov tabuľky",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Akceptované typy súborov sú .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Akceptované typy súborov sú .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Kľúč parametra nemôže byť prázdny", "parameterKeyCannotBeEmpty": "Kľúč parametra nemôže byť prázdny",
"duplicateParameterKeysAreNotAllowed": "Duplicitné kľúče parametrov nie sú povolené", "duplicateParameterKeysAreNotAllowed": "Duplicitné kľúče parametrov nie sú povolené",
"fieldRequired": "{value} nemôže byť prázdny.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Projekt nie je prístupný", "projectNotAccessible": "Projekt nie je prístupný",
"copyToClipboardError": "Nepodarilo sa skopírovať do schránky", "copyToClipboardError": "Nepodarilo sa skopírovať do schránky",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/sl.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Ime tabele", "tableName": "Ime tabele",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Sprejete vrste datotek so .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Sprejete vrste datotek so .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Ključ parametra ne more biti prazen", "parameterKeyCannotBeEmpty": "Ključ parametra ne more biti prazen",
"duplicateParameterKeysAreNotAllowed": "Podvojeni ključi parametrov niso dovoljeni", "duplicateParameterKeysAreNotAllowed": "Podvojeni ključi parametrov niso dovoljeni",
"fieldRequired": "{value} ne more biti prazen.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Projekt ni dostopen", "projectNotAccessible": "Projekt ni dostopen",
"copyToClipboardError": "Neuspešno kopiranje v odložišče", "copyToClipboardError": "Neuspešno kopiranje v odložišče",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/sv.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Tabellnamn", "tableName": "Tabellnamn",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "De accepterade filtyperna är .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "De accepterade filtyperna är .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameternyckeln kan inte vara tom", "parameterKeyCannotBeEmpty": "Parameternyckeln kan inte vara tom",
"duplicateParameterKeysAreNotAllowed": "Dubbla parameternycklar är inte tillåtna", "duplicateParameterKeysAreNotAllowed": "Dubbla parameternycklar är inte tillåtna",
"fieldRequired": "{value} får inte vara tom.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Projektet är inte tillgängligt", "projectNotAccessible": "Projektet är inte tillgängligt",
"copyToClipboardError": "Kopiering till urklipp misslyckades", "copyToClipboardError": "Kopiering till urklipp misslyckades",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/th.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "ชอตาราง", "tableName": "ชอตาราง",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty", "parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed", "duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "{value} cannot be empty.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project not accessible", "projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Failed to copy to clipboard", "copyToClipboardError": "Failed to copy to clipboard",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

5
packages/nc-gui/lang/tr.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Kabul edilen dosya türleri .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Kabul edilen dosya türleri .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parametre anahtarı boş olamaz", "parameterKeyCannotBeEmpty": "Parametre anahtarı boş olamaz",
"duplicateParameterKeysAreNotAllowed": "Yinelenen parametre anahtarlarına izin verilmez", "duplicateParameterKeysAreNotAllowed": "Yinelenen parametre anahtarlarına izin verilmez",
"fieldRequired": "{value} boş olamaz.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Proje erişilebilir değil", "projectNotAccessible": "Proje erişilebilir değil",
"copyToClipboardError": "Panoya kopyalanamadı", "copyToClipboardError": "Panoya kopyalanamadı",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/uk.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Назва таблиці", "tableName": "Назва таблиці",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Дозволені типи файлів: .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "Дозволені типи файлів: .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Ключ параметра не може бути порожнім", "parameterKeyCannotBeEmpty": "Ключ параметра не може бути порожнім",
"duplicateParameterKeysAreNotAllowed": "Дублювання ключів параметрів неприпустимо", "duplicateParameterKeysAreNotAllowed": "Дублювання ключів параметрів неприпустимо",
"fieldRequired": "{value} не може бути порожнім.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Проєкт недоступний", "projectNotAccessible": "Проєкт недоступний",
"copyToClipboardError": "Не вдалося скопіювати в буфер обміну", "copyToClipboardError": "Не вдалося скопіювати в буфер обміну",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

7
packages/nc-gui/lang/vi.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "Tên bảng.", "tableName": "Tên bảng.",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty", "parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed", "duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "{value} cannot be empty.", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project not accessible", "projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Failed to copy to clipboard", "copyToClipboardError": "Failed to copy to clipboard",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

21
packages/nc-gui/lang/zh-Hans.json

@ -162,7 +162,7 @@
"insertAbove": "将上方内容插入", "insertAbove": "将上方内容插入",
"insertBelow": "将下方内容插入", "insertBelow": "将下方内容插入",
"hideField": "隐藏字段", "hideField": "隐藏字段",
"showField": "Show Field", "showField": "显示字段",
"sortAsc": "升序", "sortAsc": "升序",
"sortDesc": "降序", "sortDesc": "降序",
"move": "移动", "move": "移动",
@ -448,16 +448,18 @@
"noResultsMatchedYourSearch": "您的搜索没有任何匹配结果" "noResultsMatchedYourSearch": "您的搜索没有任何匹配结果"
}, },
"labels": { "labels": {
"today": "Today", "connectionDetails": "链接明细",
"workspace": "Workspace", "metaSync": "元同步",
"today": "今天",
"workspace": "工作区",
"txt": "TXT 记录值", "txt": "TXT 记录值",
"transferOwnership": "转让所有权", "transferOwnership": "转让所有权",
"recentActivity": "最近动态", "recentActivity": "最近动态",
"goToMembers": "转到成员", "goToMembers": "转到成员",
"addMember": "添加成员", "addMember": "添加成员",
"numberOfMembers": "No. Members", "numberOfMembers": "工作区序号",
"numberOfBases": "No. Bases", "numberOfBases": "项目序号",
"numberOfRecords": "No. Records", "numberOfRecords": "记录序号",
"workspaceName": "工作区名称", "workspaceName": "工作区名称",
"workspaceWithoutOwner": "工作区(无所有者)", "workspaceWithoutOwner": "工作区(无所有者)",
"inviteUsersToWorkspace": "邀请用户访问工作区", "inviteUsersToWorkspace": "邀请用户访问工作区",
@ -469,7 +471,7 @@
"signOutUsers": "注销用户", "signOutUsers": "注销用户",
"deactivateUser": "停用用户", "deactivateUser": "停用用户",
"deactivateUsers": "停用用户", "deactivateUsers": "停用用户",
"lastActive": "Last Active", "lastActive": "最近活动",
"dateAdded": "日期已添加", "dateAdded": "日期已添加",
"uploadImage": "上传图片", "uploadImage": "上传图片",
"organizationProfile": "组织简介", "organizationProfile": "组织简介",
@ -482,7 +484,7 @@
"deleteUserAndData": "删除用户及其数据", "deleteUserAndData": "删除用户及其数据",
"userOptions": "用户选项", "userOptions": "用户选项",
"deleteThisOrganization": "删除该组织", "deleteThisOrganization": "删除该组织",
"dangerZone": "Dangerzone", "dangerZone": "危险区",
"selectYear": "选择年份", "selectYear": "选择年份",
"save": "保存", "save": "保存",
"cancel": "取消", "cancel": "取消",
@ -1099,6 +1101,7 @@
"searchOptions": "搜索选项" "searchOptions": "搜索选项"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "控制您的组织名称和外观。", "controlOrgAppearance": "控制您的组织名称和外观。",
"addCompanyDomains": "添加公司域,限制不需要的用户访问。", "addCompanyDomains": "添加公司域,限制不需要的用户访问。",
"restrictUsersFromSharing": "限制用户公开共享项目 。", "restrictUsersFromSharing": "限制用户公开共享项目 。",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "可接受的文件类型是 .xls, .xlsx, .xlsm, .ods, .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "可接受的文件类型是 .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "参数键不能为空", "parameterKeyCannotBeEmpty": "参数键不能为空",
"duplicateParameterKeysAreNotAllowed": "不允许重复的参数键", "duplicateParameterKeysAreNotAllowed": "不允许重复的参数键",
"fieldRequired": "{value} 不能为空。", "fieldRequired": "此字段不能为空。",
"projectNotAccessible": "无权访问此项目", "projectNotAccessible": "无权访问此项目",
"copyToClipboardError": "未能复制到剪贴板", "copyToClipboardError": "未能复制到剪贴板",
"pasteFromClipboardError": "从剪贴板粘贴失败", "pasteFromClipboardError": "从剪贴板粘贴失败",

7
packages/nc-gui/lang/zh-Hant.json

@ -448,6 +448,8 @@
"noResultsMatchedYourSearch": "Your search did not yield any matching results." "noResultsMatchedYourSearch": "Your search did not yield any matching results."
}, },
"labels": { "labels": {
"connectionDetails": "Connection Details",
"metaSync": "Meta Sync",
"today": "Today", "today": "Today",
"workspace": "Workspace", "workspace": "Workspace",
"txt": "TXT Record value", "txt": "TXT Record value",
@ -587,7 +589,7 @@
"untitledToken": "Untitled token", "untitledToken": "Untitled token",
"tableName": "表名稱", "tableName": "表名稱",
"dashboardName": "Dashboard name", "dashboardName": "Dashboard name",
"createView": "Create a View", "createView": "Create View",
"creatingView": "Creating View", "creatingView": "Creating View",
"duplicateView": "Duplicate View", "duplicateView": "Duplicate View",
"duplicateGridView": "Duplicate Grid View", "duplicateGridView": "Duplicate Grid View",
@ -1099,6 +1101,7 @@
"searchOptions": "Search options" "searchOptions": "Search options"
}, },
"msg": { "msg": {
"formulaNotSupported": "This function is unavailable for your database",
"controlOrgAppearance": "Control your organisations name and appearance.", "controlOrgAppearance": "Control your organisations name and appearance.",
"addCompanyDomains": "Add company domains to restrict access to unwanted users.", "addCompanyDomains": "Add company domains to restrict access to unwanted users.",
"restrictUsersFromSharing": "Restrict users from being able to share bases publicly.", "restrictUsersFromSharing": "Restrict users from being able to share bases publicly.",
@ -1495,7 +1498,7 @@
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "受支持的檔案類型包括 .xls、.xlsx、.xlsm、.ods 和 .ots", "theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "受支持的檔案類型包括 .xls、.xlsx、.xlsm、.ods 和 .ots",
"parameterKeyCannotBeEmpty": "參數鍵不可為空", "parameterKeyCannotBeEmpty": "參數鍵不可為空",
"duplicateParameterKeysAreNotAllowed": "不允許重複的參數鍵", "duplicateParameterKeysAreNotAllowed": "不允許重複的參數鍵",
"fieldRequired": "{value} 不能為空", "fieldRequired": "This field cannot be empty.",
"projectNotAccessible": "Project not accessible", "projectNotAccessible": "Project not accessible",
"copyToClipboardError": "複製到剪貼簿失敗", "copyToClipboardError": "複製到剪貼簿失敗",
"pasteFromClipboardError": "Failed to paste from clipboard", "pasteFromClipboardError": "Failed to paste from clipboard",

2
packages/nocodb/src/app.module.ts

@ -21,7 +21,6 @@ import { JobsModule } from '~/modules/jobs/jobs.module';
import appConfig from '~/app.config'; import appConfig from '~/app.config';
import { ExtractIdsMiddleware } from '~/middlewares/extract-ids/extract-ids.middleware'; import { ExtractIdsMiddleware } from '~/middlewares/extract-ids/extract-ids.middleware';
import { HookHandlerService } from '~/services/hook-handler.service';
import { BasicStrategy } from '~/strategies/basic.strategy/basic.strategy'; import { BasicStrategy } from '~/strategies/basic.strategy/basic.strategy';
import { UsersModule } from '~/modules/users/users.module'; import { UsersModule } from '~/modules/users/users.module';
import { AuthModule } from '~/modules/auth/auth.module'; import { AuthModule } from '~/modules/auth/auth.module';
@ -66,7 +65,6 @@ export const ceModuleConfig = {
LocalStrategy, LocalStrategy,
AuthTokenStrategy, AuthTokenStrategy,
BaseViewStrategy, BaseViewStrategy,
HookHandlerService,
BasicStrategy, BasicStrategy,
], ],
}; };

6
packages/nocodb/src/controllers/auth/ui/emailTemplates/invite.ts

@ -132,8 +132,8 @@ export default `<!doctype html>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
Hi,</p> Hi,</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
I invited you to be "<%- roles -%>" of the NocoDB base "<%- baseName %>". You have been invited to become "<%- roles -%>" of the NocoDB base "<%- baseName %>".
Click the button below to to accept my invitation.</p> Click the button below to accept the invitation.</p>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" <table role="presentation" border="0" cellpadding="0" cellspacing="0"
class="btn btn-primary" class="btn btn-primary"
style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; box-sizing: border-box; width: 100%;" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; box-sizing: border-box; width: 100%;"
@ -161,7 +161,7 @@ export default `<!doctype html>
</tbody> </tbody>
</table> </table>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
Thanks regards <%- adminEmail %>.</p> Have a nice day,<br><%- adminEmail %></p>
</td> </td>
</tr> </tr>
</table> </table>

4
packages/nocodb/src/controllers/auth/ui/emailTemplates/verify.ts

@ -132,7 +132,7 @@ export default `<!doctype html>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
Hi,</p> Hi,</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
Please verify your email address by clicking the following button.</p> Please verify your e-mail address by clicking the following button.</p>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" <table role="presentation" border="0" cellpadding="0" cellspacing="0"
class="btn btn-primary" class="btn btn-primary"
style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; box-sizing: border-box; width: 100%;" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; box-sizing: border-box; width: 100%;"
@ -160,7 +160,7 @@ export default `<!doctype html>
</tbody> </tbody>
</table> </table>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
Thanks regards NocoDB.</p> Thank you and have a nice day,<br><%- adminEmail %></p>
</td> </td>
</tr> </tr>
</table> </table>

4
packages/nocodb/src/filters/global-exception/global-exception.filter.ts

@ -10,6 +10,7 @@ import {
ExternalError, ExternalError,
extractDBError, extractDBError,
Forbidden, Forbidden,
NcBaseError,
NcBaseErrorv2, NcBaseErrorv2,
NotFound, NotFound,
SsoError, SsoError,
@ -39,7 +40,8 @@ export class GlobalExceptionFilter implements ExceptionFilter {
exception = new NcBaseErrorv2(NcErrorType.BAD_JSON); exception = new NcBaseErrorv2(NcErrorType.BAD_JSON);
} }
const dbError = extractDBError(exception); // try to extract db error for unknown errors
const dbError = !(exception instanceof NcBaseError) ? extractDBError(exception) : null;
// skip unnecessary error logging // skip unnecessary error logging
if ( if (

3
packages/nocodb/src/helpers/isDisposableEmail.ts

@ -3503,9 +3503,6 @@ const disposableEmailDomains = [
'xrap.de', 'xrap.de',
'xrho.com', 'xrho.com',
'xvx.us', 'xvx.us',
'xwaretech.com',
'xwaretech.info',
'xwaretech.net',
'xww.ro', 'xww.ro',
'xxhamsterxx.ga', 'xxhamsterxx.ga',
'xxi2.com', 'xxi2.com',

13
packages/nocodb/src/interface/Jobs.ts

@ -1,3 +1,5 @@
import type { UserType } from 'nocodb-sdk';
export const JOBS_QUEUE = 'jobs'; export const JOBS_QUEUE = 'jobs';
export enum JobTypes { export enum JobTypes {
@ -12,6 +14,7 @@ export enum JobTypes {
UpdateWsStat = 'update-ws-stats', UpdateWsStat = 'update-ws-stats',
UpdateSrcStat = 'update-source-stat', UpdateSrcStat = 'update-source-stat',
HealthCheck = 'health-check', HealthCheck = 'health-check',
HandleWebhook = 'handle-webhook',
} }
export enum JobStatus { export enum JobStatus {
@ -40,3 +43,13 @@ export enum InstanceCommands {
RESET = 'reset', RESET = 'reset',
RELEASE = 'release', RELEASE = 'release',
} }
export interface HandleWebhookJobData {
hookName: string;
prevData;
newData;
user: UserType;
viewId: string;
modelId: string;
tnPath: string;
}

6
packages/nocodb/src/modules/global/global.module.ts

@ -12,7 +12,9 @@ import { JwtStrategy } from '~/strategies/jwt.strategy';
import { UsersService } from '~/services/users/users.service'; import { UsersService } from '~/services/users/users.service';
import { TelemetryService } from '~/services/telemetry.service'; import { TelemetryService } from '~/services/telemetry.service';
import { AppHooksListenerService } from '~/services/app-hooks-listener.service'; import { AppHooksListenerService } from '~/services/app-hooks-listener.service';
import { HookHandlerService } from '~/services/hook-handler.service';
import { UsersModule } from '~/modules/users/users.module'; import { UsersModule } from '~/modules/users/users.module';
import { JobsModule } from '~/modules/jobs/jobs.module';
export const JwtStrategyProvider: Provider = { export const JwtStrategyProvider: Provider = {
provide: JwtStrategy, provide: JwtStrategy,
@ -36,7 +38,7 @@ export const JwtStrategyProvider: Provider = {
}; };
export const globalModuleMetadata = { export const globalModuleMetadata = {
imports: [EventEmitterModule, forwardRef(() => UsersModule)], imports: [EventEmitterModule, forwardRef(() => UsersModule), JobsModule],
providers: [ providers: [
InitMetaServiceProvider, InitMetaServiceProvider,
AppHooksService, AppHooksService,
@ -46,6 +48,7 @@ export const globalModuleMetadata = {
AppHooksService, AppHooksService,
AppHooksListenerService, AppHooksListenerService,
TelemetryService, TelemetryService,
HookHandlerService,
], ],
exports: [ exports: [
MetaService, MetaService,
@ -54,6 +57,7 @@ export const globalModuleMetadata = {
AppHooksService, AppHooksService,
AppHooksListenerService, AppHooksListenerService,
TelemetryService, TelemetryService,
HookHandlerService,
...(process.env.NC_WORKER_CONTAINER !== 'true' ? [SocketGateway] : []), ...(process.env.NC_WORKER_CONTAINER !== 'true' ? [SocketGateway] : []),
], ],
}; };

6
packages/nocodb/src/modules/jobs/fallback/fallback-queue.service.ts

@ -6,6 +6,7 @@ import { AtImportProcessor } from '~/modules/jobs/jobs/at-import/at-import.proce
import { MetaSyncProcessor } from '~/modules/jobs/jobs/meta-sync/meta-sync.processor'; import { MetaSyncProcessor } from '~/modules/jobs/jobs/meta-sync/meta-sync.processor';
import { SourceCreateProcessor } from '~/modules/jobs/jobs/source-create/source-create.processor'; import { SourceCreateProcessor } from '~/modules/jobs/jobs/source-create/source-create.processor';
import { SourceDeleteProcessor } from '~/modules/jobs/jobs/source-delete/source-delete.processor'; import { SourceDeleteProcessor } from '~/modules/jobs/jobs/source-delete/source-delete.processor';
import { WebhookHandlerProcessor } from '~/modules/jobs/jobs/webhook-handler/webhook-handler.processor';
import { JobsEventService } from '~/modules/jobs/fallback/jobs-event.service'; import { JobsEventService } from '~/modules/jobs/fallback/jobs-event.service';
import { JobStatus, JobTypes } from '~/interface/Jobs'; import { JobStatus, JobTypes } from '~/interface/Jobs';
@ -31,6 +32,7 @@ export class QueueService {
protected readonly metaSyncProcessor: MetaSyncProcessor, protected readonly metaSyncProcessor: MetaSyncProcessor,
protected readonly sourceCreateProcessor: SourceCreateProcessor, protected readonly sourceCreateProcessor: SourceCreateProcessor,
protected readonly sourceDeleteProcessor: SourceDeleteProcessor, protected readonly sourceDeleteProcessor: SourceDeleteProcessor,
protected readonly webhookHandlerProcessor: WebhookHandlerProcessor,
) { ) {
this.emitter.on(JobStatus.ACTIVE, (data: { job: Job }) => { this.emitter.on(JobStatus.ACTIVE, (data: { job: Job }) => {
const job = this.queueMemory.find((job) => job.id === data.job.id); const job = this.queueMemory.find((job) => job.id === data.job.id);
@ -88,6 +90,10 @@ export class QueueService {
this: this.sourceDeleteProcessor, this: this.sourceDeleteProcessor,
fn: this.sourceDeleteProcessor.job, fn: this.sourceDeleteProcessor.job,
}, },
[JobTypes.HandleWebhook]: {
this: this.webhookHandlerProcessor,
fn: this.webhookHandlerProcessor.job,
},
}; };
async jobWrapper(job: Job) { async jobWrapper(job: Job) {

13
packages/nocodb/src/modules/jobs/jobs-service.interface.ts

@ -0,0 +1,13 @@
import type Bull from 'bull';
import type { JobStatus } from '~/interface/Jobs';
export interface IJobsService {
jobsQueue: Bull.Queue;
toggleQueue(): Promise<void>;
add(name: string, data: any): Promise<Bull.Job<any>>;
jobStatus(jobId: string): Promise<JobStatus>;
jobList(): Promise<Bull.Job<any>[]>;
getJobWithData(data: any): Promise<Bull.Job<any>>;
resumeQueue(): Promise<void>;
pauseQueue(): Promise<void>;
}

5
packages/nocodb/src/modules/jobs/jobs.controller.ts

@ -21,6 +21,7 @@ import { GlobalGuard } from '~/guards/global/global.guard';
import NocoCache from '~/cache/NocoCache'; import NocoCache from '~/cache/NocoCache';
import { CacheGetType, CacheScope } from '~/utils/globals'; import { CacheGetType, CacheScope } from '~/utils/globals';
import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard'; import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard';
import { IJobsService } from '~/modules/jobs/jobs-service.interface';
const nanoidv2 = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 14); const nanoidv2 = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 14);
const POLLING_INTERVAL = 30000; const POLLING_INTERVAL = 30000;
@ -31,7 +32,7 @@ export class JobsController implements OnModuleInit {
jobsRedisService: JobsRedisService; jobsRedisService: JobsRedisService;
constructor( constructor(
@Inject('JobsService') private readonly jobsService, @Inject('JobsService') private readonly jobsService: IJobsService,
private moduleRef: ModuleRef, private moduleRef: ModuleRef,
) {} ) {}
@ -168,7 +169,7 @@ export class JobsController implements OnModuleInit {
const job = await this.jobsService.getJobWithData(data); const job = await this.jobsService.getJobWithData(data);
if (job) { if (job) {
res = {}; res = {};
res.id = job.id; res.id = `${job.id}`;
res.status = await this.jobsService.jobStatus(data.id); res.status = await this.jobsService.jobStatus(data.id);
} }
} }

2
packages/nocodb/src/modules/jobs/jobs.module.ts

@ -14,6 +14,7 @@ import { SourceCreateController } from '~/modules/jobs/jobs/source-create/source
import { SourceCreateProcessor } from '~/modules/jobs/jobs/source-create/source-create.processor'; import { SourceCreateProcessor } from '~/modules/jobs/jobs/source-create/source-create.processor';
import { SourceDeleteController } from '~/modules/jobs/jobs/source-delete/source-delete.controller'; import { SourceDeleteController } from '~/modules/jobs/jobs/source-delete/source-delete.controller';
import { SourceDeleteProcessor } from '~/modules/jobs/jobs/source-delete/source-delete.processor'; import { SourceDeleteProcessor } from '~/modules/jobs/jobs/source-delete/source-delete.processor';
import { WebhookHandlerProcessor } from '~/modules/jobs/jobs/webhook-handler/webhook-handler.processor';
// Jobs Module Related // Jobs Module Related
import { JobsLogService } from '~/modules/jobs/jobs/jobs-log.service'; import { JobsLogService } from '~/modules/jobs/jobs/jobs-log.service';
@ -77,6 +78,7 @@ export const JobsModuleMetadata = {
MetaSyncProcessor, MetaSyncProcessor,
SourceCreateProcessor, SourceCreateProcessor,
SourceDeleteProcessor, SourceDeleteProcessor,
WebhookHandlerProcessor,
], ],
exports: ['JobsService'], exports: ['JobsService'],
}; };

5
packages/nocodb/src/modules/jobs/jobs/at-import/at-import.controller.ts

@ -13,11 +13,14 @@ import { SyncSource } from '~/models';
import { NcError } from '~/helpers/catchError'; import { NcError } from '~/helpers/catchError';
import { JobTypes } from '~/interface/Jobs'; import { JobTypes } from '~/interface/Jobs';
import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard'; import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard';
import { IJobsService } from '~/modules/jobs/jobs-service.interface';
@Controller() @Controller()
@UseGuards(MetaApiLimiterGuard, GlobalGuard) @UseGuards(MetaApiLimiterGuard, GlobalGuard)
export class AtImportController { export class AtImportController {
constructor(@Inject('JobsService') private readonly jobsService) {} constructor(
@Inject('JobsService') private readonly jobsService: IJobsService,
) {}
@Post([ @Post([
'/api/v1/db/meta/syncs/:syncId/trigger', '/api/v1/db/meta/syncs/:syncId/trigger',

3
packages/nocodb/src/modules/jobs/jobs/export-import/duplicate.controller.ts

@ -17,12 +17,13 @@ import { Base, Column, Model, Source } from '~/models';
import { generateUniqueName } from '~/helpers/exportImportHelpers'; import { generateUniqueName } from '~/helpers/exportImportHelpers';
import { JobTypes } from '~/interface/Jobs'; import { JobTypes } from '~/interface/Jobs';
import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard'; import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard';
import { IJobsService } from '~/modules/jobs/jobs-service.interface';
@Controller() @Controller()
@UseGuards(MetaApiLimiterGuard, GlobalGuard) @UseGuards(MetaApiLimiterGuard, GlobalGuard)
export class DuplicateController { export class DuplicateController {
constructor( constructor(
@Inject('JobsService') protected readonly jobsService, @Inject('JobsService') protected readonly jobsService: IJobsService,
protected readonly basesService: BasesService, protected readonly basesService: BasesService,
) {} ) {}

13
packages/nocodb/src/modules/jobs/jobs/export-import/duplicate.processor.ts

@ -205,12 +205,12 @@ export class DuplicateProcessor {
(c.colOptions.type === RelationTypes.BELONGS_TO || (c.colOptions.type === RelationTypes.BELONGS_TO ||
(c.colOptions.type === RelationTypes.ONE_TO_ONE && (c.colOptions.type === RelationTypes.ONE_TO_ONE &&
c.meta?.bt)) && c.meta?.bt)) &&
c.colOptions.fk_related_model_id === modelId, c.colOptions.fk_related_model_id === sourceModel.id,
) )
.map((c) => c.id); .map((c) => c.id);
if (bts.length > 0) { if (bts.length > 0) {
fields[md.id] = [md.primaryKey.id]; fields[md.id] = fields[md.id] ? fields[md.id] : [md.primaryKey.id];
fields[md.id].push(...bts); fields[md.id].push(...bts);
} }
} }
@ -294,14 +294,6 @@ export class DuplicateProcessor {
throw new Error(`Export failed for model '${sourceModel.id}'`); throw new Error(`Export failed for model '${sourceModel.id}'`);
} }
exportedModel.model.columns = exportedModel.model.columns.filter((c) =>
c.id.includes(columnId),
);
if (exportedModel.model.columns.length !== 1) {
throw new Error(`There was an error duplicating column!`);
}
const replacedColumn = exportedModel.model.columns.find((c) => const replacedColumn = exportedModel.model.columns.find((c) =>
c.id.includes(columnId), c.id.includes(columnId),
); );
@ -325,6 +317,7 @@ export class DuplicateProcessor {
req, req,
externalModels: relatedModels, externalModels: relatedModels,
existingModel: sourceModel, existingModel: sourceModel,
importColumnIds: [columnId],
}); });
elapsedTime(hrTime, 'import model schema', 'duplicateColumn'); elapsedTime(hrTime, 'import model schema', 'duplicateColumn');

64
packages/nocodb/src/modules/jobs/jobs/export-import/import.service.ts

@ -81,6 +81,7 @@ export class ImportService {
req: NcRequest; req: NcRequest;
externalModels?: Model[]; externalModels?: Model[];
existingModel?: Model; existingModel?: Model;
importColumnIds?: string[];
}) { }) {
const hrTime = initTime(); const hrTime = initTime();
@ -143,7 +144,12 @@ export class ImportService {
const modelData = data.model; const modelData = data.model;
const reducedColumnSet = modelData.columns.filter( const reducedColumnSet = modelData.columns.filter(
(a) => !isVirtualCol(a) && a.uidt !== UITypes.ForeignKey, (a) =>
!isVirtualCol(a) &&
a.uidt !== UITypes.ForeignKey &&
(param.importColumnIds
? param.importColumnIds.includes(getEntityIdentifier(a.id))
: true),
); );
// create table with static columns // create table with static columns
@ -228,7 +234,14 @@ export class ImportService {
const modelData = data.model; const modelData = data.model;
const table = tableReferences.get(modelData.id); const table = tableReferences.get(modelData.id);
const linkedColumnSet = modelData.columns.filter((a) => isLinksOrLTAR(a)); const linkedColumnSet = modelData.columns.filter(
(a) =>
isLinksOrLTAR(a) &&
!a.system &&
(param.importColumnIds
? param.importColumnIds.includes(getEntityIdentifier(a.id))
: true),
);
for (const col of linkedColumnSet) { for (const col of linkedColumnSet) {
if (col.colOptions) { if (col.colOptions) {
@ -299,9 +312,8 @@ export class ImportService {
colOptions.fk_mm_model_id && a.id !== col.id, colOptions.fk_mm_model_id && a.id !== col.id,
); );
// referencing the same model
if (colOptions.fk_related_model_id === modelData.id) { if (colOptions.fk_related_model_id === modelData.id) {
continue; childColumn.title = `${childColumn.title} copy`;
} }
for (const nColumn of childModel.columns) { for (const nColumn of childModel.columns) {
@ -391,31 +403,8 @@ export class ImportService {
a.id !== col.id, a.id !== col.id,
); );
// referencing the same model
if (colOptions.fk_related_model_id === modelData.id) { if (colOptions.fk_related_model_id === modelData.id) {
const counterRelationType = childColumn.title = `${childColumn.title} copy`;
colOptions.type === 'hm' ? 'bt' : 'oo';
const oldCol = childModel.columns.find(
(oColumn) =>
oColumn.colOptions?.fk_parent_column_id ===
getEntityIdentifier(colOptions.fk_parent_column_id) &&
oColumn.colOptions?.fk_child_column_id ===
getEntityIdentifier(colOptions.fk_child_column_id) &&
oColumn.colOptions?.type === counterRelationType,
);
const col = childModel.columns.find(
(nColumn) =>
nColumn.colOptions?.fk_parent_column_id ===
getIdOrExternalId(colOptions.fk_parent_column_id) &&
nColumn.colOptions?.fk_child_column_id ===
getIdOrExternalId(colOptions.fk_child_column_id) &&
nColumn.colOptions?.type === counterRelationType,
);
idMap.set(
`${oldCol.base_id}::${oldCol.source_id}::${oldCol.fk_model_id}::${oldCol.id}`,
col.id,
);
continue;
} }
for (const nColumn of childModel.columns) { for (const nColumn of childModel.columns) {
@ -520,6 +509,10 @@ export class ImportService {
a.id !== getEntityIdentifier(col.id)), a.id !== getEntityIdentifier(col.id)),
); );
if (colOptions.fk_related_model_id === modelData.id) {
childColumn.title = `${childColumn.title} copy`;
}
for (const nColumn of childModel.columns) { for (const nColumn of childModel.columns) {
if ( if (
nColumn?.colOptions?.fk_mm_model_id === nColumn?.colOptions?.fk_mm_model_id ===
@ -643,6 +636,10 @@ export class ImportService {
a.id !== getEntityIdentifier(col.id)), a.id !== getEntityIdentifier(col.id)),
); );
if (colOptions.fk_related_model_id === modelData.id) {
childColumn.title = `${childColumn.title} copy`;
}
for (const nColumn of childModel.columns) { for (const nColumn of childModel.columns) {
if ( if (
nColumn.id !== getIdOrExternalId(col.id) && nColumn.id !== getIdOrExternalId(col.id) &&
@ -768,6 +765,10 @@ export class ImportService {
a.id !== getEntityIdentifier(col.id)), a.id !== getEntityIdentifier(col.id)),
); );
if (colOptions.fk_related_model_id === modelData.id) {
childColumn.title = `${childColumn.title} copy`;
}
for (const nColumn of childModel.columns) { for (const nColumn of childModel.columns) {
if ( if (
nColumn.id !== getIdOrExternalId(col.id) && nColumn.id !== getIdOrExternalId(col.id) &&
@ -815,7 +816,7 @@ export class ImportService {
referencedColumnSet.push( referencedColumnSet.push(
...modelData.columns.filter( ...modelData.columns.filter(
(a) => (a) =>
a.uidt === UITypes.Lookup || (a.uidt === UITypes.Lookup ||
a.uidt === UITypes.Rollup || a.uidt === UITypes.Rollup ||
a.uidt === UITypes.Formula || a.uidt === UITypes.Formula ||
a.uidt === UITypes.QrCode || a.uidt === UITypes.QrCode ||
@ -823,7 +824,10 @@ export class ImportService {
a.uidt === UITypes.LastModifiedTime || a.uidt === UITypes.LastModifiedTime ||
a.uidt === UITypes.CreatedBy || a.uidt === UITypes.CreatedBy ||
a.uidt === UITypes.LastModifiedBy || a.uidt === UITypes.LastModifiedBy ||
a.uidt === UITypes.Barcode, a.uidt === UITypes.Barcode) &&
(param.importColumnIds
? param.importColumnIds.includes(getEntityIdentifier(a.id))
: true),
), ),
); );
} }

8
packages/nocodb/src/modules/jobs/jobs/health-check.processor.ts

@ -1,17 +1,19 @@
import { Process, Processor } from '@nestjs/bull'; import { Process, Processor } from '@nestjs/bull';
import { Inject, Logger } from '@nestjs/common'; import { Inject, Logger } from '@nestjs/common';
import type { Queue } from 'bull';
import { JOBS_QUEUE, JobTypes } from '~/interface/Jobs'; import { JOBS_QUEUE, JobTypes } from '~/interface/Jobs';
import { IJobsService } from '~/modules/jobs/jobs-service.interface';
@Processor(JOBS_QUEUE) @Processor(JOBS_QUEUE)
export class HealthCheckProcessor { export class HealthCheckProcessor {
private logger = new Logger(HealthCheckProcessor.name); private logger = new Logger(HealthCheckProcessor.name);
constructor(@Inject('JobsService') protected readonly jobsService) {} constructor(
@Inject('JobsService') protected readonly jobsService: IJobsService,
) {}
@Process(JobTypes.HealthCheck) @Process(JobTypes.HealthCheck)
async healthCheck() { async healthCheck() {
const queue = this.jobsService.jobsQueue as Queue; const queue = this.jobsService.jobsQueue;
if (queue) { if (queue) {
queue queue

5
packages/nocodb/src/modules/jobs/jobs/meta-sync/meta-sync.controller.ts

@ -13,11 +13,14 @@ import { Acl } from '~/middlewares/extract-ids/extract-ids.middleware';
import { NcError } from '~/helpers/catchError'; import { NcError } from '~/helpers/catchError';
import { JobTypes } from '~/interface/Jobs'; import { JobTypes } from '~/interface/Jobs';
import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard'; import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard';
import { IJobsService } from '~/modules/jobs/jobs-service.interface';
@Controller() @Controller()
@UseGuards(MetaApiLimiterGuard, GlobalGuard) @UseGuards(MetaApiLimiterGuard, GlobalGuard)
export class MetaSyncController { export class MetaSyncController {
constructor(@Inject('JobsService') private readonly jobsService) {} constructor(
@Inject('JobsService') private readonly jobsService: IJobsService,
) {}
@Post([ @Post([
'/api/v1/db/meta/projects/:baseId/meta-diff', '/api/v1/db/meta/projects/:baseId/meta-diff',

5
packages/nocodb/src/modules/jobs/jobs/source-create/source-create.controller.ts

@ -15,11 +15,14 @@ import { Acl } from '~/middlewares/extract-ids/extract-ids.middleware';
import { NcError } from '~/helpers/catchError'; import { NcError } from '~/helpers/catchError';
import { JobTypes } from '~/interface/Jobs'; import { JobTypes } from '~/interface/Jobs';
import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard'; import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard';
import { IJobsService } from '~/modules/jobs/jobs-service.interface';
@Controller() @Controller()
@UseGuards(MetaApiLimiterGuard, GlobalGuard) @UseGuards(MetaApiLimiterGuard, GlobalGuard)
export class SourceCreateController { export class SourceCreateController {
constructor(@Inject('JobsService') private readonly jobsService) {} constructor(
@Inject('JobsService') private readonly jobsService: IJobsService,
) {}
@Post([ @Post([
'/api/v1/db/meta/projects/:baseId/bases', '/api/v1/db/meta/projects/:baseId/bases',

3
packages/nocodb/src/modules/jobs/jobs/source-delete/source-delete.controller.ts

@ -13,12 +13,13 @@ import { NcError } from '~/helpers/catchError';
import { JobTypes } from '~/interface/Jobs'; import { JobTypes } from '~/interface/Jobs';
import { SourcesService } from '~/services/sources.service'; import { SourcesService } from '~/services/sources.service';
import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard'; import { MetaApiLimiterGuard } from '~/guards/meta-api-limiter.guard';
import { IJobsService } from '~/modules/jobs/jobs-service.interface';
@Controller() @Controller()
@UseGuards(MetaApiLimiterGuard, GlobalGuard) @UseGuards(MetaApiLimiterGuard, GlobalGuard)
export class SourceDeleteController { export class SourceDeleteController {
constructor( constructor(
@Inject('JobsService') private readonly jobsService, @Inject('JobsService') private readonly jobsService: IJobsService,
private readonly sourcesService: SourcesService, private readonly sourcesService: SourcesService,
) {} ) {}

24
packages/nocodb/src/modules/jobs/jobs/webhook-handler/webhook-handler.processor.ts

@ -0,0 +1,24 @@
import { Process, Processor } from '@nestjs/bull';
import { forwardRef, Inject, Logger } from '@nestjs/common';
import { Job } from 'bull';
import {
type HandleWebhookJobData,
JOBS_QUEUE,
JobTypes,
} from '~/interface/Jobs';
import { HookHandlerService } from '~/services/hook-handler.service';
@Processor(JOBS_QUEUE)
export class WebhookHandlerProcessor {
private logger = new Logger(WebhookHandlerProcessor.name);
constructor(
@Inject(forwardRef(() => HookHandlerService))
private readonly hookHandlerService: HookHandlerService,
) {}
@Process(JobTypes.HandleWebhook)
async job(job: Job<HandleWebhookJobData>) {
await this.hookHandlerService.handleHooks(job.data);
}
}

6
packages/nocodb/src/services/base-users/ui/emailTemplates/invite.ts

@ -132,8 +132,8 @@ export default `<!doctype html>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
Hi,</p> Hi,</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
I invited you to be "<%- roles -%>" of the NocoDB base "<%- baseName %>". You have been invited to become "<%- roles -%>" of the NocoDB base "<%- baseName %>".
Click the button below to to accept my invitation.</p> Click the button below to accept the invitation.</p>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" <table role="presentation" border="0" cellpadding="0" cellspacing="0"
class="btn btn-primary" class="btn btn-primary"
style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; box-sizing: border-box; width: 100%;" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; box-sizing: border-box; width: 100%;"
@ -161,7 +161,7 @@ export default `<!doctype html>
</tbody> </tbody>
</table> </table>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
Thanks regards <%- adminEmail %>.</p> Have a nice day,<br><%- adminEmail %></p>
</td> </td>
</tr> </tr>
</table> </table>

4
packages/nocodb/src/services/base-users/ui/emailTemplates/verify.ts

@ -132,7 +132,7 @@ export default `<!doctype html>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
Hi,</p> Hi,</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
Please verify your email address by clicking the following button.</p> Please verify your e-mail address by clicking the following button.</p>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" <table role="presentation" border="0" cellpadding="0" cellspacing="0"
class="btn btn-primary" class="btn btn-primary"
style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; box-sizing: border-box; width: 100%;" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; box-sizing: border-box; width: 100%;"
@ -160,7 +160,7 @@ export default `<!doctype html>
</tbody> </tbody>
</table> </table>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;"> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px;">
Thanks regards NocoDB.</p> Thank you and have a nice day,<br><%- adminEmail %>
</td> </td>
</tr> </tr>
</table> </table>

10
packages/nocodb/src/services/columns.service.ts

@ -452,10 +452,16 @@ export class ColumnsService {
}), }),
); );
const data = await sqlClient.raw('SELECT DISTINCT ?? FROM ??', [ const data = await baseModel.execAndParse(
baseModel.dbDriver.raw('SELECT DISTINCT ?? FROM ??', [
column.column_name, column.column_name,
baseModel.getTnPath(table.table_name), baseModel.getTnPath(table.table_name),
]); ]),
null,
{
raw: true,
},
);
if (data.length) { if (data.length) {
const existingOptions = colBody.colOptions.options.map( const existingOptions = colBody.colOptions.options.map(

61
packages/nocodb/src/services/hook-handler.service.ts

@ -1,8 +1,7 @@
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable, Logger } from '@nestjs/common';
import { UITypes, ViewTypes } from 'nocodb-sdk'; import { type HookType, UITypes, ViewTypes } from 'nocodb-sdk';
import ejs from 'ejs'; import ejs from 'ejs';
import type { OnModuleDestroy, OnModuleInit } from '@nestjs/common'; import type { OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import type { UserType } from 'nocodb-sdk';
import NcPluginMgrv2 from '~/helpers/NcPluginMgrv2'; import NcPluginMgrv2 from '~/helpers/NcPluginMgrv2';
import { import {
_transformSubmittedFormDataForEmail, _transformSubmittedFormDataForEmail,
@ -11,18 +10,22 @@ import {
import { IEventEmitter } from '~/modules/event-emitter/event-emitter.interface'; import { IEventEmitter } from '~/modules/event-emitter/event-emitter.interface';
import formSubmissionEmailTemplate from '~/utils/common/formSubmissionEmailTemplate'; import formSubmissionEmailTemplate from '~/utils/common/formSubmissionEmailTemplate';
import { FormView, Hook, Model, View } from '~/models'; import { FormView, Hook, Model, View } from '~/models';
import { type HandleWebhookJobData, JobTypes } from '~/interface/Jobs';
import { IJobsService } from '~/modules/jobs/jobs-service.interface';
export const HANDLE_WEBHOOK = '__nc_handleHooks'; export const HANDLE_WEBHOOK = '__nc_handleHooks';
@Injectable() @Injectable()
export class HookHandlerService implements OnModuleInit, OnModuleDestroy { export class HookHandlerService implements OnModuleInit, OnModuleDestroy {
private logger = new Logger(HookHandlerService.name);
private unsubscribe: () => void; private unsubscribe: () => void;
constructor( constructor(
@Inject('IEventEmitter') private readonly eventEmitter: IEventEmitter, @Inject('IEventEmitter') private readonly eventEmitter: IEventEmitter,
@Inject('JobsService') private readonly jobsService: IJobsService,
) {} ) {}
private async handleHooks({ public async handleHooks({
hookName, hookName,
prevData, prevData,
newData, newData,
@ -30,15 +33,7 @@ export class HookHandlerService implements OnModuleInit, OnModuleDestroy {
viewId, viewId,
modelId, modelId,
tnPath, tnPath,
}: { }: HandleWebhookJobData): Promise<void> {
hookName;
prevData;
newData;
user: UserType;
viewId: string;
modelId: string;
tnPath: string;
}): Promise<void> {
const view = await View.get(viewId); const view = await View.get(viewId);
const model = await Model.get(modelId); const model = await Model.get(modelId);
@ -111,7 +106,11 @@ export class HookHandlerService implements OnModuleInit, OnModuleDestroy {
}); });
} }
} catch (e) { } catch (e) {
console.log(e); this.logger.error({
error: e,
details: 'Error while sending form submission email',
hookName,
});
} }
} }
@ -119,23 +118,47 @@ export class HookHandlerService implements OnModuleInit, OnModuleDestroy {
const [event, operation] = hookName.split('.'); const [event, operation] = hookName.split('.');
const hooks = await Hook.list({ const hooks = await Hook.list({
fk_model_id: modelId, fk_model_id: modelId,
event, event: event as HookType['event'],
operation, operation: operation as HookType['operation'],
}); });
for (const hook of hooks) { for (const hook of hooks) {
if (hook.active) { if (hook.active) {
invokeWebhook(hook, model, view, prevData, newData, user); await invokeWebhook(hook, model, view, prevData, newData, user);
} }
} }
} catch (e) { } catch (e) {
console.log('hooks :: error', hookName, e); this.logger.error({
error: e,
details: 'Error while handling webhook',
hookName,
});
}
} }
private async triggerHook({
hookName,
prevData,
newData,
user,
viewId,
modelId,
tnPath,
}: HandleWebhookJobData) {
await this.jobsService.add(JobTypes.HandleWebhook, {
hookName,
prevData,
newData,
user,
viewId,
modelId,
tnPath,
});
} }
onModuleInit(): any { onModuleInit(): any {
this.unsubscribe = this.eventEmitter.on( this.unsubscribe = this.eventEmitter.on(
HANDLE_WEBHOOK, HANDLE_WEBHOOK,
this.handleHooks.bind(this), this.triggerHook.bind(this),
); );
} }

2
tests/playwright/pages/Dashboard/ViewSidebar/index.ts

@ -161,7 +161,7 @@ export class ViewSidebarPage extends BasePage {
force: true, force: true,
}); });
const submitAction = () => const submitAction = () =>
this.rootPage.locator('.ant-modal-content').locator('button:has-text("Create view"):visible').click(); this.rootPage.locator('.ant-modal-content').locator('button:has-text("Create View"):visible').click();
await this.waitForResponse({ await this.waitForResponse({
httpMethodsToMatch: ['POST'], httpMethodsToMatch: ['POST'],
requestUrlPathToMatch: '/api/v1/db/meta/tables/', requestUrlPathToMatch: '/api/v1/db/meta/tables/',

9
tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts

@ -65,7 +65,14 @@ export class ToolbarFilterPage extends BasePage {
await this.get().locator(`button:has-text("Add Filter Group")`).last().click(); await this.get().locator(`button:has-text("Add Filter Group")`).last().click();
const filterDropdown = this.get().locator('.menu-filter-dropdown').nth(filterGroupIndex); const filterDropdown = this.get().locator('.menu-filter-dropdown').nth(filterGroupIndex);
await filterDropdown.waitFor({ state: 'visible' }); await filterDropdown.waitFor({ state: 'visible' });
await filterDropdown.locator(`button:has-text("Add Filter")`).first().click(); const ADD_BUTTON_SELECTOR = `span:has-text("add")`;
const FILTER_GROUP_SUB_MENU_SELECTOR = `.nc-dropdown-filter-group-sub-menu`;
const ADD_FILTER_SELECTOR = `.nc-menu-item:has-text("Add Filter")`;
await filterDropdown.locator(ADD_BUTTON_SELECTOR).first().click();
const filterGroupSubMenu = this.rootPage.locator(FILTER_GROUP_SUB_MENU_SELECTOR).last();
await filterGroupSubMenu.waitFor({ state: 'visible' });
await filterGroupSubMenu.locator(ADD_FILTER_SELECTOR).first().click();
const selectField = filterDropdown.locator('.nc-filter-field-select').last(); const selectField = filterDropdown.locator('.nc-filter-field-select').last();
const selectOperation = filterDropdown.locator('.nc-filter-operation-select').last(); const selectOperation = filterDropdown.locator('.nc-filter-operation-select').last();
const selectValue = filterDropdown.locator('.nc-filter-value-select > input').last(); const selectValue = filterDropdown.locator('.nc-filter-value-select > input').last();

Loading…
Cancel
Save