Browse Source

Merge pull request #4810 from nocodb/develop

pull/4812/head 0.101.0
github-actions[bot] 2 years ago committed by GitHub
parent
commit
996026341c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/workflows/pr-to-master.yml
  2. 2
      .github/workflows/release-draft.yml
  3. 94
      .github/workflows/release-executables.yml
  4. 2
      .github/workflows/release-nightly-dev.yml
  5. 4
      .github/workflows/release-npm.yml
  6. 2
      .github/workflows/release-pr.yml
  7. 4
      .github/workflows/update-sdk-path.yml
  8. 20
      packages/nc-cli/package-lock.json
  9. 13
      packages/nc-gui/components/cell/Currency.vue
  10. 8
      packages/nc-gui/components/cell/Json.vue
  11. 37
      packages/nc-gui/components/cell/MultiSelect.vue
  12. 13
      packages/nc-gui/components/cell/Percent.vue
  13. 39
      packages/nc-gui/components/cell/SingleSelect.vue
  14. 8
      packages/nc-gui/components/dashboard/TreeView.vue
  15. 4
      packages/nc-gui/components/general/ViewIcon.vue
  16. 6
      packages/nc-gui/components/smartsheet/Gallery.vue
  17. 60
      packages/nc-gui/components/smartsheet/Kanban.vue
  18. 2
      packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue
  19. 3
      packages/nc-gui/components/virtual-cell/Formula.vue
  20. 1
      packages/nc-gui/components/virtual-cell/barcode/Barcode.vue
  21. 3
      packages/nc-gui/composables/useMultiSelect/index.ts
  22. 8
      packages/nc-gui/composables/useProject.ts
  23. 748
      packages/nc-gui/lang/cs.json
  24. 748
      packages/nc-gui/lang/eu.json
  25. 160
      packages/nc-gui/lang/fr.json
  26. 748
      packages/nc-gui/lang/sk.json
  27. 3
      packages/nc-gui/lib/enums.ts
  28. 3
      packages/nc-gui/nuxt.config.ts
  29. 76
      packages/nc-gui/package-lock.json
  30. 2
      packages/nc-gui/package.json
  31. 18
      packages/nc-gui/pages/[projectType]/[projectId]/index/index.vue
  32. 10
      packages/nc-gui/pages/index/index/[projectId].vue
  33. 65
      packages/nc-plugin/package-lock.json
  34. 112
      packages/noco-docs/content/en/getting-started/installation.md
  35. 2
      packages/noco-docs/content/en/setup-and-usages/dashboard.md
  36. 99
      packages/noco-docs/content/en/setup-and-usages/meta-management.md
  37. 21
      packages/noco-docs/content/en/setup-and-usages/project-settings.md
  38. 2
      packages/noco-docs/content/en/setup-and-usages/sync-schema.md
  39. 9233
      packages/noco-docs/package-lock.json
  40. 17
      packages/nocodb-sdk/package-lock.json
  41. 17
      packages/nocodb-sdk/src/lib/formulaHelpers.ts
  42. 511
      packages/nocodb/package-lock.json
  43. 6
      packages/nocodb/package.json
  44. 2
      packages/nocodb/src/lib/Noco.ts
  45. 132
      packages/nocodb/src/lib/db/sql-client/lib/mysql/mysql.queries.ts
  46. 14
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
  47. 2
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts
  48. 86
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts
  49. 15
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts
  50. 53
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts
  51. 6
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/sortV2.ts
  52. 21
      packages/nocodb/src/lib/meta/api/columnApis.ts
  53. 13
      packages/nocodb/src/lib/meta/api/sync/helpers/job.ts
  54. 6
      packages/nocodb/src/lib/meta/helpers/populateSamplePayload.ts
  55. 2
      packages/nocodb/src/lib/models/Base.ts
  56. 13
      packages/nocodb/src/lib/models/Filter.ts
  57. 27
      packages/nocodb/src/lib/models/Model.ts
  58. 2
      packages/nocodb/src/lib/version-upgrader/NcUpgrader.ts
  59. 34
      packages/nocodb/src/lib/version-upgrader/ncFilterUpgrader.ts
  60. 14
      tests/playwright/package-lock.json
  61. 13
      tests/playwright/pages/Dashboard/common/Cell/DateTimeCell.ts
  62. 12
      tests/playwright/tests/columnFormula.spec.ts
  63. 3
      tests/playwright/tests/language.spec.ts

2
.github/workflows/pr-to-master.yml

@ -55,7 +55,7 @@ jobs:
echo "Pull Request URL - ${{ steps.cpr.outputs.pr_url }}"
- name: automerge
if: ${{ github.event.inputs.targetEnv == 'PROD' || inputs.targetEnv == 'PROD' }}
uses: "pascalgn/automerge-action@v0.14.3"
uses: "pascalgn/automerge-action@v0.15.5"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
PULL_REQUEST: "${{ steps.cpr.outputs.pr_number }}"

2
.github/workflows/release-draft.yml

@ -56,7 +56,7 @@ jobs:
echo "TARGET_SHA=${TARGET_SHA}" >> $GITHUB_OUTPUT
echo "Setting TARGET_SHA: ${TARGET_SHA}"
- name: Create tag
uses: actions/github-script@v3
uses: actions/github-script@v6
with:
# need workflows permission but it's not in GITHUB_TOKEN scope
# need a custom PAT with workflows permission here

94
.github/workflows/release-executables.yml

@ -21,14 +21,6 @@ jobs:
build-executables:
runs-on: ubuntu-latest
steps:
# Get the latest draft release for asset upload url
- uses: cardinalby/git-get-release-action@v1
id: get_release
env:
GITHUB_TOKEN: ${{ secrets.NC_GITHUB_TOKEN }}
with:
latest: 1
draft: true
- uses: actions/checkout@v3
- name: Cache node modules
id: cache-npm
@ -107,54 +99,23 @@ jobs:
mv ./dist/Noco-macos-arm64 ./mac-dist/
mv ./dist/Noco-macos-x64 ./mac-dist/
- name: Upload win-arm64 build to asset
- name: Upload executables to asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./scripts/pkg-executable/dist/Noco-win-arm64.exe
asset_name: Noco-win-arm64.exe
asset_content_type: application/octet-stream
- name: Upload win-x64 build to asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./scripts/pkg-executable/dist/Noco-win-x64.exe
asset_name: Noco-win-x64.exe
asset_content_type: application/octet-stream
- name: Upload linux-arm64 build to asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./scripts/pkg-executable/dist/Noco-linux-arm64
asset_name: Noco-linux-arm64
asset_content_type: application/octet-stream
- name: Upload linux-x64 build to asset
uses: actions/upload-release-asset@v1
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./scripts/pkg-executable/dist/Noco-linux-x64
asset_name: Noco-linux-x64
asset_content_type: application/octet-stream
files: |
./scripts/pkg-executable/dist/Noco-win-arm64.exe
./scripts/pkg-executable/dist/Noco-win-x64.exe
./scripts/pkg-executable/dist/Noco-linux-arm64
./scripts/pkg-executable/dist/Noco-linux-x64
- uses: actions/upload-artifact@master
with:
name: ${{ github.event.inputs.tag || inputs.tag }}
path: scripts/pkg-executable/mac-dist
retention-days: 1
outputs:
upload_url: ${{ steps.get_release.outputs.upload_url }}
sign-mac-executables:
runs-on: macos-latest
needs: build-executables
@ -205,40 +166,15 @@ jobs:
id: compress
- name: Upload macos-x64 build to asset
uses: actions/upload-release-asset@v1
- name: Upload macos executable to asset
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.build-executables.outputs.upload_url }}
asset_path: ./scripts/pkg-executable/mac-dist/Noco-macos-x64
asset_name: Noco-macos-x64
asset_content_type: application/octet-stream
- name: Upload macos-arm64 build to asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.build-executables.outputs.upload_url }}
asset_path: ./scripts/pkg-executable/mac-dist/Noco-macos-arm64
asset_name: Noco-macos-arm64
asset_content_type: application/octet-stream
- name: Upload macos compressed build(for homebrew) to asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.build-executables.outputs.upload_url }}
asset_path: ./scripts/pkg-executable/mac-dist/nocodb.tar.gz
asset_name: nocodb.tar.gz
asset_content_type: application/octet-stream
files: |
./scripts/pkg-executable/mac-dist/Noco-macos-x64
./scripts/pkg-executable/mac-dist/Noco-macos-arm64
./scripts/pkg-executable/mac-dist/nocodb.tar.gz
- name: Generate Homebrew Formula class and push
run: |
@ -267,7 +203,3 @@ jobs:
git commit ./Formula/nocodb.rb -m "Automatic publish"
git push

2
.github/workflows/release-nightly-dev.yml

@ -21,7 +21,7 @@ jobs:
TAG_NAME=${CURRENT_DATE}-${CURRENT_TIME}
IS_DAILY='Y'
# Get current version
CURRENT_VERSION=$(basename $(curl -fs -o/dev/null -w %{redirect_url} https://github.com/nocodb/nocodb/releases/latest))
CURRENT_VERSION=$(curl -fs https://docs.nocodb.com/releases | grep article | grep div | grep h2 | grep 'id\="[^"]*' -o | cut -c 5-)
# Set the tag
if [[ ${{ github.event_name }} == 'workflow_dispatch' ]]; then
IS_DAILY='N'

4
.github/workflows/release-npm.yml

@ -68,7 +68,7 @@ jobs:
- name: Create Pull Request
if: ${{ github.event.inputs.targetEnv == 'PROD' || inputs.targetEnv == 'PROD' }}
id: cpr
uses: peter-evans/create-pull-request@v3
uses: peter-evans/create-pull-request@v4.2.3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
@ -84,7 +84,7 @@ jobs:
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
- name: automerge
if: ${{ github.event.inputs.targetEnv == 'PROD' || inputs.targetEnv == 'PROD' }}
uses: "pascalgn/automerge-action@v0.14.3"
uses: "pascalgn/automerge-action@v0.15.5"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
PULL_REQUEST: "${{ steps.cpr.outputs.pull-request-number }}"

2
.github/workflows/release-pr.yml

@ -33,7 +33,7 @@ jobs:
# Get current PR number
PR_NUMBER=${{github.event.number}}
# Get current version
CURRENT_VERSION=$(basename $(curl -fs -o/dev/null -w %{redirect_url} https://github.com/nocodb/nocodb/releases/latest))
CURRENT_VERSION=$(curl -fs https://docs.nocodb.com/releases | grep article | grep div | grep h2 | grep 'id\="[^"]*' -o | cut -c 5-)
# Construct tag name
TAG_NAME=pr-${PR_NUMBER}-${CURRENT_DATE}-${CURRENT_TIME}
echo "TARGET_TAG=${TAG_NAME}" >> $GITHUB_OUTPUT

4
.github/workflows/update-sdk-path.yml

@ -27,7 +27,7 @@ jobs:
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v3
uses: peter-evans/create-pull-request@v4.2.3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
@ -41,7 +41,7 @@ jobs:
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
- name: automerge
uses: "pascalgn/automerge-action@v0.14.3"
uses: "pascalgn/automerge-action@v0.15.5"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
PULL_REQUEST: "${{ steps.cpr.outputs.pull-request-number }}"

20
packages/nc-cli/package-lock.json generated

@ -8753,13 +8753,10 @@
"dev": true
},
"node_modules/json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
"integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==",
"dev": true,
"dependencies": {
"minimist": "^1.2.5"
},
"bin": {
"json5": "lib/cli.js"
},
@ -22229,13 +22226,10 @@
"dev": true
},
"json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz",
"integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==",
"dev": true
},
"jsonfile": {
"version": "6.1.0",

13
packages/nc-gui/components/cell/Currency.vue

@ -14,7 +14,18 @@ const column = inject(ColumnInj)!
const editEnabled = inject(EditModeInj)!
const vModel = useVModel(props, 'modelValue', emit)
const _vModel = useVModel(props, 'modelValue', emit)
const vModel = computed({
get: () => _vModel.value,
set: (value: unknown) => {
if (value === '') {
_vModel.value = null
} else {
_vModel.value = value as number
}
},
})
const lastSaved = ref()

8
packages/nc-gui/components/cell/Json.vue

@ -123,8 +123,8 @@ useSelectedCellKeyupListener(active, (e) => {
<template>
<component :is="isExpanded ? AModal : 'div'" v-model:visible="isExpanded" :closable="false" centered :footer="null">
<div v-if="editEnabled && !readonly" class="flex flex-col w-full">
<div class="flex flex-row justify-between pt-1 pb-2">
<div v-if="editEnabled && !readonly" class="flex flex-col w-full" @mousedown.stop @mouseup.stop @click.stop>
<div class="flex flex-row justify-between pt-1 pb-2" @mousedown.stop>
<a-button type="text" size="small" @click="isExpanded = !isExpanded">
<CilFullscreenExit v-if="isExpanded" class="h-2.5" />
@ -134,8 +134,8 @@ useSelectedCellKeyupListener(active, (e) => {
<div v-if="!isForm || isExpanded" class="flex flex-row">
<a-button type="text" size="small" :onclick="clear"><div class="text-xs">Cancel</div></a-button>
<a-button type="primary" size="small" :disabled="!!error || localValue === vModel">
<div class="text-xs" @click="onSave">Save</div>
<a-button type="primary" size="small" :disabled="!!error || localValue === vModel" @click="onSave">
<div class="text-xs">Save</div>
</a-button>
</div>
</div>

37
packages/nc-gui/components/cell/MultiSelect.vue

@ -19,6 +19,7 @@ import {
useEventListener,
useMetas,
useProject,
useRoles,
useSelectedCellKeyupListener,
watch,
} from '#imports'
@ -57,6 +58,8 @@ const { $api } = useNuxtApp()
const { getMeta } = useMetas()
const { hasRole } = useRoles()
const { isPg, isMysql } = useProject()
// a variable to keep newly created options value
@ -80,6 +83,10 @@ const isOptionMissing = computed(() => {
return (options.value ?? []).every((op) => op.title !== searchVal.value)
})
const hasEditRoles = computed(() => hasRole('owner', true) || hasRole('creator', true) || hasRole('editor', true))
const editAllowed = computed(() => hasEditRoles.value && (active.value || editable.value))
const vModel = computed({
get: () => {
const selected = selectedIds.value.reduce((acc, id) => {
@ -154,10 +161,12 @@ watch(
)
watch(isOpen, (n, _o) => {
if (!n) {
aselect.value?.$el?.querySelector('input')?.blur()
} else {
aselect.value?.$el?.querySelector('input')?.focus()
if (editAllowed.value) {
if (!n) {
aselect.value?.$el?.querySelector('input')?.blur()
} else {
aselect.value?.$el?.querySelector('input')?.focus()
}
}
})
@ -167,7 +176,7 @@ useSelectedCellKeyupListener(active, (e) => {
isOpen.value = false
break
case 'Enter':
if (active.value && !isOpen.value) {
if (editAllowed.value && active.value && !isOpen.value) {
isOpen.value = true
}
break
@ -179,6 +188,10 @@ useSelectedCellKeyupListener(active, (e) => {
// skip
break
default:
if (!editAllowed.value) {
e.preventDefault()
break
}
// toggle only if char key pressed
if (!(e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) && e.key?.length === 1) {
e.stopPropagation()
@ -272,14 +285,14 @@ const onTagClick = (e: Event, onClose: Function) => {
:bordered="false"
clear-icon
show-search
:show-arrow="!readOnly"
:show-arrow="hasEditRoles && !readOnly && (editable || (active && vModel.length === 0))"
:open="isOpen && (active || editable)"
:disabled="readOnly"
:class="{ '!ml-[-8px]': readOnly }"
:class="{ '!ml-[-8px]': readOnly, 'caret-transparent': !hasEditRoles }"
:dropdown-class-name="`nc-dropdown-multi-select-cell ${isOpen ? 'active' : ''}`"
@search="search"
@keydown.stop
@click="isOpen = (active || editable) && !isOpen"
@click="isOpen = editAllowed && !isOpen"
>
<a-select-option
v-for="op of options"
@ -303,7 +316,11 @@ const onTagClick = (e: Event, onClose: Function) => {
</a-tag>
</a-select-option>
<a-select-option v-if="searchVal && isOptionMissing && !isPublic" :key="searchVal" :value="searchVal">
<a-select-option
v-if="searchVal && isOptionMissing && !isPublic && (hasRole('owner', true) || hasRole('creator', true))"
:key="searchVal"
:value="searchVal"
>
<div class="flex gap-2 text-gray-500 items-center h-full">
<MdiPlusThick class="min-w-4" />
<div class="text-xs whitespace-normal">
@ -318,7 +335,7 @@ const onTagClick = (e: Event, onClose: Function) => {
class="rounded-tag nc-selected-option"
:style="{ display: 'flex', alignItems: 'center' }"
:color="options.find((el) => el.title === val)?.color"
:closable="(active || editable) && (vModel.length > 1 || !column?.rqd)"
:closable="editAllowed && (active || editable) && (vModel.length > 1 || !column?.rqd)"
:close-icon="h(MdiCloseCircle, { class: ['ms-close-icon'] })"
@click="onTagClick($event, onClose)"
@close="onClose"

13
packages/nc-gui/components/cell/Percent.vue

@ -12,7 +12,18 @@ const emits = defineEmits(['update:modelValue'])
const editEnabled = inject(EditModeInj)
const vModel = useVModel(props, 'modelValue', emits)
const _vModel = useVModel(props, 'modelValue', emits)
const vModel = computed({
get: () => _vModel.value,
set: (value) => {
if (value === '') {
_vModel.value = null
} else {
_vModel.value = value
}
},
})
const focus: VNodeRef = (el) => {
;(el as HTMLInputElement)?.focus()

39
packages/nc-gui/components/cell/SingleSelect.vue

@ -14,6 +14,7 @@ import {
extractSdkResponseErrorMsg,
inject,
ref,
useRoles,
useSelectedCellKeyupListener,
watch,
} from '#imports'
@ -49,6 +50,8 @@ const searchVal = ref()
const { getMeta } = useMetas()
const { hasRole } = useRoles()
const { isPg, isMysql } = useProject()
// a variable to keep newly created option value
@ -73,6 +76,10 @@ const isOptionMissing = computed(() => {
return (options.value ?? []).every((op) => op.title !== searchVal.value)
})
const hasEditRoles = computed(() => hasRole('owner', true) || hasRole('creator', true) || hasRole('editor', true))
const editAllowed = computed(() => hasEditRoles.value && (active.value || editable.value))
const vModel = computed({
get: () => tempSelectedOptState.value ?? modelValue,
set: (val) => {
@ -87,10 +94,12 @@ const vModel = computed({
})
watch(isOpen, (n, _o) => {
if (!n) {
aselect.value?.$el?.querySelector('input')?.blur()
} else {
aselect.value?.$el?.querySelector('input')?.focus()
if (editAllowed.value) {
if (!n) {
aselect.value?.$el?.querySelector('input')?.blur()
} else {
aselect.value?.$el?.querySelector('input')?.focus()
}
}
})
@ -100,11 +109,15 @@ useSelectedCellKeyupListener(active, (e) => {
isOpen.value = false
break
case 'Enter':
if (active.value && !isOpen.value) {
if (editAllowed.value && active.value && !isOpen.value) {
isOpen.value = true
}
break
default:
if (!editAllowed.value) {
e.preventDefault()
break
}
// toggle only if char key pressed
if (!(e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) && e.key?.length === 1) {
e.stopPropagation()
@ -174,7 +187,7 @@ const toggleMenu = (e: Event) => {
vModel.value = ''
return
}
isOpen.value = (active.value || editable.value) && !isOpen.value
isOpen.value = editAllowed.value && !isOpen.value
}
</script>
@ -183,11 +196,12 @@ const toggleMenu = (e: Event) => {
ref="aselect"
v-model:value="vModel"
class="w-full"
:allow-clear="!column.rqd && active"
:class="{ 'caret-transparent': !hasEditRoles }"
:allow-clear="!column.rqd && editAllowed"
:bordered="false"
:open="isOpen && (active || editable)"
:open="isOpen"
:disabled="readOnly"
:show-arrow="!readOnly && (active || editable || vModel === null)"
:show-arrow="hasEditRoles && !readOnly && (editable || (active && vModel === null))"
:dropdown-class-name="`nc-dropdown-single-select-cell ${isOpen ? 'active' : ''}`"
show-search
@select="isOpen = false"
@ -216,8 +230,11 @@ const toggleMenu = (e: Event) => {
</span>
</a-tag>
</a-select-option>
<a-select-option v-if="searchVal && isOptionMissing && !isPublic" :key="searchVal" :value="searchVal">
<a-select-option
v-if="searchVal && isOptionMissing && !isPublic && (hasRole('owner', true) || hasRole('creator', true))"
:key="searchVal"
:value="searchVal"
>
<div class="flex gap-2 text-gray-500 items-center h-full">
<MdiPlusThick class="min-w-4" />
<div class="text-xs whitespace-normal">

8
packages/nc-gui/components/dashboard/TreeView.vue

@ -35,7 +35,7 @@ const { addTab, updateTab } = useTabs()
const { $api, $e } = useNuxtApp()
const { bases, tables, loadTables, isSharedBase } = useProject()
const { project, loadProject, bases, tables, loadTables, isSharedBase } = useProject()
const { activeTab } = useTabs()
@ -324,6 +324,12 @@ const setIcon = async (icon: string, table: TableType) => {
message.error(await extractSdkResponseErrorMsg(e))
}
}
onMounted(async () => {
if (!project.value?.id) {
await loadProject()
}
})
</script>
<template>

4
packages/nc-gui/components/general/ViewIcon.vue

@ -10,7 +10,7 @@ const props = defineProps<{
const viewMeta = toRef(props, 'meta')
</script>
<template>
<template v-if="viewMeta">
<IcIcon
v-if="viewMeta?.meta?.icon"
:data-testid="`nc-icon-${viewMeta?.meta?.icon}`"
@ -19,7 +19,7 @@ const viewMeta = toRef(props, 'meta')
/>
<component
:is="viewIcons[viewMeta.type]?.icon"
v-else
v-else-if="viewMeta?.type"
class="nc-view-icon group-hover"
:style="{ color: viewIcons[viewMeta.type]?.color }"
/>

6
packages/nc-gui/components/smartsheet/Gallery.vue

@ -17,6 +17,7 @@ import {
createEventHook,
extractPkFromRow,
inject,
isLTAR,
nextTick,
onMounted,
provide,
@ -210,7 +211,10 @@ watch(view, async (nextView) => {
</template>
<div v-for="col in fieldsWithoutCover" :key="`record-${record.row.id}-${col.id}`">
<div v-if="!isRowEmpty(record, col)" class="flex flex-col space-y-1 px-4 mb-6 bg-gray-50 rounded-lg w-full">
<div
v-if="!isRowEmpty(record, col) || isLTAR(col.uidt)"
class="flex flex-col space-y-1 px-4 mb-6 bg-gray-50 rounded-lg w-full"
>
<div class="flex flex-row w-full justify-start border-b-1 border-gray-100 py-2.5">
<div class="w-full text-gray-600">
<LazySmartsheetHeaderVirtualCell v-if="isVirtualCol(col)" :column="col" :hide-menu="true" />

60
packages/nc-gui/components/smartsheet/Kanban.vue

@ -13,6 +13,7 @@ import {
MetaInj,
OpenNewRecordFormHookInj,
inject,
isLTAR,
onBeforeMount,
onBeforeUnmount,
provide,
@ -472,35 +473,40 @@ watch(view, async (nextView) => {
:key="`record-${record.row.id}-${col.id}`"
class="flex flex-col rounded-lg w-full"
>
<!-- Smartsheet Header (Virtual) Cell -->
<div v-if="!isRowEmpty(record, col)" class="flex flex-row w-full justify-start pt-2">
<div class="w-full text-gray-400">
<LazySmartsheetHeaderVirtualCell v-if="isVirtualCol(col)" :column="col" :hide-menu="true" />
<LazySmartsheetHeaderCell v-else :column="col" :hide-menu="true" />
<div v-if="!isRowEmpty(record, col) || isLTAR(col.uidt)">
<!-- Smartsheet Header (Virtual) Cell -->
<div class="flex flex-row w-full justify-start pt-2">
<div class="w-full text-gray-400">
<LazySmartsheetHeaderVirtualCell
v-if="isVirtualCol(col)"
:column="col"
:hide-menu="true"
/>
<LazySmartsheetHeaderCell v-else :column="col" :hide-menu="true" />
</div>
</div>
</div>
<!-- Smartsheet (Virtual) Cell -->
<div
v-if="!isRowEmpty(record, col)"
class="flex flex-row w-full items-center justify-start pl-[6px]"
:class="{ '!ml-[-12px]': col.uidt === UITypes.SingleSelect }"
>
<LazySmartsheetVirtualCell
v-if="isVirtualCol(col)"
v-model="record.row[col.title]"
class="text-sm pt-1"
:column="col"
:row="record"
/>
<LazySmartsheetCell
v-else
v-model="record.row[col.title]"
class="text-sm pt-1"
:column="col"
:edit-enabled="false"
:read-only="true"
/>
<!-- Smartsheet (Virtual) Cell -->
<div
class="flex flex-row w-full items-center justify-start pl-[6px]"
:class="{ '!ml-[-12px]': col.uidt === UITypes.SingleSelect }"
>
<LazySmartsheetVirtualCell
v-if="isVirtualCol(col)"
v-model="record.row[col.title]"
class="text-sm pt-1"
:column="col"
:row="record"
/>
<LazySmartsheetCell
v-else
v-model="record.row[col.title]"
class="text-sm pt-1"
:column="col"
:edit-enabled="false"
:read-only="true"
/>
</div>
</div>
</div>
</a-card>

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

@ -236,7 +236,7 @@ defineExpose({
:key="`${i}_7`"
v-model:value="filter.value"
class="nc-filter-value-select"
:disabled="filter.readOnly"
:disabled="filter.readOnly || !filter.fk_column_id"
@click.stop
@input="saveOrUpdate(filter, i)"
/>

3
packages/nc-gui/components/virtual-cell/Formula.vue

@ -24,11 +24,10 @@ const { showEditNonEditableFieldWarning, showClearNonEditableFieldWarning, activ
<template #title>
<span class="font-bold">{{ column.colOptions.error }}</span>
</template>
<span>ERR!</span>
</a-tooltip>
<div class="p-2" @dblclick="activateShowEditNonEditableFieldWarning">
<div v-else class="p-2" @dblclick="activateShowEditNonEditableFieldWarning">
<div v-if="urls" v-html="urls" />
<div v-else>{{ result }}</div>

1
packages/nc-gui/components/virtual-cell/barcode/Barcode.vue

@ -46,7 +46,6 @@ const { showEditNonEditableFieldWarning, showClearNonEditableFieldWarning } = us
v-if="showBarcode"
:barcode-value="barcodeValue"
:barcode-format="barcodeMeta.barcodeFormat"
class="nc-barcode-svg"
@on-click-barcode="showBarcodeModal"
>
<template #barcodeRenderError>

3
packages/nc-gui/composables/useMultiSelect/index.ts

@ -267,7 +267,8 @@ export function useMultiSelect(
// copy - ctrl/cmd +c
case 67:
// set clipboard context only if single cell selected
if (selectedRange.isSingleCell() && rowObj.row[columnObj.title!]) {
// or if selected range is empty
if (selectedRange.isSingleCell() || (selectedRange.isEmpty() && rowObj && columnObj)) {
clipboardContext = {
value: rowObj.row[columnObj.title!],
uidt: columnObj.uidt as UITypes,

8
packages/nc-gui/composables/useProject.ts

@ -1,6 +1,7 @@
import type { BaseType, OracleUi, ProjectType, TableType } from 'nocodb-sdk'
import { SqlUiFactory } from 'nocodb-sdk'
import { isString } from '@vueuse/core'
import { useRoute } from 'vue-router'
import {
ClientType,
computed,
@ -11,7 +12,6 @@ import {
useInjectionState,
useNuxtApp,
useRoles,
useRoute,
useRouter,
useTheme,
} from '#imports'
@ -42,9 +42,9 @@ const [setup, use] = useInjectionState(() => {
const lastOpenedViewMap = ref<Record<string, string>>({})
let forcedProjectId: string | undefined
const forcedProjectId = ref<string>()
const projectId = computed(() => forcedProjectId || (route.params.projectId as string))
const projectId = computed(() => forcedProjectId.value || (route.params.projectId as string))
// todo: refactor path param name and variable name
const projectType = $computed(() => route.params.projectType as string)
@ -107,7 +107,7 @@ const [setup, use] = useInjectionState(() => {
}
async function loadProject(withTheme = true, forcedId?: string) {
if (forcedId) forcedProjectId = forcedId
if (forcedId) forcedProjectId.value = forcedId
if (projectType === 'base') {
try {
const baseData = await api.public.sharedBaseGet(route.params.projectId as string)

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

@ -0,0 +1,748 @@
{
"general": {
"home": "Domů",
"load": "Načíst",
"open": "Otevřít",
"close": "Zavřít",
"yes": "Ano",
"no": "Ne",
"ok": "OK",
"and": "a",
"or": "nebo",
"add": "Přidat",
"edit": "Upravit",
"remove": "Odstranit",
"save": "Uložit",
"cancel": "Zrušit",
"submit": "Potvrdit",
"create": "Vytvořit",
"duplicate": "Duplikovat",
"insert": "Vložit",
"delete": "Smazat",
"update": "Aktualizovat",
"rename": "Přejmenovat",
"reload": "Znovu načíst",
"reset": "Obnovit",
"install": "Instalovat",
"show": "Zobrazit",
"hide": "Skrýt",
"showAll": "Zobrazit vše",
"hideAll": "Skrýt vše",
"showMore": "Zobrazit více",
"showOptions": "Zobrazit možnosti",
"hideOptions": "Skrýt možnosti",
"showMenu": "Zobrazit menu",
"hideMenu": "Skrýt menu",
"addAll": "Přidat vše",
"removeAll": "Odstranit vše",
"signUp": "REGISTROVAT",
"signIn": "PŘIHLÁSIT SE",
"signOut": "Odhlásit se",
"required": "Vyžadováno",
"preferred": "Preferováno",
"mandatory": "Povinné",
"loading": "Načítání ...",
"title": "Název",
"upload": "Nahrát",
"download": "Stáhnout",
"default": "Výchozí",
"more": "Více",
"less": "Méně",
"event": "Událost",
"condition": "Podmínka",
"after": "Po",
"before": "Před",
"search": "Hledat",
"notification": "Oznámení",
"reference": "Reference",
"function": "Funkce",
"confirm": "Potvrdit",
"generate": "Generovat",
"copy": "Kopírovat",
"misc": "Ostatní",
"lock": "Uzamknout",
"unlock": "Odemknout",
"credentials": "Přihlašovací údaje",
"help": "Pomoc",
"questions": "Otázky",
"reachOut": "Reach out here",
"betaNote": "Tato funkce je momentálně v beta verzi.",
"moreInfo": "Více informací naleznete zde",
"logs": "Protokoly",
"groupingField": "Grouping Field",
"insertAfter": "Vložit za",
"insertBefore": "Vložit před",
"hideField": "Skrýt pole",
"sortAsc": "Seřadit vzestupně",
"sortDesc": "Seřadit sestupně"
},
"objects": {
"project": "Projekt",
"projects": "Projekty",
"table": "Tabulka",
"tables": "Tabulky",
"field": "Pole",
"fields": "Pole",
"column": "Sloupec",
"columns": "Sloupce",
"page": "Stránka",
"pages": "Stránky",
"record": "záznam",
"records": "záznamy",
"webhook": "Webhook",
"webhooks": "Webhooky",
"view": "Pohled",
"views": "Pohledy",
"viewType": {
"grid": "Mřížka",
"gallery": "Galerie",
"form": "Formulář",
"kanban": "Kanban",
"calendar": "Kalendář"
},
"user": "Uživatel",
"users": "Uživatelé",
"role": "Role",
"roles": "Role",
"roleType": {
"owner": "Vlastník",
"creator": "Autor",
"editor": "Editor",
"commenter": "Komentátor",
"viewer": "Sledující",
"orgLevelCreator": "Organization Level Creator",
"orgLevelViewer": "Organization Level Viewer"
},
"sqlVIew": "SQL pohled"
},
"datatype": {
"ID": "ID",
"ForeignKey": "Cizí klíč",
"SingleLineText": "Jednořádkový text",
"LongText": "Dlouhý text",
"Attachment": "Příloha",
"Checkbox": "Zaškrtávací políčko",
"MultiSelect": "Vícenásobný výběr",
"SingleSelect": "Jednoduchý výběr",
"Collaborator": "Spolupracovník",
"Date": "Datum",
"Year": "Rok",
"Time": "Čas",
"PhoneNumber": "Telefonní číslo",
"Email": "E-mail",
"URL": "URL",
"Number": "Číslo",
"Decimal": "Desetinné číslo",
"Currency": "Měna",
"Percent": "Procenta",
"Duration": "Doba trvání",
"Rating": "Hodnocení",
"Formula": "Vzorec",
"Rollup": "Rollup",
"Count": "Počet",
"Lookup": "Lookup",
"DateTime": "Datum a čas",
"CreateTime": "Create Time",
"LastModifiedTime": "Čas poslední úpravy",
"AutoNumber": "Auto Number",
"Barcode": "Čárový kód",
"Button": "Tlačítko",
"Password": "Heslo",
"relationProperties": {
"noAction": "Žádná akce",
"cascade": "Kaskádově",
"restrict": "Restrict",
"setNull": "Nastavit NULL",
"setDefault": "Nastavit výchozí"
}
},
"filterOperation": {
"isEqual": "je rovno",
"isNotEqual": "není rovno",
"isLike": "je jako",
"isNot like": "není jako",
"isEmpty": "je prázdný",
"isNotEmpty": "is not empty",
"isNull": "is null",
"isNotNull": "is not null"
},
"title": {
"erdView": "ERD View",
"newProj": "New Project",
"myProject": "My Projects",
"formTitle": "Form Title",
"collabView": "Collaborative View",
"lockedView": "Locked View",
"personalView": "Personal View",
"appStore": "App Store",
"teamAndAuth": "Team & Auth",
"rolesUserMgmt": "Roles & Users Management",
"userMgmt": "Users Management",
"apiTokenMgmt": "API Tokens Management",
"rolesMgmt": "Roles Management",
"projMeta": "Project Metadata",
"metaMgmt": "Meta Management",
"metadata": "Metadata",
"exportImportMeta": "Export / Import Metadata",
"uiACL": "UI Access Control",
"metaOperations": "Metadata Operations",
"audit": "Audit",
"auditLogs": "Audit Log",
"sqlMigrations": "SQL migrace",
"dbCredentials": "Database Credentials",
"advancedParameters": "SSL & Advanced parameters",
"headCreateProject": "Vytvořit projekt | NocoDB",
"headLogin": "Přihlásit se | NocoDB",
"resetPassword": "Obnovit heslo",
"teamAndSettings": "Tým a nastavení",
"apiDocs": "API Docs",
"importFromAirtable": "Import From Airtable",
"generateToken": "Generovat token",
"APIsAndSupport": "APIs & Support",
"helpCenter": "Help center",
"swaggerDocumentation": "Swagger Documentation",
"quickImportFrom": "Rychlý import z",
"quickImport": "Rychlý import",
"advancedSettings": "Pokročilá nastavení",
"codeSnippet": "Úryvek kódu",
"keyboardShortcut": "Klávesové zkratky"
},
"labels": {
"createdBy": "Vytvořil/a",
"notifyVia": "Upozornit pomocí",
"projName": "Název projektu",
"tableName": "Název tabulky",
"viewName": "Název zobrazení",
"viewLink": "Zobrazit odkaz",
"columnName": "Název sloupce",
"columnType": "Typ sloupce",
"roleName": "Název role",
"roleDescription": "Popis role",
"databaseType": "Typ v databázi",
"lengthValue": "Délka / hodnota",
"dbType": "Typ databáze",
"sqliteFile": "SQLite soubor",
"hostAddress": "Adresa hostitele",
"port": "Číslo portu",
"username": "Uživatelské jméno",
"password": "Heslo",
"schemaName": "Název schématu",
"database": "Databáze",
"action": "Akce",
"actions": "Akce",
"operation": "Operace",
"operationType": "Typ operace",
"operationSubType": "Podtyp operace",
"description": "Popis",
"authentication": "Authentication",
"token": "Token",
"where": "Kde",
"cache": "Mezipaměť",
"chat": "Chat",
"email": "E-mail",
"storage": "Úložiště",
"uiAcl": "UI-ACL",
"models": "Modely",
"syncState": "Stav synchronizace",
"created": "Vytvořeno",
"sqlOutput": "Výstup SQL",
"addOption": "Přidat možnost",
"qrCodeValueColumn": "Sloupec s hodnotou QR kódu",
"barcodeValueColumn": "Sloupec s hodnotou čárového kódu",
"barcodeFormat": "Formát čárového kódu",
"qrCodeValueTooLong": "Příliš mnoho znaků pro QR kód",
"barcodeValueTooLong": "Příliš mnoho znaků pro čárový kód",
"aggregateFunction": "Agregační funkce",
"dbCreateIfNotExists": "Databáze : vytvořit, pokud neexistuje",
"clientKey": "Klíč klienta",
"clientCert": "Certifikát klienta",
"serverCA": "CA serveru",
"requriedCa": "Požadovaná CA",
"requriedIdentity": "Required-IDENTITY",
"inflection": {
"tableName": "Inflection - Table name",
"columnName": "Inflection - Column name"
},
"community": {
"starUs1": "Star",
"starUs2": "nás na Githubu",
"bookDemo": "Zarezervujte si DEMO zdarma",
"getAnswered": "Get your questions answered",
"joinDiscord": "Připojte se na Discord",
"joinCommunity": "Připojte se k NocoDB komunitě",
"joinReddit": "Připojte se k /r/NocoDB",
"followNocodb": "Sledovat NocoDB"
},
"docReference": "Odkaz na dokument",
"selectUserRole": "Vybrat uživatelskou roli",
"childTable": "Podřízená tabulka",
"childColumn": "Podřízený sloupec",
"onUpdate": "Při aktualizaci",
"onDelete": "Při odstranění",
"account": "Účet",
"language": "Jazyk",
"primaryColor": "Hlavní barva",
"accentColor": "Barva zvýraznění",
"customTheme": "Vlastní motiv",
"requestDataSource": "Request a data source you need?",
"apiKey": "API klíč",
"sharedBase": "Shared Base",
"importData": "Importovat data",
"importSecondaryViews": "Import Secondary Views",
"importRollupColumns": "Import Rollup Columns",
"importLookupColumns": "Import Lookup Columns",
"importAttachmentColumns": "Import Attachment Columns",
"importFormulaColumns": "Import Formula Columns",
"noData": "Žádná data",
"goToDashboard": "Přejít na přehled",
"importing": "Importing",
"flattenNested": "Flatten Nested",
"downloadAllowed": "Download allowed",
"weAreHiring": "We are Hiring!",
"primaryKey": "Primární klíč",
"hasMany": "má mnoho",
"belongsTo": "patří do",
"manyToMany": "má mnoho vztahů",
"extraConnectionParameters": "Extra connection parameters",
"commentsOnly": "Pouze komentáře",
"documentation": "Dokumentace",
"subscribeNewsletter": "Subscribe to our weekly newsletter",
"signUpWithGoogle": "Sign up with Google",
"signInWithGoogle": "Sign in with Google",
"agreeToTos": "By signing up, you agree to the Terms of Service",
"welcomeToNc": "Welcome to NocoDB!",
"inviteOnlySignup": "Povolit registraci pouze pomocí pozvánky s odkazem"
},
"activity": {
"createProject": "Vytvořit projekt",
"importProject": "Import projektu",
"searchProject": "Vyhledat projekt",
"editProject": "Upravit projekt",
"stopProject": "Zastavit projekt",
"startProject": "Spustit projekt",
"restartProject": "Restartovat projekt",
"deleteProject": "Smazat projekt",
"refreshProject": "Aktualizovat projekty",
"saveProject": "Uložit projekt",
"deleteKanbanStack": "Delete stack?",
"createProjectExtended": {
"extDB": "Vytvořit připojením <br>k externí databázi",
"excel": "Vytvořit projekt z Excelu",
"template": "Vytvořit projekt ze šablony"
},
"OkSaveProject": "Potvrdit a uložit projekt",
"upgrade": {
"available": "Dostupná aktualizace",
"releaseNote": "Seznam změn",
"howTo": "Jak aktualizovat?"
},
"translate": "Pomozte s překladem",
"account": {
"authToken": "Kopírovat ověřovací token",
"swagger": "Swagger: REST API",
"projInfo": "Kopírovat informace o projektu",
"themes": "Motivy"
},
"sort": "Řazení",
"addSort": "Přidat možnost řazení",
"filter": "Filtr",
"addFilter": "Přidat filtr",
"share": "Sdílet",
"shareBase": {
"disable": "Disable shared base",
"enable": "Anyone with the link",
"link": "Shared base link"
},
"invite": "Invite",
"inviteMore": "Invite more",
"inviteTeam": "Invite Team",
"inviteUser": "Invite User",
"inviteToken": "Invite Token",
"newUser": "New User",
"editUser": "Edit user",
"deleteUser": "Remove user from project",
"resendInvite": "Resend invite E-mail",
"copyInviteURL": "Copy invite URL",
"copyPasswordResetURL": "Copy password reset URL",
"newRole": "New role",
"reloadRoles": "Reload roles",
"nextPage": "Next page",
"prevPage": "Previous page",
"nextRecord": "Next record",
"previousRecord": "Previous record",
"copyApiURL": "Copy API URL",
"createTable": "Table Create",
"refreshTable": "Tables Refresh",
"renameTable": "Table Rename",
"deleteTable": "Table Delete",
"addField": "Add new field to this table",
"setPrimary": "Set as Primary value",
"addRow": "Přidat nový řádek",
"saveRow": "Uložit řádek",
"saveAndExit": "Uložit a odejít",
"saveAndStay": "Uložit a zůstat",
"insertRow": "Vložit nový řádek",
"deleteRow": "Odstranit řádek",
"deleteSelectedRow": "Odstranit vybrané řádky",
"importExcel": "Importovat Excel",
"importCSV": "Importovat CSV",
"downloadCSV": "Stáhnout jako CSV",
"downloadExcel": "Stáhnout jako XLSX",
"uploadCSV": "Nahrát CSV",
"import": "Importovat",
"importMetadata": "Importovat metadata",
"exportMetadata": "Exportovat metadata",
"clearMetadata": "Vymazat metadata",
"exportToFile": "Exportovat do souboru",
"changePwd": "Změnit heslo",
"createView": "Vytvořit pohled",
"shareView": "Sdílet pohled",
"listSharedView": "Shared View List",
"ListView": "Seznam pohledů",
"copyView": "Kopírovat pohled",
"renameView": "Přejmenovat pohled",
"deleteView": "Odstranit pohled",
"createGrid": "Create Grid View",
"createGallery": "Create Gallery View",
"createCalendar": "Create Calendar View",
"createKanban": "Create Kanban View",
"createForm": "Create Form View",
"showSystemFields": "Show system fields",
"copyUrl": "Kopírovat URL adresu",
"openTab": "Otevřít novou kartu",
"iFrame": "Copy embeddable HTML code",
"addWebhook": "Přidat nový webhook",
"newToken": "Přidat nový token",
"exportZip": "Exportovat zip archív",
"importZip": "Importovat zip archív",
"metaSync": "Synchronizovat nyní",
"settings": "Nastavení",
"previewAs": "Náhled jako",
"resetReview": "Obnovit náhled",
"testDbConn": "Otestovat připojení k databázi",
"removeDbFromEnv": "Odstranit databázi z prostředí",
"editConnJson": "Edit connection JSON",
"sponsorUs": "Sponsor Us",
"sendEmail": "SEND EMAIL",
"addUserToProject": "Add user to project",
"getApiSnippet": "Get API Snippet",
"clearCell": "Clear cell",
"addFilterGroup": "Add Filter Group",
"linkRecord": "Link record",
"addNewRecord": "Add new record",
"useConnectionUrl": "Use Connection URL",
"toggleCommentsDraw": "Toggle comments draw",
"expandRecord": "Expand Record",
"deleteRecord": "Delete Record",
"erd": {
"showColumns": "Show Columns",
"showPkAndFk": "Show Primary and Foreign Keys",
"showSqlViews": "Show SQL Views",
"showMMTables": "Show Many to Many tables",
"showJunctionTableNames": "Show Junction Table Names"
},
"kanban": {
"collapseStack": "Collapse Stack",
"deleteStack": "Delete Stack",
"stackedBy": "Stacked By",
"chooseGroupingField": "Choose a Grouping Field",
"addOrEditStack": "Add / Edit Stack"
}
},
"tooltip": {
"saveChanges": "Save changes",
"xcDB": "Create a new project",
"extDB": "Supports MySQL, PostgreSQL, SQL Server & SQLite",
"apiRest": "Accessible via REST APIs",
"apiGQL": "Accessible via GraphQL APIs",
"theme": {
"dark": "It does come in Black (^⇧B)",
"light": "Does it come in Black ? (^⇧B)"
},
"addTable": "Add new table",
"inviteMore": "Invite more users",
"toggleNavDraw": "Toggle navigation drawer",
"reloadApiToken": "Reload API tokens",
"generateNewApiToken": "Generate new API token",
"addRole": "Add new role",
"reloadList": "Reload list",
"metaSync": "Sync metadata",
"sqlMigration": "Reload migrations",
"updateRestart": "Update & Restart",
"cancelReturn": "Cancel and Return",
"exportMetadata": "Export all metadata from the meta tables to meta directory.",
"importMetadata": "Import all metadata from the meta directory to meta tables.",
"clearMetadata": "Clear all metadata from meta tables.",
"clientKey": "Select .key file",
"clientCert": "Select .cert file",
"clientCA": "Select CA file"
},
"placeholder": {
"projName": "Enter Project Name",
"password": {
"enter": "Enter the password",
"current": "Current password",
"new": "New password",
"save": "Save password",
"confirm": "Confirm new password"
},
"searchProjectTree": "Search tables",
"searchFields": "Search fields",
"searchColumn": "Search {search} column",
"searchApps": "Search apps",
"searchModels": "Search models",
"noItemsFound": "No items found",
"defaultValue": "Default value",
"filterByEmail": "Filter by E-mail",
"filterQuery": "Filter query",
"selectField": "Select field"
},
"msg": {
"warning": {
"barcode": {
"renderError": "Barcode error - please check compatibility between input and barcode type"
},
"nonEditableFields": {
"computedFieldUnableToClear": "Warning: Computed field - unable to clear text",
"qrFieldsCannotBeDirectlyChanged": "Warning: QR fields cannot be directly changed."
}
},
"info": {
"pasteNotSupported": "Paste operation is not supported on the active cell",
"roles": {
"orgCreator": "Creator can create new projects and access any invited project.",
"orgViewer": "Viewer is not allowed to create new projects but they can access any invited project."
},
"footerInfo": "Rows per page",
"upload": "Select file to Upload",
"upload_sub": "or drag and drop file",
"excelSupport": "Supported: .xls, .xlsx, .xlsm, .ods, .ots",
"excelURL": "Enter excel file URL",
"csvURL": "Enter CSV file URL",
"footMsg": "# of rows to parse to infer datatype",
"excelImport": "sheet(s) are available for import",
"exportMetadata": "Do you want to export metadata from meta tables?",
"importMetadata": "Do you want to import metadata from meta tables?",
"clearMetadata": "Do you want to clear metadata from meta tables?",
"projectEmptyMessage": "Get started by creating a new project",
"stopProject": "Do you want to stop the project?",
"startProject": "Do you want to start the project?",
"restartProject": "Do you want to restart the project?",
"deleteProject": "Do you want to delete the project?",
"shareBasePrivate": "Generate publicly shareable readonly base",
"shareBasePublic": "Anyone on the internet with this link can view",
"userInviteNoSMTP": "Looks like you have not configured mailer yet! Please copy above invite link and send it to",
"dragDropHide": "Drag and drop fields here to hide",
"formInput": "Enter form input label",
"formHelpText": "Add some help text",
"onlyCreator": "Only visible to Creator",
"formDesc": "Add form description",
"beforeEnablePwd": "Restrict access with a password",
"afterEnablePwd": "Access is password restricted",
"privateLink": "This view is shared via a private link",
"privateLinkAdditionalInfo": "People with private link can only see cells visible in this view",
"afterFormSubmitted": "After form is submitted",
"apiOptions": "Access Project via",
"submitAnotherForm": "Show 'Submit Another Form' button",
"showBlankForm": "Show a blank form after 5 seconds",
"emailForm": "E-mail me at",
"showSysFields": "Show system fields",
"filterAutoApply": "Auto apply",
"showMessage": "Show this message",
"viewNotShared": "Current view is not shared!",
"showAllViews": "Show all shared views of this table",
"collabView": "Collaborators with edit permissions or higher can change the view configuration.",
"lockedView": "No one can edit the view configuration until it is unlocked.",
"personalView": "Only you can edit the view configuration. Other collaborators’ personal views are hidden by default.",
"ownerDesc": "Can add/remove creators. And full edit database structures & fields.",
"creatorDesc": "Can fully edit database structure & values.",
"editorDesc": "Can edit records but cannot change structure of database/fields.",
"commenterDesc": "Can view and comment the records but cannot edit anything",
"viewerDesc": "Can view the records but cannot edit anything",
"addUser": "Add new user",
"staticRoleInfo": "System defined roles can't be edited",
"exportZip": "Export project meta to zip file and download.",
"importZip": "Import project meta zip file and restart.",
"importText": "Import NocoDB Project by uploading metadata zip file",
"metaNoChange": "No change identified",
"sqlMigration": "Schema migrations will be created automatically. Create a table and refresh this page.",
"dbConnectionStatus": "Environment validated",
"dbConnected": "Connection was successful",
"notifications": {
"no_new": "No new notifications",
"clear": "Clear"
},
"sponsor": {
"header": "You can help us!",
"message": "We are a tiny team working full time to make NocoDB Open-source. We believe a tool like NocoDB should be available freely to every problem solver on Internet."
},
"loginMsg": "Log In To NocoDB",
"passwordRecovery": {
"message_1": "Please provide the email address you used when you signed up.",
"message_2": "We will send you an email with a link to reset your password.",
"success": "Please check your email to reset the password"
},
"signUp": {
"superAdmin": "You will be the 'Super Admin'",
"alreadyHaveAccount": "Already have an account ?",
"workEmail": "Enter your work email",
"enterPassword": "Enter your password",
"forgotPassword": "Forgot your password ?",
"dontHaveAccount": "Don't have an account ?"
},
"addView": {
"grid": "Add Grid View",
"gallery": "Add Gallery View",
"form": "Add Form View",
"kanban": "Add Kanban View",
"calendar": "Add Calendar View"
},
"tablesMetadataInSync": "Tables metadata is in Sync",
"addMultipleUsers": "You can add multiple comma(,) separated emails",
"enterTableName": "Enter table name",
"addDefaultColumns": "Add default columns",
"tableNameInDb": "Table name as saved in database",
"airtable": {
"credentials": "Where to find this?"
},
"import": {
"clickOrDrag": "Click or drag file to this area to upload"
},
"metaDataRecreated": "Table metadata recreated successfully",
"invalidCredentials": "Invalid credentials",
"downloadingMoreFiles": "Downloading more files",
"copiedToClipboard": "Copied to clipboard",
"requriedFieldsCantBeMoved": "Required field can't be moved",
"updateNotAllowedWithoutPK": "Update not allowed for table which doesn't have primary key",
"autoIncFieldNotEditable": "Auto increment field is not editable",
"editingPKnotSupported": "Editing primary key not supported",
"deletedCache": "Deleted cache successfully",
"cacheEmpty": "Cache is empty",
"exportedCache": "Exported Cache Successfully",
"valueAlreadyInList": "This value is already in the list",
"noColumnsToUpdate": "No columns to update",
"tableDeleted": "Deleted table successfully",
"generatePublicShareableReadonlyBase": "Generate publicly shareable readonly base",
"deleteViewConfirmation": "Are you sure you want to delete this view?",
"deleteTableConfirmation": "Do you want to delete the table",
"showM2mTables": "Show M2M Tables",
"deleteKanbanStackConfirmation": "Deleting this stack will also remove the select option `{stackToBeDeleted}` from the `{groupingField}`. The records will move to the uncategorized stack.",
"computedFieldEditWarning": "Computed field: contents are read-only. Use column edit menu to reconfigure",
"computedFieldDeleteWarning": "Computed field: contents are read-only. Unable to clear content."
},
"error": {
"searchProject": "Your search for {search} found no results",
"invalidChar": "Invalid character in folder path.",
"invalidDbCredentials": "Invalid database credentials.",
"unableToConnectToDb": "Unable to connect to database, please check your database is up.",
"userDoesntHaveSufficientPermission": "User does not exist or have sufficient permission to create schema.",
"dbConnectionStatus": "Invalid database parameters",
"dbConnectionFailed": "Connection Failure:",
"signUpRules": {
"emailReqd": "E-mail is required",
"emailInvalid": "E-mail must be valid",
"passwdRequired": "Password is required",
"passwdLength": "You password must be atleast 8 characters",
"passwdMismatch": "Passwords do not match",
"completeRuleSet": "At least 8 characters with one Uppercase, one number and one special character",
"atLeast8Char": "At least 8 characters",
"atLeastOneUppercase": "One Uppercase letter",
"atLeastOneNumber": "One Number",
"atLeastOneSpecialChar": "One special character",
"allowedSpecialCharList": "Allowed special character list"
},
"invalidURL": "Invalid URL",
"internalError": "Some internal error occurred",
"templateGeneratorNotFound": "Template Generator cannot be found!",
"fileUploadFailed": "Failed to upload file",
"primaryColumnUpdateFailed": "Failed to update primary column",
"formDescriptionTooLong": "Data too long for Form Description",
"columnsRequired": "Following columns are required",
"selectAtleastOneColumn": "At least one column has to be selected",
"columnDescriptionNotFound": "Cannot find the destination column for",
"duplicateMappingFound": "Duplicate mapping found, please remove one of the mapping",
"nullValueViolatesNotNull": "Null value violates not-null constraint",
"sourceHasInvalidNumbers": "Source data contains some invalid numbers",
"sourceHasInvalidBoolean": "Source data contains some invalid boolean values",
"invalidForm": "Invalid Form",
"formValidationFailed": "Form validation failed",
"youHaveBeenSignedOut": "You have been signed out",
"failedToLoadList": "Failed to load list",
"failedToLoadChildrenList": "Failed to load children list",
"deleteFailed": "Delete failed",
"unlinkFailed": "Unlink failed",
"rowUpdateFailed": "Row update failed",
"deleteRowFailed": "Failed to delete row",
"setFormDataFailed": "Failed to set form data",
"formViewUpdateFailed": "Failed to update form view",
"tableNameRequired": "Table name is required",
"nameShouldStartWithAnAlphabetOr_": "Name should start with an alphabet or _",
"followingCharactersAreNotAllowed": "Following characters are not allowed",
"columnNameRequired": "Column name is required",
"projectNameExceeds50Characters": "Project name exceeds 50 characters",
"projectNameCannotStartWithSpace": "Project name cannot start with space",
"requiredField": "Required field",
"ipNotAllowed": "IP not allowed",
"targetFileIsNotAnAcceptedFileType": "Target file is not an accepted file type",
"theAcceptedFileTypeIsCsv": "The accepted file type is .csv",
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "{value} cannot be empty.",
"projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Failed to copy to clipboard"
},
"toast": {
"exportMetadata": "Project metadata exported successfully",
"importMetadata": "Project metadata imported successfully",
"clearMetadata": "Project metadata cleared successfully",
"stopProject": "Project stopped successfully",
"startProject": "Project started successfully",
"restartProject": "Project restarted successfully",
"deleteProject": "Project deleted successfully",
"authToken": "Auth token copied to clipboard",
"projInfo": "Copied project info to clipboard",
"inviteUrlCopy": "Copied invite URL to clipboard",
"createView": "View created successfully",
"formEmailSMTP": "Please activate SMTP plugin in App store for enabling email notification",
"collabView": "Successfully Switched to collaborative view",
"lockedView": "Successfully Switched to locked view",
"futureRelease": "Coming soon!"
},
"success": {
"columnDuplicated": "Column duplicated successfully",
"updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully",
"pluginTested": "Successfully tested plugin settings",
"tableRenamed": "Table renamed successfully",
"viewDeleted": "View deleted successfully",
"primaryColumnUpdated": "Successfully updated as primary column",
"tableDataExported": "Successfully exported all table data",
"updated": "Successfully updated",
"sharedViewDeleted": "Deleted shared view successfully",
"userDeleted": "User deleted successfully",
"viewRenamed": "View renamed successfully",
"tokenGenerated": "Token generated successfully",
"tokenDeleted": "Token deleted successfully",
"userAddedToProject": "Successfully added user to project",
"userAdded": "Successfully added user",
"userDeletedFromProject": "Successfully deleted user from project",
"inviteEmailSent": "Invite Email sent successfully",
"inviteURLCopied": "Invite URL copied to clipboard",
"passwordResetURLCopied": "Password reset URL copied to clipboard",
"shareableURLCopied": "Copied shareable base URL to clipboard!",
"embeddableHTMLCodeCopied": "Copied embeddable HTML code!",
"userDetailsUpdated": "Successfully updated the user details",
"tableDataImported": "Successfully imported table data",
"webhookUpdated": "Webhook details updated successfully",
"webhookDeleted": "Hook deleted successfully",
"webhookTested": "Webhook tested successfully",
"columnUpdated": "Column updated",
"columnCreated": "Column created",
"passwordChanged": "Password changed successfully. Please login again.",
"settingsSaved": "Settings saved successfully",
"roleUpdated": "Role updated successfully"
}
}
}

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

@ -0,0 +1,748 @@
{
"general": {
"home": "Home",
"load": "Load",
"open": "Open",
"close": "Close",
"yes": "Yes",
"no": "No",
"ok": "OK",
"and": "And",
"or": "Or",
"add": "Add",
"edit": "Edit",
"remove": "Remove",
"save": "Save",
"cancel": "Cancel",
"submit": "Submit",
"create": "Create",
"duplicate": "Duplicate",
"insert": "Insert",
"delete": "Delete",
"update": "Update",
"rename": "Rename",
"reload": "Reload",
"reset": "Reset",
"install": "Install",
"show": "Show",
"hide": "Hide",
"showAll": "Show all",
"hideAll": "Hide all",
"showMore": "Show more",
"showOptions": "Show options",
"hideOptions": "Hide options",
"showMenu": "Show menu",
"hideMenu": "Hide menu",
"addAll": "Add all",
"removeAll": "Remove all",
"signUp": "SIGN UP",
"signIn": "SIGN IN",
"signOut": "Sign Out",
"required": "Required",
"preferred": "Preferred",
"mandatory": "Mandatory",
"loading": "Loading ...",
"title": "Title",
"upload": "Upload",
"download": "Download",
"default": "Default",
"more": "More",
"less": "Less",
"event": "Event",
"condition": "Condition",
"after": "After",
"before": "Before",
"search": "Search",
"notification": "Notification",
"reference": "Reference",
"function": "Function",
"confirm": "Confirm",
"generate": "Generate",
"copy": "Copy",
"misc": "Miscellaneous",
"lock": "Lock",
"unlock": "Unlock",
"credentials": "Credentials",
"help": "Help",
"questions": "Questions",
"reachOut": "Reach out here",
"betaNote": "This feature is currently in beta.",
"moreInfo": "More information can be found here",
"logs": "Logs",
"groupingField": "Grouping Field",
"insertAfter": "Insert After",
"insertBefore": "Insert Before",
"hideField": "Hide Field",
"sortAsc": "Sort Ascending",
"sortDesc": "Sort Descending"
},
"objects": {
"project": "Project",
"projects": "Projects",
"table": "Table",
"tables": "Tables",
"field": "Field",
"fields": "Fields",
"column": "Column",
"columns": "Columns",
"page": "Page",
"pages": "Pages",
"record": "record",
"records": "records",
"webhook": "Webhook",
"webhooks": "Webhooks",
"view": "View",
"views": "Views",
"viewType": {
"grid": "Grid",
"gallery": "Gallery",
"form": "Form",
"kanban": "Kanban",
"calendar": "Calendar"
},
"user": "User",
"users": "Users",
"role": "Role",
"roles": "Roles",
"roleType": {
"owner": "Owner",
"creator": "Creator",
"editor": "Editor",
"commenter": "Commenter",
"viewer": "Viewer",
"orgLevelCreator": "Organization Level Creator",
"orgLevelViewer": "Organization Level Viewer"
},
"sqlVIew": "SQL View"
},
"datatype": {
"ID": "ID",
"ForeignKey": "Foreign Key",
"SingleLineText": "Single Line Text",
"LongText": "Long Text",
"Attachment": "Attachment",
"Checkbox": "Checkbox",
"MultiSelect": "Multi Select",
"SingleSelect": "Single Select",
"Collaborator": "Collaborator",
"Date": "Date",
"Year": "Year",
"Time": "Time",
"PhoneNumber": "Phone Number",
"Email": "Email",
"URL": "URL",
"Number": "Number",
"Decimal": "Decimal",
"Currency": "Currency",
"Percent": "Percent",
"Duration": "Duration",
"Rating": "Rating",
"Formula": "Formula",
"Rollup": "Rollup",
"Count": "Count",
"Lookup": "Lookup",
"DateTime": "Date Time",
"CreateTime": "Create Time",
"LastModifiedTime": "Last Modified Time",
"AutoNumber": "Auto Number",
"Barcode": "Barcode",
"Button": "Button",
"Password": "Password",
"relationProperties": {
"noAction": "No Action",
"cascade": "Cascade",
"restrict": "Restrict",
"setNull": "Set NULL",
"setDefault": "Set Default"
}
},
"filterOperation": {
"isEqual": "is equal",
"isNotEqual": "is not equal",
"isLike": "is like",
"isNot like": "is not like",
"isEmpty": "is empty",
"isNotEmpty": "is not empty",
"isNull": "is null",
"isNotNull": "is not null"
},
"title": {
"erdView": "ERD View",
"newProj": "New Project",
"myProject": "My Projects",
"formTitle": "Form Title",
"collabView": "Collaborative View",
"lockedView": "Locked View",
"personalView": "Personal View",
"appStore": "App Store",
"teamAndAuth": "Team & Auth",
"rolesUserMgmt": "Roles & Users Management",
"userMgmt": "Users Management",
"apiTokenMgmt": "API Tokens Management",
"rolesMgmt": "Roles Management",
"projMeta": "Project Metadata",
"metaMgmt": "Meta Management",
"metadata": "Metadata",
"exportImportMeta": "Export / Import Metadata",
"uiACL": "UI Access Control",
"metaOperations": "Metadata Operations",
"audit": "Audit",
"auditLogs": "Audit Log",
"sqlMigrations": "SQL Migrations",
"dbCredentials": "Database Credentials",
"advancedParameters": "SSL & Advanced parameters",
"headCreateProject": "Create Project | NocoDB",
"headLogin": "Log In | NocoDB",
"resetPassword": "Reset your password",
"teamAndSettings": "Team & Settings",
"apiDocs": "API Docs",
"importFromAirtable": "Import From Airtable",
"generateToken": "Generate Token",
"APIsAndSupport": "APIs & Support",
"helpCenter": "Help center",
"swaggerDocumentation": "Swagger Documentation",
"quickImportFrom": "Quick Import From",
"quickImport": "Quick Import",
"advancedSettings": "Advanced Settings",
"codeSnippet": "Code Snippet",
"keyboardShortcut": "Keyboard Shortcuts"
},
"labels": {
"createdBy": "Created By",
"notifyVia": "Notify Via",
"projName": "Project name",
"tableName": "Table name",
"viewName": "View name",
"viewLink": "View Link",
"columnName": "Column Name",
"columnType": "Column Type",
"roleName": "Role Name",
"roleDescription": "Role Description",
"databaseType": "Type in Database",
"lengthValue": "Length/ value",
"dbType": "Database Type",
"sqliteFile": "SQLite File",
"hostAddress": "Host Address",
"port": "Port Number",
"username": "Username",
"password": "Password",
"schemaName": "Schema name",
"database": "Database",
"action": "Action",
"actions": "Actions",
"operation": "Operation",
"operationType": "Operation type",
"operationSubType": "Operation sub-type",
"description": "Description",
"authentication": "Authentication",
"token": "Token",
"where": "Where",
"cache": "Cache",
"chat": "Chat",
"email": "E-mail",
"storage": "Storage",
"uiAcl": "UI-ACL",
"models": "Models",
"syncState": "Sync state",
"created": "Created",
"sqlOutput": "SQL Output",
"addOption": "Add option",
"qrCodeValueColumn": "Column with QR code value",
"barcodeValueColumn": "Column with Barcode value",
"barcodeFormat": "Barcode format",
"qrCodeValueTooLong": "Too many characters for a QR code",
"barcodeValueTooLong": "Too many characters for a barcode",
"aggregateFunction": "Aggregate function",
"dbCreateIfNotExists": "Database : create if not exists",
"clientKey": "Client Key",
"clientCert": "Client Cert",
"serverCA": "Server CA",
"requriedCa": "Required-CA",
"requriedIdentity": "Required-IDENTITY",
"inflection": {
"tableName": "Inflection - Table name",
"columnName": "Inflection - Column name"
},
"community": {
"starUs1": "Star",
"starUs2": "us on Github",
"bookDemo": "Book a Free DEMO",
"getAnswered": "Get your questions answered",
"joinDiscord": "Join Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Join /r/NocoDB",
"followNocodb": "Follow NocoDB"
},
"docReference": "Document Reference",
"selectUserRole": "Select User Role",
"childTable": "Child table",
"childColumn": "Child column",
"onUpdate": "On Update",
"onDelete": "On Delete",
"account": "Account",
"language": "Language",
"primaryColor": "Primary Color",
"accentColor": "Accent Color",
"customTheme": "Custom Theme",
"requestDataSource": "Request a data source you need?",
"apiKey": "API Key",
"sharedBase": "Shared Base",
"importData": "Import Data",
"importSecondaryViews": "Import Secondary Views",
"importRollupColumns": "Import Rollup Columns",
"importLookupColumns": "Import Lookup Columns",
"importAttachmentColumns": "Import Attachment Columns",
"importFormulaColumns": "Import Formula Columns",
"noData": "No Data",
"goToDashboard": "Go to Dashboard",
"importing": "Importing",
"flattenNested": "Flatten Nested",
"downloadAllowed": "Download allowed",
"weAreHiring": "We are Hiring!",
"primaryKey": "Primary key",
"hasMany": "has many",
"belongsTo": "belongs to",
"manyToMany": "have many to many relation",
"extraConnectionParameters": "Extra connection parameters",
"commentsOnly": "Comments only",
"documentation": "Documentation",
"subscribeNewsletter": "Subscribe to our weekly newsletter",
"signUpWithGoogle": "Sign up with Google",
"signInWithGoogle": "Sign in with Google",
"agreeToTos": "By signing up, you agree to the Terms of Service",
"welcomeToNc": "Welcome to NocoDB!",
"inviteOnlySignup": "Allow signup only using invite url"
},
"activity": {
"createProject": "Create Project",
"importProject": "Import Project",
"searchProject": "Search Project",
"editProject": "Edit Project",
"stopProject": "Stop Project",
"startProject": "Start Project",
"restartProject": "Restart Project",
"deleteProject": "Delete Project",
"refreshProject": "Refresh projects",
"saveProject": "Save Project",
"deleteKanbanStack": "Delete stack?",
"createProjectExtended": {
"extDB": "Create By Connecting <br>To An External Database",
"excel": "Create Project from excel",
"template": "Create Project from template"
},
"OkSaveProject": "Ok & Save Project",
"upgrade": {
"available": "Upgrade available",
"releaseNote": "Release notes",
"howTo": "How to upgrade ?"
},
"translate": "Help translate",
"account": {
"authToken": "Copy Auth Token",
"swagger": "Swagger: REST APIs",
"projInfo": "Copy Project Info",
"themes": "Themes"
},
"sort": "Sort",
"addSort": "Add Sort Option",
"filter": "Filter",
"addFilter": "Add Filter",
"share": "Share",
"shareBase": {
"disable": "Disable shared base",
"enable": "Anyone with the link",
"link": "Shared base link"
},
"invite": "Invite",
"inviteMore": "Invite more",
"inviteTeam": "Invite Team",
"inviteUser": "Invite User",
"inviteToken": "Invite Token",
"newUser": "New User",
"editUser": "Edit user",
"deleteUser": "Remove user from project",
"resendInvite": "Resend invite E-mail",
"copyInviteURL": "Copy invite URL",
"copyPasswordResetURL": "Copy password reset URL",
"newRole": "New role",
"reloadRoles": "Reload roles",
"nextPage": "Next page",
"prevPage": "Previous page",
"nextRecord": "Next record",
"previousRecord": "Previous record",
"copyApiURL": "Copy API URL",
"createTable": "Table Create",
"refreshTable": "Tables Refresh",
"renameTable": "Table Rename",
"deleteTable": "Table Delete",
"addField": "Add new field to this table",
"setPrimary": "Set as Primary value",
"addRow": "Add new row",
"saveRow": "Save row",
"saveAndExit": "Save & Exit",
"saveAndStay": "Save & Stay",
"insertRow": "Insert New Row",
"deleteRow": "Delete Row",
"deleteSelectedRow": "Delete Selected Rows",
"importExcel": "Import Excel",
"importCSV": "Import CSV",
"downloadCSV": "Download as CSV",
"downloadExcel": "Download as XLSX",
"uploadCSV": "Upload CSV",
"import": "Import",
"importMetadata": "Import Metadata",
"exportMetadata": "Export Metadata",
"clearMetadata": "Clear Metadata",
"exportToFile": "Export to file",
"changePwd": "Change Password",
"createView": "Create a View",
"shareView": "Share View",
"listSharedView": "Shared View List",
"ListView": "Views List",
"copyView": "Copy view",
"renameView": "Rename view",
"deleteView": "Delete view",
"createGrid": "Create Grid View",
"createGallery": "Create Gallery View",
"createCalendar": "Create Calendar View",
"createKanban": "Create Kanban View",
"createForm": "Create Form View",
"showSystemFields": "Show system fields",
"copyUrl": "Copy URL",
"openTab": "Open new tab",
"iFrame": "Copy embeddable HTML code",
"addWebhook": "Add New Webhook",
"newToken": "Add New Token",
"exportZip": "Export zip",
"importZip": "Import zip",
"metaSync": "Sync Now",
"settings": "Settings",
"previewAs": "Preview as",
"resetReview": "Reset Preview",
"testDbConn": "Test Database Connection",
"removeDbFromEnv": "Remove Database from environment",
"editConnJson": "Edit connection JSON",
"sponsorUs": "Sponsor Us",
"sendEmail": "SEND EMAIL",
"addUserToProject": "Add user to project",
"getApiSnippet": "Get API Snippet",
"clearCell": "Clear cell",
"addFilterGroup": "Add Filter Group",
"linkRecord": "Link record",
"addNewRecord": "Add new record",
"useConnectionUrl": "Use Connection URL",
"toggleCommentsDraw": "Toggle comments draw",
"expandRecord": "Expand Record",
"deleteRecord": "Delete Record",
"erd": {
"showColumns": "Show Columns",
"showPkAndFk": "Show Primary and Foreign Keys",
"showSqlViews": "Show SQL Views",
"showMMTables": "Show Many to Many tables",
"showJunctionTableNames": "Show Junction Table Names"
},
"kanban": {
"collapseStack": "Collapse Stack",
"deleteStack": "Delete Stack",
"stackedBy": "Stacked By",
"chooseGroupingField": "Choose a Grouping Field",
"addOrEditStack": "Add / Edit Stack"
}
},
"tooltip": {
"saveChanges": "Save changes",
"xcDB": "Create a new project",
"extDB": "Supports MySQL, PostgreSQL, SQL Server & SQLite",
"apiRest": "Accessible via REST APIs",
"apiGQL": "Accessible via GraphQL APIs",
"theme": {
"dark": "It does come in Black (^⇧B)",
"light": "Does it come in Black ? (^⇧B)"
},
"addTable": "Add new table",
"inviteMore": "Invite more users",
"toggleNavDraw": "Toggle navigation drawer",
"reloadApiToken": "Reload API tokens",
"generateNewApiToken": "Generate new API token",
"addRole": "Add new role",
"reloadList": "Reload list",
"metaSync": "Sync metadata",
"sqlMigration": "Reload migrations",
"updateRestart": "Update & Restart",
"cancelReturn": "Cancel and Return",
"exportMetadata": "Export all metadata from the meta tables to meta directory.",
"importMetadata": "Import all metadata from the meta directory to meta tables.",
"clearMetadata": "Clear all metadata from meta tables.",
"clientKey": "Select .key file",
"clientCert": "Select .cert file",
"clientCA": "Select CA file"
},
"placeholder": {
"projName": "Enter Project Name",
"password": {
"enter": "Enter the password",
"current": "Current password",
"new": "New password",
"save": "Save password",
"confirm": "Confirm new password"
},
"searchProjectTree": "Search tables",
"searchFields": "Search fields",
"searchColumn": "Search {search} column",
"searchApps": "Search apps",
"searchModels": "Search models",
"noItemsFound": "No items found",
"defaultValue": "Default value",
"filterByEmail": "Filter by E-mail",
"filterQuery": "Filter query",
"selectField": "Select field"
},
"msg": {
"warning": {
"barcode": {
"renderError": "Barcode error - please check compatibility between input and barcode type"
},
"nonEditableFields": {
"computedFieldUnableToClear": "Warning: Computed field - unable to clear text",
"qrFieldsCannotBeDirectlyChanged": "Warning: QR fields cannot be directly changed."
}
},
"info": {
"pasteNotSupported": "Paste operation is not supported on the active cell",
"roles": {
"orgCreator": "Creator can create new projects and access any invited project.",
"orgViewer": "Viewer is not allowed to create new projects but they can access any invited project."
},
"footerInfo": "Rows per page",
"upload": "Select file to Upload",
"upload_sub": "or drag and drop file",
"excelSupport": "Supported: .xls, .xlsx, .xlsm, .ods, .ots",
"excelURL": "Enter excel file URL",
"csvURL": "Enter CSV file URL",
"footMsg": "# of rows to parse to infer datatype",
"excelImport": "sheet(s) are available for import",
"exportMetadata": "Do you want to export metadata from meta tables?",
"importMetadata": "Do you want to import metadata from meta tables?",
"clearMetadata": "Do you want to clear metadata from meta tables?",
"projectEmptyMessage": "Get started by creating a new project",
"stopProject": "Do you want to stop the project?",
"startProject": "Do you want to start the project?",
"restartProject": "Do you want to restart the project?",
"deleteProject": "Do you want to delete the project?",
"shareBasePrivate": "Generate publicly shareable readonly base",
"shareBasePublic": "Anyone on the internet with this link can view",
"userInviteNoSMTP": "Looks like you have not configured mailer yet! Please copy above invite link and send it to",
"dragDropHide": "Drag and drop fields here to hide",
"formInput": "Enter form input label",
"formHelpText": "Add some help text",
"onlyCreator": "Only visible to Creator",
"formDesc": "Add form description",
"beforeEnablePwd": "Restrict access with a password",
"afterEnablePwd": "Access is password restricted",
"privateLink": "This view is shared via a private link",
"privateLinkAdditionalInfo": "People with private link can only see cells visible in this view",
"afterFormSubmitted": "After form is submitted",
"apiOptions": "Access Project via",
"submitAnotherForm": "Show 'Submit Another Form' button",
"showBlankForm": "Show a blank form after 5 seconds",
"emailForm": "E-mail me at",
"showSysFields": "Show system fields",
"filterAutoApply": "Auto apply",
"showMessage": "Show this message",
"viewNotShared": "Current view is not shared!",
"showAllViews": "Show all shared views of this table",
"collabView": "Collaborators with edit permissions or higher can change the view configuration.",
"lockedView": "No one can edit the view configuration until it is unlocked.",
"personalView": "Only you can edit the view configuration. Other collaborators’ personal views are hidden by default.",
"ownerDesc": "Can add/remove creators. And full edit database structures & fields.",
"creatorDesc": "Can fully edit database structure & values.",
"editorDesc": "Can edit records but cannot change structure of database/fields.",
"commenterDesc": "Can view and comment the records but cannot edit anything",
"viewerDesc": "Can view the records but cannot edit anything",
"addUser": "Add new user",
"staticRoleInfo": "System defined roles can't be edited",
"exportZip": "Export project meta to zip file and download.",
"importZip": "Import project meta zip file and restart.",
"importText": "Import NocoDB Project by uploading metadata zip file",
"metaNoChange": "No change identified",
"sqlMigration": "Schema migrations will be created automatically. Create a table and refresh this page.",
"dbConnectionStatus": "Environment validated",
"dbConnected": "Connection was successful",
"notifications": {
"no_new": "No new notifications",
"clear": "Clear"
},
"sponsor": {
"header": "You can help us!",
"message": "We are a tiny team working full time to make NocoDB Open-source. We believe a tool like NocoDB should be available freely to every problem solver on Internet."
},
"loginMsg": "Log In To NocoDB",
"passwordRecovery": {
"message_1": "Please provide the email address you used when you signed up.",
"message_2": "We will send you an email with a link to reset your password.",
"success": "Please check your email to reset the password"
},
"signUp": {
"superAdmin": "You will be the 'Super Admin'",
"alreadyHaveAccount": "Already have an account ?",
"workEmail": "Enter your work email",
"enterPassword": "Enter your password",
"forgotPassword": "Forgot your password ?",
"dontHaveAccount": "Don't have an account ?"
},
"addView": {
"grid": "Add Grid View",
"gallery": "Add Gallery View",
"form": "Add Form View",
"kanban": "Add Kanban View",
"calendar": "Add Calendar View"
},
"tablesMetadataInSync": "Tables metadata is in Sync",
"addMultipleUsers": "You can add multiple comma(,) separated emails",
"enterTableName": "Enter table name",
"addDefaultColumns": "Add default columns",
"tableNameInDb": "Table name as saved in database",
"airtable": {
"credentials": "Where to find this?"
},
"import": {
"clickOrDrag": "Click or drag file to this area to upload"
},
"metaDataRecreated": "Table metadata recreated successfully",
"invalidCredentials": "Invalid credentials",
"downloadingMoreFiles": "Downloading more files",
"copiedToClipboard": "Copied to clipboard",
"requriedFieldsCantBeMoved": "Required field can't be moved",
"updateNotAllowedWithoutPK": "Update not allowed for table which doesn't have primary key",
"autoIncFieldNotEditable": "Auto increment field is not editable",
"editingPKnotSupported": "Editing primary key not supported",
"deletedCache": "Deleted cache successfully",
"cacheEmpty": "Cache is empty",
"exportedCache": "Exported Cache Successfully",
"valueAlreadyInList": "This value is already in the list",
"noColumnsToUpdate": "No columns to update",
"tableDeleted": "Deleted table successfully",
"generatePublicShareableReadonlyBase": "Generate publicly shareable readonly base",
"deleteViewConfirmation": "Are you sure you want to delete this view?",
"deleteTableConfirmation": "Do you want to delete the table",
"showM2mTables": "Show M2M Tables",
"deleteKanbanStackConfirmation": "Deleting this stack will also remove the select option `{stackToBeDeleted}` from the `{groupingField}`. The records will move to the uncategorized stack.",
"computedFieldEditWarning": "Computed field: contents are read-only. Use column edit menu to reconfigure",
"computedFieldDeleteWarning": "Computed field: contents are read-only. Unable to clear content."
},
"error": {
"searchProject": "Your search for {search} found no results",
"invalidChar": "Invalid character in folder path.",
"invalidDbCredentials": "Invalid database credentials.",
"unableToConnectToDb": "Unable to connect to database, please check your database is up.",
"userDoesntHaveSufficientPermission": "User does not exist or have sufficient permission to create schema.",
"dbConnectionStatus": "Invalid database parameters",
"dbConnectionFailed": "Connection Failure:",
"signUpRules": {
"emailReqd": "E-mail is required",
"emailInvalid": "E-mail must be valid",
"passwdRequired": "Password is required",
"passwdLength": "You password must be atleast 8 characters",
"passwdMismatch": "Passwords do not match",
"completeRuleSet": "At least 8 characters with one Uppercase, one number and one special character",
"atLeast8Char": "At least 8 characters",
"atLeastOneUppercase": "One Uppercase letter",
"atLeastOneNumber": "One Number",
"atLeastOneSpecialChar": "One special character",
"allowedSpecialCharList": "Allowed special character list"
},
"invalidURL": "Invalid URL",
"internalError": "Some internal error occurred",
"templateGeneratorNotFound": "Template Generator cannot be found!",
"fileUploadFailed": "Failed to upload file",
"primaryColumnUpdateFailed": "Failed to update primary column",
"formDescriptionTooLong": "Data too long for Form Description",
"columnsRequired": "Following columns are required",
"selectAtleastOneColumn": "At least one column has to be selected",
"columnDescriptionNotFound": "Cannot find the destination column for",
"duplicateMappingFound": "Duplicate mapping found, please remove one of the mapping",
"nullValueViolatesNotNull": "Null value violates not-null constraint",
"sourceHasInvalidNumbers": "Source data contains some invalid numbers",
"sourceHasInvalidBoolean": "Source data contains some invalid boolean values",
"invalidForm": "Invalid Form",
"formValidationFailed": "Form validation failed",
"youHaveBeenSignedOut": "You have been signed out",
"failedToLoadList": "Failed to load list",
"failedToLoadChildrenList": "Failed to load children list",
"deleteFailed": "Delete failed",
"unlinkFailed": "Unlink failed",
"rowUpdateFailed": "Row update failed",
"deleteRowFailed": "Failed to delete row",
"setFormDataFailed": "Failed to set form data",
"formViewUpdateFailed": "Failed to update form view",
"tableNameRequired": "Table name is required",
"nameShouldStartWithAnAlphabetOr_": "Name should start with an alphabet or _",
"followingCharactersAreNotAllowed": "Following characters are not allowed",
"columnNameRequired": "Column name is required",
"projectNameExceeds50Characters": "Project name exceeds 50 characters",
"projectNameCannotStartWithSpace": "Project name cannot start with space",
"requiredField": "Required field",
"ipNotAllowed": "IP not allowed",
"targetFileIsNotAnAcceptedFileType": "Target file is not an accepted file type",
"theAcceptedFileTypeIsCsv": "The accepted file type is .csv",
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "{value} cannot be empty.",
"projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Failed to copy to clipboard"
},
"toast": {
"exportMetadata": "Project metadata exported successfully",
"importMetadata": "Project metadata imported successfully",
"clearMetadata": "Project metadata cleared successfully",
"stopProject": "Project stopped successfully",
"startProject": "Project started successfully",
"restartProject": "Project restarted successfully",
"deleteProject": "Project deleted successfully",
"authToken": "Auth token copied to clipboard",
"projInfo": "Copied project info to clipboard",
"inviteUrlCopy": "Copied invite URL to clipboard",
"createView": "View created successfully",
"formEmailSMTP": "Please activate SMTP plugin in App store for enabling email notification",
"collabView": "Successfully Switched to collaborative view",
"lockedView": "Successfully Switched to locked view",
"futureRelease": "Coming soon!"
},
"success": {
"columnDuplicated": "Column duplicated successfully",
"updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully",
"pluginTested": "Successfully tested plugin settings",
"tableRenamed": "Table renamed successfully",
"viewDeleted": "View deleted successfully",
"primaryColumnUpdated": "Successfully updated as primary column",
"tableDataExported": "Successfully exported all table data",
"updated": "Successfully updated",
"sharedViewDeleted": "Deleted shared view successfully",
"userDeleted": "User deleted successfully",
"viewRenamed": "View renamed successfully",
"tokenGenerated": "Token generated successfully",
"tokenDeleted": "Token deleted successfully",
"userAddedToProject": "Successfully added user to project",
"userAdded": "Successfully added user",
"userDeletedFromProject": "Successfully deleted user from project",
"inviteEmailSent": "Invite Email sent successfully",
"inviteURLCopied": "Invite URL copied to clipboard",
"passwordResetURLCopied": "Password reset URL copied to clipboard",
"shareableURLCopied": "Copied shareable base URL to clipboard!",
"embeddableHTMLCodeCopied": "Copied embeddable HTML code!",
"userDetailsUpdated": "Successfully updated the user details",
"tableDataImported": "Successfully imported table data",
"webhookUpdated": "Webhook details updated successfully",
"webhookDeleted": "Hook deleted successfully",
"webhookTested": "Webhook tested successfully",
"columnUpdated": "Column updated",
"columnCreated": "Column created",
"passwordChanged": "Password changed successfully. Please login again.",
"settingsSaved": "Settings saved successfully",
"roleUpdated": "Role updated successfully"
}
}
}

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

@ -16,7 +16,7 @@
"cancel": "Annuler",
"submit": "Soumettre",
"create": "Créer",
"duplicate": "Duplicate",
"duplicate": "Dupliquer",
"insert": "Insérer",
"delete": "Supprimer",
"update": "Mettre à jour",
@ -56,25 +56,25 @@
"notification": "Notification",
"reference": "Référence",
"function": "Fonction",
"confirm": "Confirm",
"generate": "Generate",
"copy": "Copy",
"confirm": "Confirmer",
"generate": "Générer",
"copy": "Copier",
"misc": "Miscellaneous",
"lock": "Lock",
"unlock": "Unlock",
"credentials": "Credentials",
"help": "Help",
"lock": "Verrouiller",
"unlock": "Déverrouiller",
"credentials": "Identifiants",
"help": "Aide",
"questions": "Questions",
"reachOut": "Reach out here",
"betaNote": "This feature is currently in beta.",
"moreInfo": "More information can be found here",
"betaNote": "Cette fonctionnalité est encore en développement.",
"moreInfo": "Plus d'informations peuvent être trouvées ici",
"logs": "Logs",
"groupingField": "Grouping Field",
"insertAfter": "Insert After",
"insertBefore": "Insert Before",
"hideField": "Hide Field",
"sortAsc": "Sort Ascending",
"sortDesc": "Sort Descending"
"hideField": "Masquer le champ",
"sortAsc": "Trier par ordre croissant",
"sortDesc": "Trier par ordre décroissant"
},
"objects": {
"project": "Projet",
@ -197,21 +197,21 @@
"teamAndSettings": "Équipe & paramètres",
"apiDocs": "Docs API",
"importFromAirtable": "Importer depuis Airtable",
"generateToken": "Generate Token",
"generateToken": "Générer un jeton",
"APIsAndSupport": "Les API et la prise en charge",
"helpCenter": "Help center",
"swaggerDocumentation": "Swagger Documentation",
"quickImportFrom": "Quick Import From",
"quickImport": "Quick Import",
"advancedSettings": "Advanced Settings",
"quickImport": "Importation rapide",
"advancedSettings": "Paramètres avancés",
"codeSnippet": "Code Snippet",
"keyboardShortcut": "Keyboard Shortcuts"
},
"labels": {
"createdBy": "Created By",
"createdBy": "Créé par",
"notifyVia": "Notifier via",
"projName": "Nom du projet",
"tableName": "Nom de la table",
"tableName": "Nom du tableau",
"viewName": "Vue",
"viewLink": "Lien de vue",
"columnName": "Nom de la colonne",
@ -280,37 +280,37 @@
"onUpdate": "Mise à jour en cours",
"onDelete": "Suppression en cours",
"account": "Compte",
"language": "Language",
"primaryColor": "Primary Color",
"accentColor": "Accent Color",
"language": "Langue",
"primaryColor": "Couleur primaire",
"accentColor": "Couleur secondaire",
"customTheme": "Thème personnalisé",
"requestDataSource": "Request a data source you need?",
"apiKey": "Clé d'API",
"sharedBase": "Shared Base",
"importData": "Import Data",
"importData": "Importer des données",
"importSecondaryViews": "Importer des vues secondaires",
"importRollupColumns": "Import Rollup Columns",
"importLookupColumns": "Import Lookup Columns",
"importAttachmentColumns": "Import Attachment Columns",
"importFormulaColumns": "Import Formula Columns",
"noData": "No Data",
"goToDashboard": "Go to Dashboard",
"noData": "Aucune donnée",
"goToDashboard": "Accéder au tableau de bord",
"importing": "Importing",
"flattenNested": "Flatten Nested",
"downloadAllowed": "Download allowed",
"weAreHiring": "We are Hiring!",
"downloadAllowed": "Téléchargement autorisé",
"weAreHiring": "Nous recrutons !",
"primaryKey": "Primary key",
"hasMany": "has many",
"belongsTo": "belongs to",
"hasMany": "a plusieurs",
"belongsTo": "appartient à",
"manyToMany": "have many to many relation",
"extraConnectionParameters": "Extra connection parameters",
"commentsOnly": "Comments only",
"commentsOnly": "Commentaires uniquement",
"documentation": "Documentation",
"subscribeNewsletter": "Subscribe to our weekly newsletter",
"subscribeNewsletter": "Abonnez-vous à notre newsletter hebdomadaire",
"signUpWithGoogle": "S’enregistrer avec Google",
"signInWithGoogle": "Se connecter avec Google",
"agreeToTos": "By signing up, you agree to the Terms of Service",
"welcomeToNc": "Welcome to NocoDB!",
"agreeToTos": "En continuant, vous acceptez les Conditions d'Utilisation",
"welcomeToNc": "Bienvenue sur NocoDB !",
"inviteOnlySignup": "Allow signup only using invite url"
},
"activity": {
@ -356,7 +356,7 @@
"invite": "Inviter",
"inviteMore": "Inviter plus",
"inviteTeam": "Inviter une équipe",
"inviteUser": "Invite User",
"inviteUser": "Inviter un utilisateur",
"inviteToken": "Inviter via un jeton",
"newUser": "Nouvel utilisateur",
"editUser": "Modifier l'utilisateur",
@ -375,17 +375,17 @@
"refreshTable": "Actualiser le tableau",
"renameTable": "Renommer le tableau",
"deleteTable": "Supprimer le tableau",
"addField": "Ajouter un nouveau champ à cette table",
"addField": "Ajouter un nouveau champ à ce tableau",
"setPrimary": "Définir comme valeur primaire",
"addRow": "Ajouter une nouvelle ligne",
"saveRow": "Enregistrer la ligne",
"saveAndExit": "Save & Exit",
"saveAndStay": "Save & Stay",
"saveAndExit": "Enregistrer et quitter",
"saveAndStay": "Enregistrer et rester",
"insertRow": "Insérer une nouvelle ligne",
"deleteRow": "Supprimer la ligne",
"deleteSelectedRow": "Supprimer les lignes sélectionnées",
"importExcel": "Importer depuis Excel",
"importCSV": "Import CSV",
"importCSV": "Importer un fichier CSV",
"downloadCSV": "Télécharger comme CSV",
"downloadExcel": "Télécharger comme XLSX",
"uploadCSV": "Téléverser un CSV",
@ -424,10 +424,10 @@
"editConnJson": "Éditer le JSON de connexion",
"sponsorUs": "Nous Parrainer",
"sendEmail": "ENVOYER UN EMAIL",
"addUserToProject": "Add user to project",
"addUserToProject": "Ajouter un utilisateur au projet",
"getApiSnippet": "Récupérer le Snippet API",
"clearCell": "Clear cell",
"addFilterGroup": "Add Filter Group",
"clearCell": "Vider la cellule",
"addFilterGroup": "Ajouter un groupe de filtres",
"linkRecord": "Link record",
"addNewRecord": "Add new record",
"useConnectionUrl": "Use Connection URL",
@ -459,7 +459,7 @@
"dark": "Nuit (^⇧B)",
"light": "Jour (^⇧B)"
},
"addTable": "Ajouter une nouvelle table",
"addTable": "Ajouter un nouveau tableau",
"inviteMore": "Inviter plus d'utilisateurs",
"toggleNavDraw": "Basculer le tiroir de navigation",
"reloadApiToken": "Recharger les jetons API",
@ -493,9 +493,9 @@
"searchModels": "Chercher un modèle",
"noItemsFound": "Aucun élément trouvé",
"defaultValue": "Valeur par défaut",
"filterByEmail": "Filtrer par courriel",
"filterQuery": "Filter query",
"selectField": "Select field"
"filterByEmail": "Rechercher un courriel",
"filterQuery": "Rechercher",
"selectField": "Sélectionner un champ"
},
"msg": {
"warning": {
@ -504,7 +504,7 @@
},
"nonEditableFields": {
"computedFieldUnableToClear": "Warning: Computed field - unable to clear text",
"qrFieldsCannotBeDirectlyChanged": "Warning: QR fields cannot be directly changed."
"qrFieldsCannotBeDirectlyChanged": "Attention : les champs QR code ne peuvent pas être modifiés directement."
}
},
"info": {
@ -599,32 +599,32 @@
},
"tablesMetadataInSync": "Les métadonnées de tables sont en synchronisation",
"addMultipleUsers": "Vous pouvez ajouter plusieurs courriels séparés par des virgules (,)",
"enterTableName": "Entrer le nom de la table",
"enterTableName": "Entrez le nom du tableau",
"addDefaultColumns": "Ajouter des colonnes par défaut",
"tableNameInDb": "Nom de la table tel qu'enregistré dans la base de données",
"airtable": {
"credentials": "Where to find this?"
"credentials": "Où trouver ceci ?"
},
"import": {
"clickOrDrag": "Click or drag file to this area to upload"
},
"metaDataRecreated": "Table metadata recreated successfully",
"invalidCredentials": "Invalid credentials",
"downloadingMoreFiles": "Downloading more files",
"copiedToClipboard": "Copied to clipboard",
"requriedFieldsCantBeMoved": "Required field can't be moved",
"invalidCredentials": "Identifiants invalides",
"downloadingMoreFiles": "Téléchargement de fichiers supplémentaires",
"copiedToClipboard": "Copié dans le presse-papier",
"requriedFieldsCantBeMoved": "Les champs requis ne peuvent pas être déplacés",
"updateNotAllowedWithoutPK": "Update not allowed for table which doesn't have primary key",
"autoIncFieldNotEditable": "Auto increment field is not editable",
"editingPKnotSupported": "Modification de la clé primaire non prise en charge",
"deletedCache": "Deleted cache successfully",
"cacheEmpty": "Cache is empty",
"cacheEmpty": "Le cache est vide",
"exportedCache": "Exported Cache Successfully",
"valueAlreadyInList": "This value is already in the list",
"noColumnsToUpdate": "No columns to update",
"tableDeleted": "Deleted table successfully",
"noColumnsToUpdate": "Aucune colonne à mettre à jour",
"tableDeleted": "Tableau supprimé avec succès",
"generatePublicShareableReadonlyBase": "Generate publicly shareable readonly base",
"deleteViewConfirmation": "Êtes-vous sûr de vouloir effacer cette vue ?",
"deleteTableConfirmation": "Do you want to delete the table",
"deleteTableConfirmation": "Voulez-vous supprimer ce tableau",
"showM2mTables": "Show M2M Tables",
"deleteKanbanStackConfirmation": "Deleting this stack will also remove the select option `{stackToBeDeleted}` from the `{groupingField}`. The records will move to the uncategorized stack.",
"computedFieldEditWarning": "Computed field: contents are read-only. Use column edit menu to reconfigure",
@ -644,15 +644,15 @@
"passwdRequired": "Mot de passe requis",
"passwdLength": "Votre mot de passe doit contenir au moins 8 caractères",
"passwdMismatch": "Les mots de passe ne correspondent pas",
"completeRuleSet": "At least 8 characters with one Uppercase, one number and one special character",
"atLeast8Char": "At least 8 characters",
"atLeastOneUppercase": "One Uppercase letter",
"atLeastOneNumber": "One Number",
"atLeastOneSpecialChar": "One special character",
"completeRuleSet": "Au moins 8 caractères avec une majuscule, un chiffre et un caractère spécial",
"atLeast8Char": "Au moins 8 caractères",
"atLeastOneUppercase": "Une lettre majuscule",
"atLeastOneNumber": "Un chiffre",
"atLeastOneSpecialChar": "Un caractère spécial",
"allowedSpecialCharList": "Allowed special character list"
},
"invalidURL": "Invalid URL",
"internalError": "Some internal error occurred",
"invalidURL": "URL invalide",
"internalError": "Une erreur interne est survenue",
"templateGeneratorNotFound": "Template Generator cannot be found!",
"fileUploadFailed": "Failed to upload file",
"primaryColumnUpdateFailed": "Failed to update primary column",
@ -675,14 +675,14 @@
"deleteRowFailed": "Failed to delete row",
"setFormDataFailed": "Failed to set form data",
"formViewUpdateFailed": "Échec de la mise à jour de la vue du formulaire",
"tableNameRequired": "Table name is required",
"nameShouldStartWithAnAlphabetOr_": "Name should start with an alphabet or _",
"followingCharactersAreNotAllowed": "Following characters are not allowed",
"columnNameRequired": "Column name is required",
"projectNameExceeds50Characters": "Project name exceeds 50 characters",
"projectNameCannotStartWithSpace": "Project name cannot start with space",
"requiredField": "Required field",
"ipNotAllowed": "IP not allowed",
"tableNameRequired": "Nom du tableau requis",
"nameShouldStartWithAnAlphabetOr_": "Le nom doit commencer par une lettre de l'alphabet ou _",
"followingCharactersAreNotAllowed": "Les caractères suivants ne sont pas autorisés",
"columnNameRequired": "Nom de la colonne requis",
"projectNameExceeds50Characters": "Le nom du projet dépasse les 50 caractères",
"projectNameCannotStartWithSpace": "Le nom du projet ne peut pas commencer par un espace",
"requiredField": "Champ requis",
"ipNotAllowed": "Adresse IP non autorisée",
"targetFileIsNotAnAcceptedFileType": "Target file is not an accepted file type",
"theAcceptedFileTypeIsCsv": "The accepted file type is .csv",
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
@ -715,15 +715,15 @@
"pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully",
"pluginTested": "Successfully tested plugin settings",
"tableRenamed": "Table renamed successfully",
"tableRenamed": "Tableau renommé avec succès",
"viewDeleted": "Vue effacée avec succès",
"primaryColumnUpdated": "Successfully updated as primary column",
"tableDataExported": "Successfully exported all table data",
"updated": "Successfully updated",
"tableDataExported": "Toutes les données du tableau ont été exportées avec succès",
"updated": "Mise à jour réussie",
"sharedViewDeleted": "Vue partagée effacée avec succès",
"userDeleted": "User deleted successfully",
"userDeleted": "Utilisateur supprimé avec succès",
"viewRenamed": "Vue renommée avec succès",
"tokenGenerated": "Token generated successfully",
"tokenGenerated": "Jeton généré avec succès",
"tokenDeleted": "Token deleted successfully",
"userAddedToProject": "Successfully added user to project",
"userAdded": "Successfully added user",
@ -734,14 +734,14 @@
"shareableURLCopied": "Copied shareable base URL to clipboard!",
"embeddableHTMLCodeCopied": "Copied embeddable HTML code!",
"userDetailsUpdated": "Successfully updated the user details",
"tableDataImported": "Successfully imported table data",
"tableDataImported": "Données du tableau importées avec succès",
"webhookUpdated": "Webhook details updated successfully",
"webhookDeleted": "Hook deleted successfully",
"webhookTested": "Webhook tested successfully",
"columnUpdated": "Column updated",
"columnCreated": "Column created",
"passwordChanged": "Password changed successfully. Please login again.",
"settingsSaved": "Settings saved successfully",
"columnUpdated": "Colonne mise à jour",
"columnCreated": "Colonne créée",
"passwordChanged": "Mot de passe modifié avec succès. Veuillez vous reconnecter.",
"settingsSaved": "Paramètres modifiés avec succès",
"roleUpdated": "Role updated successfully"
}
}

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

@ -0,0 +1,748 @@
{
"general": {
"home": "Home",
"load": "Load",
"open": "Open",
"close": "Close",
"yes": "Yes",
"no": "No",
"ok": "OK",
"and": "And",
"or": "Or",
"add": "Add",
"edit": "Edit",
"remove": "Remove",
"save": "Save",
"cancel": "Cancel",
"submit": "Submit",
"create": "Create",
"duplicate": "Duplicate",
"insert": "Insert",
"delete": "Delete",
"update": "Update",
"rename": "Rename",
"reload": "Reload",
"reset": "Reset",
"install": "Install",
"show": "Show",
"hide": "Hide",
"showAll": "Show all",
"hideAll": "Hide all",
"showMore": "Show more",
"showOptions": "Show options",
"hideOptions": "Hide options",
"showMenu": "Show menu",
"hideMenu": "Hide menu",
"addAll": "Add all",
"removeAll": "Remove all",
"signUp": "SIGN UP",
"signIn": "SIGN IN",
"signOut": "Sign Out",
"required": "Required",
"preferred": "Preferred",
"mandatory": "Mandatory",
"loading": "Loading ...",
"title": "Title",
"upload": "Upload",
"download": "Download",
"default": "Default",
"more": "More",
"less": "Less",
"event": "Event",
"condition": "Condition",
"after": "After",
"before": "Before",
"search": "Search",
"notification": "Notification",
"reference": "Reference",
"function": "Function",
"confirm": "Confirm",
"generate": "Generate",
"copy": "Copy",
"misc": "Miscellaneous",
"lock": "Lock",
"unlock": "Unlock",
"credentials": "Credentials",
"help": "Help",
"questions": "Questions",
"reachOut": "Reach out here",
"betaNote": "This feature is currently in beta.",
"moreInfo": "More information can be found here",
"logs": "Logs",
"groupingField": "Grouping Field",
"insertAfter": "Insert After",
"insertBefore": "Insert Before",
"hideField": "Hide Field",
"sortAsc": "Sort Ascending",
"sortDesc": "Sort Descending"
},
"objects": {
"project": "Project",
"projects": "Projects",
"table": "Table",
"tables": "Tables",
"field": "Field",
"fields": "Fields",
"column": "Column",
"columns": "Columns",
"page": "Page",
"pages": "Pages",
"record": "record",
"records": "records",
"webhook": "Webhook",
"webhooks": "Webhooks",
"view": "View",
"views": "Views",
"viewType": {
"grid": "Grid",
"gallery": "Gallery",
"form": "Form",
"kanban": "Kanban",
"calendar": "Calendar"
},
"user": "User",
"users": "Users",
"role": "Role",
"roles": "Roles",
"roleType": {
"owner": "Owner",
"creator": "Creator",
"editor": "Editor",
"commenter": "Commenter",
"viewer": "Viewer",
"orgLevelCreator": "Organization Level Creator",
"orgLevelViewer": "Organization Level Viewer"
},
"sqlVIew": "SQL View"
},
"datatype": {
"ID": "ID",
"ForeignKey": "Foreign Key",
"SingleLineText": "Single Line Text",
"LongText": "Long Text",
"Attachment": "Attachment",
"Checkbox": "Checkbox",
"MultiSelect": "Multi Select",
"SingleSelect": "Single Select",
"Collaborator": "Collaborator",
"Date": "Date",
"Year": "Year",
"Time": "Time",
"PhoneNumber": "Phone Number",
"Email": "Email",
"URL": "URL",
"Number": "Number",
"Decimal": "Decimal",
"Currency": "Currency",
"Percent": "Percent",
"Duration": "Duration",
"Rating": "Rating",
"Formula": "Formula",
"Rollup": "Rollup",
"Count": "Count",
"Lookup": "Lookup",
"DateTime": "Date Time",
"CreateTime": "Create Time",
"LastModifiedTime": "Last Modified Time",
"AutoNumber": "Auto Number",
"Barcode": "Barcode",
"Button": "Button",
"Password": "Password",
"relationProperties": {
"noAction": "No Action",
"cascade": "Cascade",
"restrict": "Restrict",
"setNull": "Set NULL",
"setDefault": "Set Default"
}
},
"filterOperation": {
"isEqual": "is equal",
"isNotEqual": "is not equal",
"isLike": "is like",
"isNot like": "is not like",
"isEmpty": "is empty",
"isNotEmpty": "is not empty",
"isNull": "is null",
"isNotNull": "is not null"
},
"title": {
"erdView": "ERD View",
"newProj": "New Project",
"myProject": "My Projects",
"formTitle": "Form Title",
"collabView": "Collaborative View",
"lockedView": "Locked View",
"personalView": "Personal View",
"appStore": "App Store",
"teamAndAuth": "Team & Auth",
"rolesUserMgmt": "Roles & Users Management",
"userMgmt": "Users Management",
"apiTokenMgmt": "API Tokens Management",
"rolesMgmt": "Roles Management",
"projMeta": "Project Metadata",
"metaMgmt": "Meta Management",
"metadata": "Metadata",
"exportImportMeta": "Export / Import Metadata",
"uiACL": "UI Access Control",
"metaOperations": "Metadata Operations",
"audit": "Audit",
"auditLogs": "Audit Log",
"sqlMigrations": "SQL Migrations",
"dbCredentials": "Database Credentials",
"advancedParameters": "SSL & Advanced parameters",
"headCreateProject": "Create Project | NocoDB",
"headLogin": "Log In | NocoDB",
"resetPassword": "Reset your password",
"teamAndSettings": "Team & Settings",
"apiDocs": "API Docs",
"importFromAirtable": "Import From Airtable",
"generateToken": "Generate Token",
"APIsAndSupport": "APIs & Support",
"helpCenter": "Help center",
"swaggerDocumentation": "Swagger Documentation",
"quickImportFrom": "Quick Import From",
"quickImport": "Quick Import",
"advancedSettings": "Advanced Settings",
"codeSnippet": "Code Snippet",
"keyboardShortcut": "Keyboard Shortcuts"
},
"labels": {
"createdBy": "Created By",
"notifyVia": "Notify Via",
"projName": "Project name",
"tableName": "Table name",
"viewName": "View name",
"viewLink": "View Link",
"columnName": "Column Name",
"columnType": "Column Type",
"roleName": "Role Name",
"roleDescription": "Role Description",
"databaseType": "Type in Database",
"lengthValue": "Length/ value",
"dbType": "Database Type",
"sqliteFile": "SQLite File",
"hostAddress": "Host Address",
"port": "Port Number",
"username": "Username",
"password": "Password",
"schemaName": "Schema name",
"database": "Database",
"action": "Action",
"actions": "Actions",
"operation": "Operation",
"operationType": "Operation type",
"operationSubType": "Operation sub-type",
"description": "Description",
"authentication": "Authentication",
"token": "Token",
"where": "Where",
"cache": "Cache",
"chat": "Chat",
"email": "E-mail",
"storage": "Storage",
"uiAcl": "UI-ACL",
"models": "Models",
"syncState": "Sync state",
"created": "Created",
"sqlOutput": "SQL Output",
"addOption": "Add option",
"qrCodeValueColumn": "Column with QR code value",
"barcodeValueColumn": "Column with Barcode value",
"barcodeFormat": "Barcode format",
"qrCodeValueTooLong": "Too many characters for a QR code",
"barcodeValueTooLong": "Too many characters for a barcode",
"aggregateFunction": "Aggregate function",
"dbCreateIfNotExists": "Database : create if not exists",
"clientKey": "Client Key",
"clientCert": "Client Cert",
"serverCA": "Server CA",
"requriedCa": "Required-CA",
"requriedIdentity": "Required-IDENTITY",
"inflection": {
"tableName": "Inflection - Table name",
"columnName": "Inflection - Column name"
},
"community": {
"starUs1": "Star",
"starUs2": "us on Github",
"bookDemo": "Book a Free DEMO",
"getAnswered": "Get your questions answered",
"joinDiscord": "Join Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Join /r/NocoDB",
"followNocodb": "Follow NocoDB"
},
"docReference": "Document Reference",
"selectUserRole": "Select User Role",
"childTable": "Child table",
"childColumn": "Child column",
"onUpdate": "On Update",
"onDelete": "On Delete",
"account": "Account",
"language": "Language",
"primaryColor": "Primary Color",
"accentColor": "Accent Color",
"customTheme": "Custom Theme",
"requestDataSource": "Request a data source you need?",
"apiKey": "API Key",
"sharedBase": "Shared Base",
"importData": "Import Data",
"importSecondaryViews": "Import Secondary Views",
"importRollupColumns": "Import Rollup Columns",
"importLookupColumns": "Import Lookup Columns",
"importAttachmentColumns": "Import Attachment Columns",
"importFormulaColumns": "Import Formula Columns",
"noData": "No Data",
"goToDashboard": "Go to Dashboard",
"importing": "Importing",
"flattenNested": "Flatten Nested",
"downloadAllowed": "Download allowed",
"weAreHiring": "We are Hiring!",
"primaryKey": "Primary key",
"hasMany": "has many",
"belongsTo": "belongs to",
"manyToMany": "have many to many relation",
"extraConnectionParameters": "Extra connection parameters",
"commentsOnly": "Comments only",
"documentation": "Documentation",
"subscribeNewsletter": "Subscribe to our weekly newsletter",
"signUpWithGoogle": "Sign up with Google",
"signInWithGoogle": "Sign in with Google",
"agreeToTos": "By signing up, you agree to the Terms of Service",
"welcomeToNc": "Welcome to NocoDB!",
"inviteOnlySignup": "Allow signup only using invite url"
},
"activity": {
"createProject": "Create Project",
"importProject": "Import Project",
"searchProject": "Search Project",
"editProject": "Edit Project",
"stopProject": "Stop Project",
"startProject": "Start Project",
"restartProject": "Restart Project",
"deleteProject": "Delete Project",
"refreshProject": "Refresh projects",
"saveProject": "Save Project",
"deleteKanbanStack": "Delete stack?",
"createProjectExtended": {
"extDB": "Create By Connecting <br>To An External Database",
"excel": "Create Project from excel",
"template": "Create Project from template"
},
"OkSaveProject": "Ok & Save Project",
"upgrade": {
"available": "Upgrade available",
"releaseNote": "Release notes",
"howTo": "How to upgrade ?"
},
"translate": "Help translate",
"account": {
"authToken": "Copy Auth Token",
"swagger": "Swagger: REST APIs",
"projInfo": "Copy Project Info",
"themes": "Themes"
},
"sort": "Sort",
"addSort": "Add Sort Option",
"filter": "Filter",
"addFilter": "Add Filter",
"share": "Share",
"shareBase": {
"disable": "Disable shared base",
"enable": "Anyone with the link",
"link": "Shared base link"
},
"invite": "Invite",
"inviteMore": "Invite more",
"inviteTeam": "Invite Team",
"inviteUser": "Invite User",
"inviteToken": "Invite Token",
"newUser": "New User",
"editUser": "Edit user",
"deleteUser": "Remove user from project",
"resendInvite": "Resend invite E-mail",
"copyInviteURL": "Copy invite URL",
"copyPasswordResetURL": "Copy password reset URL",
"newRole": "New role",
"reloadRoles": "Reload roles",
"nextPage": "Next page",
"prevPage": "Previous page",
"nextRecord": "Next record",
"previousRecord": "Previous record",
"copyApiURL": "Copy API URL",
"createTable": "Table Create",
"refreshTable": "Tables Refresh",
"renameTable": "Table Rename",
"deleteTable": "Table Delete",
"addField": "Add new field to this table",
"setPrimary": "Set as Primary value",
"addRow": "Add new row",
"saveRow": "Save row",
"saveAndExit": "Save & Exit",
"saveAndStay": "Save & Stay",
"insertRow": "Insert New Row",
"deleteRow": "Delete Row",
"deleteSelectedRow": "Delete Selected Rows",
"importExcel": "Import Excel",
"importCSV": "Import CSV",
"downloadCSV": "Download as CSV",
"downloadExcel": "Download as XLSX",
"uploadCSV": "Upload CSV",
"import": "Import",
"importMetadata": "Import Metadata",
"exportMetadata": "Export Metadata",
"clearMetadata": "Clear Metadata",
"exportToFile": "Export to file",
"changePwd": "Change Password",
"createView": "Create a View",
"shareView": "Share View",
"listSharedView": "Shared View List",
"ListView": "Views List",
"copyView": "Copy view",
"renameView": "Rename view",
"deleteView": "Delete view",
"createGrid": "Create Grid View",
"createGallery": "Create Gallery View",
"createCalendar": "Create Calendar View",
"createKanban": "Create Kanban View",
"createForm": "Create Form View",
"showSystemFields": "Show system fields",
"copyUrl": "Copy URL",
"openTab": "Open new tab",
"iFrame": "Copy embeddable HTML code",
"addWebhook": "Add New Webhook",
"newToken": "Add New Token",
"exportZip": "Export zip",
"importZip": "Import zip",
"metaSync": "Sync Now",
"settings": "Settings",
"previewAs": "Preview as",
"resetReview": "Reset Preview",
"testDbConn": "Test Database Connection",
"removeDbFromEnv": "Remove Database from environment",
"editConnJson": "Edit connection JSON",
"sponsorUs": "Sponsor Us",
"sendEmail": "SEND EMAIL",
"addUserToProject": "Add user to project",
"getApiSnippet": "Get API Snippet",
"clearCell": "Clear cell",
"addFilterGroup": "Add Filter Group",
"linkRecord": "Link record",
"addNewRecord": "Add new record",
"useConnectionUrl": "Use Connection URL",
"toggleCommentsDraw": "Toggle comments draw",
"expandRecord": "Expand Record",
"deleteRecord": "Delete Record",
"erd": {
"showColumns": "Show Columns",
"showPkAndFk": "Show Primary and Foreign Keys",
"showSqlViews": "Show SQL Views",
"showMMTables": "Show Many to Many tables",
"showJunctionTableNames": "Show Junction Table Names"
},
"kanban": {
"collapseStack": "Collapse Stack",
"deleteStack": "Delete Stack",
"stackedBy": "Stacked By",
"chooseGroupingField": "Choose a Grouping Field",
"addOrEditStack": "Add / Edit Stack"
}
},
"tooltip": {
"saveChanges": "Save changes",
"xcDB": "Create a new project",
"extDB": "Supports MySQL, PostgreSQL, SQL Server & SQLite",
"apiRest": "Accessible via REST APIs",
"apiGQL": "Accessible via GraphQL APIs",
"theme": {
"dark": "It does come in Black (^⇧B)",
"light": "Does it come in Black ? (^⇧B)"
},
"addTable": "Add new table",
"inviteMore": "Invite more users",
"toggleNavDraw": "Toggle navigation drawer",
"reloadApiToken": "Reload API tokens",
"generateNewApiToken": "Generate new API token",
"addRole": "Add new role",
"reloadList": "Reload list",
"metaSync": "Sync metadata",
"sqlMigration": "Reload migrations",
"updateRestart": "Update & Restart",
"cancelReturn": "Cancel and Return",
"exportMetadata": "Export all metadata from the meta tables to meta directory.",
"importMetadata": "Import all metadata from the meta directory to meta tables.",
"clearMetadata": "Clear all metadata from meta tables.",
"clientKey": "Select .key file",
"clientCert": "Select .cert file",
"clientCA": "Select CA file"
},
"placeholder": {
"projName": "Enter Project Name",
"password": {
"enter": "Enter the password",
"current": "Current password",
"new": "New password",
"save": "Save password",
"confirm": "Confirm new password"
},
"searchProjectTree": "Search tables",
"searchFields": "Search fields",
"searchColumn": "Search {search} column",
"searchApps": "Search apps",
"searchModels": "Search models",
"noItemsFound": "No items found",
"defaultValue": "Default value",
"filterByEmail": "Filter by E-mail",
"filterQuery": "Filter query",
"selectField": "Select field"
},
"msg": {
"warning": {
"barcode": {
"renderError": "Barcode error - please check compatibility between input and barcode type"
},
"nonEditableFields": {
"computedFieldUnableToClear": "Warning: Computed field - unable to clear text",
"qrFieldsCannotBeDirectlyChanged": "Warning: QR fields cannot be directly changed."
}
},
"info": {
"pasteNotSupported": "Paste operation is not supported on the active cell",
"roles": {
"orgCreator": "Creator can create new projects and access any invited project.",
"orgViewer": "Viewer is not allowed to create new projects but they can access any invited project."
},
"footerInfo": "Rows per page",
"upload": "Select file to Upload",
"upload_sub": "or drag and drop file",
"excelSupport": "Supported: .xls, .xlsx, .xlsm, .ods, .ots",
"excelURL": "Enter excel file URL",
"csvURL": "Enter CSV file URL",
"footMsg": "# of rows to parse to infer datatype",
"excelImport": "sheet(s) are available for import",
"exportMetadata": "Do you want to export metadata from meta tables?",
"importMetadata": "Do you want to import metadata from meta tables?",
"clearMetadata": "Do you want to clear metadata from meta tables?",
"projectEmptyMessage": "Get started by creating a new project",
"stopProject": "Do you want to stop the project?",
"startProject": "Do you want to start the project?",
"restartProject": "Do you want to restart the project?",
"deleteProject": "Do you want to delete the project?",
"shareBasePrivate": "Generate publicly shareable readonly base",
"shareBasePublic": "Anyone on the internet with this link can view",
"userInviteNoSMTP": "Looks like you have not configured mailer yet! Please copy above invite link and send it to",
"dragDropHide": "Drag and drop fields here to hide",
"formInput": "Enter form input label",
"formHelpText": "Add some help text",
"onlyCreator": "Only visible to Creator",
"formDesc": "Add form description",
"beforeEnablePwd": "Restrict access with a password",
"afterEnablePwd": "Access is password restricted",
"privateLink": "This view is shared via a private link",
"privateLinkAdditionalInfo": "People with private link can only see cells visible in this view",
"afterFormSubmitted": "After form is submitted",
"apiOptions": "Access Project via",
"submitAnotherForm": "Show 'Submit Another Form' button",
"showBlankForm": "Show a blank form after 5 seconds",
"emailForm": "E-mail me at",
"showSysFields": "Show system fields",
"filterAutoApply": "Auto apply",
"showMessage": "Show this message",
"viewNotShared": "Current view is not shared!",
"showAllViews": "Show all shared views of this table",
"collabView": "Collaborators with edit permissions or higher can change the view configuration.",
"lockedView": "No one can edit the view configuration until it is unlocked.",
"personalView": "Only you can edit the view configuration. Other collaborators’ personal views are hidden by default.",
"ownerDesc": "Can add/remove creators. And full edit database structures & fields.",
"creatorDesc": "Can fully edit database structure & values.",
"editorDesc": "Can edit records but cannot change structure of database/fields.",
"commenterDesc": "Can view and comment the records but cannot edit anything",
"viewerDesc": "Can view the records but cannot edit anything",
"addUser": "Add new user",
"staticRoleInfo": "System defined roles can't be edited",
"exportZip": "Export project meta to zip file and download.",
"importZip": "Import project meta zip file and restart.",
"importText": "Import NocoDB Project by uploading metadata zip file",
"metaNoChange": "No change identified",
"sqlMigration": "Schema migrations will be created automatically. Create a table and refresh this page.",
"dbConnectionStatus": "Environment validated",
"dbConnected": "Connection was successful",
"notifications": {
"no_new": "No new notifications",
"clear": "Clear"
},
"sponsor": {
"header": "You can help us!",
"message": "We are a tiny team working full time to make NocoDB Open-source. We believe a tool like NocoDB should be available freely to every problem solver on Internet."
},
"loginMsg": "Log In To NocoDB",
"passwordRecovery": {
"message_1": "Please provide the email address you used when you signed up.",
"message_2": "We will send you an email with a link to reset your password.",
"success": "Please check your email to reset the password"
},
"signUp": {
"superAdmin": "You will be the 'Super Admin'",
"alreadyHaveAccount": "Already have an account ?",
"workEmail": "Enter your work email",
"enterPassword": "Enter your password",
"forgotPassword": "Forgot your password ?",
"dontHaveAccount": "Don't have an account ?"
},
"addView": {
"grid": "Add Grid View",
"gallery": "Add Gallery View",
"form": "Add Form View",
"kanban": "Add Kanban View",
"calendar": "Add Calendar View"
},
"tablesMetadataInSync": "Tables metadata is in Sync",
"addMultipleUsers": "You can add multiple comma(,) separated emails",
"enterTableName": "Enter table name",
"addDefaultColumns": "Add default columns",
"tableNameInDb": "Table name as saved in database",
"airtable": {
"credentials": "Where to find this?"
},
"import": {
"clickOrDrag": "Click or drag file to this area to upload"
},
"metaDataRecreated": "Table metadata recreated successfully",
"invalidCredentials": "Invalid credentials",
"downloadingMoreFiles": "Downloading more files",
"copiedToClipboard": "Copied to clipboard",
"requriedFieldsCantBeMoved": "Required field can't be moved",
"updateNotAllowedWithoutPK": "Update not allowed for table which doesn't have primary key",
"autoIncFieldNotEditable": "Auto increment field is not editable",
"editingPKnotSupported": "Editing primary key not supported",
"deletedCache": "Deleted cache successfully",
"cacheEmpty": "Cache is empty",
"exportedCache": "Exported Cache Successfully",
"valueAlreadyInList": "This value is already in the list",
"noColumnsToUpdate": "No columns to update",
"tableDeleted": "Deleted table successfully",
"generatePublicShareableReadonlyBase": "Generate publicly shareable readonly base",
"deleteViewConfirmation": "Are you sure you want to delete this view?",
"deleteTableConfirmation": "Do you want to delete the table",
"showM2mTables": "Show M2M Tables",
"deleteKanbanStackConfirmation": "Deleting this stack will also remove the select option `{stackToBeDeleted}` from the `{groupingField}`. The records will move to the uncategorized stack.",
"computedFieldEditWarning": "Computed field: contents are read-only. Use column edit menu to reconfigure",
"computedFieldDeleteWarning": "Computed field: contents are read-only. Unable to clear content."
},
"error": {
"searchProject": "Your search for {search} found no results",
"invalidChar": "Invalid character in folder path.",
"invalidDbCredentials": "Invalid database credentials.",
"unableToConnectToDb": "Unable to connect to database, please check your database is up.",
"userDoesntHaveSufficientPermission": "User does not exist or have sufficient permission to create schema.",
"dbConnectionStatus": "Invalid database parameters",
"dbConnectionFailed": "Connection Failure:",
"signUpRules": {
"emailReqd": "E-mail is required",
"emailInvalid": "E-mail must be valid",
"passwdRequired": "Password is required",
"passwdLength": "You password must be atleast 8 characters",
"passwdMismatch": "Passwords do not match",
"completeRuleSet": "At least 8 characters with one Uppercase, one number and one special character",
"atLeast8Char": "At least 8 characters",
"atLeastOneUppercase": "One Uppercase letter",
"atLeastOneNumber": "One Number",
"atLeastOneSpecialChar": "One special character",
"allowedSpecialCharList": "Allowed special character list"
},
"invalidURL": "Invalid URL",
"internalError": "Some internal error occurred",
"templateGeneratorNotFound": "Template Generator cannot be found!",
"fileUploadFailed": "Failed to upload file",
"primaryColumnUpdateFailed": "Failed to update primary column",
"formDescriptionTooLong": "Data too long for Form Description",
"columnsRequired": "Following columns are required",
"selectAtleastOneColumn": "At least one column has to be selected",
"columnDescriptionNotFound": "Cannot find the destination column for",
"duplicateMappingFound": "Duplicate mapping found, please remove one of the mapping",
"nullValueViolatesNotNull": "Null value violates not-null constraint",
"sourceHasInvalidNumbers": "Source data contains some invalid numbers",
"sourceHasInvalidBoolean": "Source data contains some invalid boolean values",
"invalidForm": "Invalid Form",
"formValidationFailed": "Form validation failed",
"youHaveBeenSignedOut": "You have been signed out",
"failedToLoadList": "Failed to load list",
"failedToLoadChildrenList": "Failed to load children list",
"deleteFailed": "Delete failed",
"unlinkFailed": "Unlink failed",
"rowUpdateFailed": "Row update failed",
"deleteRowFailed": "Failed to delete row",
"setFormDataFailed": "Failed to set form data",
"formViewUpdateFailed": "Failed to update form view",
"tableNameRequired": "Table name is required",
"nameShouldStartWithAnAlphabetOr_": "Name should start with an alphabet or _",
"followingCharactersAreNotAllowed": "Following characters are not allowed",
"columnNameRequired": "Column name is required",
"projectNameExceeds50Characters": "Project name exceeds 50 characters",
"projectNameCannotStartWithSpace": "Project name cannot start with space",
"requiredField": "Required field",
"ipNotAllowed": "IP not allowed",
"targetFileIsNotAnAcceptedFileType": "Target file is not an accepted file type",
"theAcceptedFileTypeIsCsv": "The accepted file type is .csv",
"theAcceptedFileTypesAreXlsXlsxXlsmOdsOts": "The accepted file types are .xls, .xlsx, .xlsm, .ods, .ots",
"parameterKeyCannotBeEmpty": "Parameter key cannot be empty",
"duplicateParameterKeysAreNotAllowed": "Duplicate parameter keys are not allowed",
"fieldRequired": "{value} cannot be empty.",
"projectNotAccessible": "Project not accessible",
"copyToClipboardError": "Failed to copy to clipboard"
},
"toast": {
"exportMetadata": "Project metadata exported successfully",
"importMetadata": "Project metadata imported successfully",
"clearMetadata": "Project metadata cleared successfully",
"stopProject": "Project stopped successfully",
"startProject": "Project started successfully",
"restartProject": "Project restarted successfully",
"deleteProject": "Project deleted successfully",
"authToken": "Auth token copied to clipboard",
"projInfo": "Copied project info to clipboard",
"inviteUrlCopy": "Copied invite URL to clipboard",
"createView": "View created successfully",
"formEmailSMTP": "Please activate SMTP plugin in App store for enabling email notification",
"collabView": "Successfully Switched to collaborative view",
"lockedView": "Successfully Switched to locked view",
"futureRelease": "Coming soon!"
},
"success": {
"columnDuplicated": "Column duplicated successfully",
"updatedUIACL": "Updated UI ACL for tables successfully",
"pluginUninstalled": "Plugin uninstalled successfully",
"pluginSettingsSaved": "Plugin settings saved successfully",
"pluginTested": "Successfully tested plugin settings",
"tableRenamed": "Table renamed successfully",
"viewDeleted": "View deleted successfully",
"primaryColumnUpdated": "Successfully updated as primary column",
"tableDataExported": "Successfully exported all table data",
"updated": "Successfully updated",
"sharedViewDeleted": "Deleted shared view successfully",
"userDeleted": "User deleted successfully",
"viewRenamed": "View renamed successfully",
"tokenGenerated": "Token generated successfully",
"tokenDeleted": "Token deleted successfully",
"userAddedToProject": "Successfully added user to project",
"userAdded": "Successfully added user",
"userDeletedFromProject": "Successfully deleted user from project",
"inviteEmailSent": "Invite Email sent successfully",
"inviteURLCopied": "Invite URL copied to clipboard",
"passwordResetURLCopied": "Password reset URL copied to clipboard",
"shareableURLCopied": "Copied shareable base URL to clipboard!",
"embeddableHTMLCodeCopied": "Copied embeddable HTML code!",
"userDetailsUpdated": "Successfully updated the user details",
"tableDataImported": "Successfully imported table data",
"webhookUpdated": "Webhook details updated successfully",
"webhookDeleted": "Hook deleted successfully",
"webhookTested": "Webhook tested successfully",
"columnUpdated": "Column updated",
"columnCreated": "Column created",
"passwordChanged": "Password changed successfully. Please login again.",
"settingsSaved": "Settings saved successfully",
"roleUpdated": "Role updated successfully"
}
}
}

3
packages/nc-gui/lib/enums.ts

@ -26,10 +26,12 @@ export enum ClientType {
export enum Language {
ar = 'العربية',
bn_IN = 'ব',
cs = 'Czech',
da = 'Dansk',
de = 'Deutsch',
en = 'English',
es = 'Español',
eu = 'Basque',
fa = 'فارسی',
fi = 'Suomalainen',
fr = 'Français',
@ -47,6 +49,7 @@ export enum Language {
pt = 'Português',
pt_BR = 'Português (Brasil)',
ru = 'Pусский',
sk = 'Slovenčina',
sl = 'Slovenščina',
sv = 'Svenska',
th = 'ไทย',

3
packages/nc-gui/nuxt.config.ts

@ -139,6 +139,9 @@ export default defineNuxtConfig({
}),
monacoEditorPlugin({
languageWorkers: ['json'],
customDistPath: (root: string, buildOutDir: string) => {
return `${buildOutDir}/` + `monacoeditorwork`
},
}),
PurgeIcons({
/* PurgeIcons Options */

76
packages/nc-gui/package-lock.json generated

@ -29,7 +29,7 @@
"jwt-decode": "^3.1.2",
"locale-codes": "^1.3.1",
"monaco-editor": "^0.33.0",
"nocodb-sdk": "0.101.0-beta.0",
"nocodb-sdk": "file:../nocodb-sdk",
"papaparse": "^5.3.2",
"qrcode": "^1.5.1",
"socket.io-client": "^4.5.1",
@ -96,7 +96,6 @@
},
"../nocodb-sdk": {
"version": "0.101.0-beta.0",
"extraneous": true,
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
@ -8544,6 +8543,7 @@
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
"devOptional": true,
"funding": [
{
"type": "individual",
@ -10518,9 +10518,9 @@
"dev": true
},
"node_modules/json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"bin": {
"json5": "lib/cli.js"
@ -11959,21 +11959,8 @@
}
},
"node_modules/nocodb-sdk": {
"version": "0.101.0-beta.0",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.101.0-beta.0.tgz",
"integrity": "sha512-/h12sltRNdbCXop/iGYyWCHQ0iU8CKYNn7VrMrTA+u1kykHBu1ja/zhF6Kk98+m5XGNYAasASxLOFzk2GHvwCw==",
"dependencies": {
"axios": "^0.21.1",
"jsep": "^1.3.6"
}
},
"node_modules/nocodb-sdk/node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"dependencies": {
"follow-redirects": "^1.14.0"
}
"resolved": "../nocodb-sdk",
"link": true
},
"node_modules/node-abi": {
"version": "3.23.0",
@ -15716,9 +15703,9 @@
}
},
"node_modules/tsconfig-paths/node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@ -23937,7 +23924,8 @@
"follow-redirects": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
"integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
"devOptional": true
},
"form-data": {
"version": "4.0.0",
@ -25344,9 +25332,9 @@
"dev": true
},
"json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true
},
"jsonc-eslint-parser": {
@ -26410,22 +26398,22 @@
}
},
"nocodb-sdk": {
"version": "0.101.0-beta.0",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.101.0-beta.0.tgz",
"integrity": "sha512-/h12sltRNdbCXop/iGYyWCHQ0iU8CKYNn7VrMrTA+u1kykHBu1ja/zhF6Kk98+m5XGNYAasASxLOFzk2GHvwCw==",
"version": "file:../nocodb-sdk",
"requires": {
"@typescript-eslint/eslint-plugin": "^4.0.1",
"@typescript-eslint/parser": "^4.0.1",
"axios": "^0.21.1",
"jsep": "^1.3.6"
},
"dependencies": {
"axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"requires": {
"follow-redirects": "^1.14.0"
}
}
"cspell": "^4.1.0",
"eslint": "^7.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-functional": "^3.0.2",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-prettier": "^4.0.0",
"jsep": "^1.3.6",
"npm-run-all": "^4.1.5",
"prettier": "^2.1.1",
"typescript": "^4.0.2"
}
},
"node-abi": {
@ -29229,9 +29217,9 @@
},
"dependencies": {
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"

2
packages/nc-gui/package.json

@ -52,7 +52,7 @@
"jwt-decode": "^3.1.2",
"locale-codes": "^1.3.1",
"monaco-editor": "^0.33.0",
"nocodb-sdk": "0.101.0-beta.0",
"nocodb-sdk": "file:../nocodb-sdk",
"papaparse": "^5.3.2",
"qrcode": "^1.5.1",
"socket.io-client": "^4.5.1",

18
packages/nc-gui/pages/[projectType]/[projectId]/index/index.vue

@ -47,7 +47,7 @@ function onEdit(targetKey: number, action: 'add' | 'remove' | string) {
<a-tabs v-model:activeKey="activeTabIndex" class="nc-root-tabs" type="editable-card" @edit="onEdit">
<a-tab-pane v-for="(tab, i) of tabs" :key="i">
<template #tab>
<div class="flex items-center gap-2 max-w-[110px]" data-testid="nc-tab-title">
<div class="flex items-center gap-2" data-testid="nc-tab-title">
<div class="flex items-center">
<Icon
v-if="tab.meta?.icon"
@ -58,15 +58,11 @@ function onEdit(targetKey: number, action: 'add' | 'remove' | string) {
<component :is="icon(tab)" v-else class="text-sm" />
</div>
<a-tooltip v-if="tab.title?.length > 12" placement="bottom">
<div class="truncate" :data-testid="`nc-root-tabs-${tab.title}`">{{ tab.title }}</div>
<template #title>
<div>{{ tab.title }}</div>
</template>
</a-tooltip>
<div v-else :data-testid="`nc-root-tabs-${tab.title}`">{{ tab.title }}</div>
<div :data-testid="`nc-root-tabs-${tab.title}`">
<GeneralTruncateText :key="tab.title" :length="12">
{{ tab.title }}
</GeneralTruncateText>
</div>
</div>
</template>
</a-tab-pane>
@ -146,6 +142,6 @@ function onEdit(targetKey: number, action: 'add' | 'remove' | string) {
}
:deep(.ant-tabs-tab-remove) {
@apply mt-[3px];
@apply flex mt-[2px];
}
</style>

10
packages/nc-gui/pages/index/index/[projectId].vue

@ -16,9 +16,7 @@ import {
const route = useRoute()
const { loadProject, updateProject, isLoading } = useProject()
loadProject(false)
const { project, loadProject, updateProject, isLoading } = useProject()
const nameValidationRules = [
{
@ -44,6 +42,12 @@ const renameProject = async () => {
}
}
onBeforeMount(async () => {
await loadProject(false)
formState.title = project.value?.title
})
const focus: VNodeRef = (el) => (el as HTMLInputElement)?.focus()
</script>

65
packages/nc-plugin/package-lock.json generated

@ -84,13 +84,10 @@
}
},
"node_modules/@babel/core/node_modules/json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"dependencies": {
"minimist": "^1.2.5"
},
"bin": {
"json5": "lib/cli.js"
},
@ -7632,9 +7629,9 @@
"dev": true
},
"node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@ -11690,17 +11687,26 @@
}
},
"node_modules/tsconfig-paths": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
"integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==",
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
"integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==",
"dev": true,
"dependencies": {
"@types/json5": "^0.0.29",
"json5": "^1.0.1",
"minimist": "^1.2.0",
"minimist": "^1.2.6",
"strip-bom": "^3.0.0"
}
},
"node_modules/tsconfig-paths/node_modules/minimist": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@ -12306,13 +12312,10 @@
},
"dependencies": {
"json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true
},
"semver": {
"version": "6.3.0",
@ -18137,9 +18140,9 @@
"dev": true
},
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
@ -21142,15 +21145,23 @@
}
},
"tsconfig-paths": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
"integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==",
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
"integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==",
"dev": true,
"requires": {
"@types/json5": "^0.0.29",
"json5": "^1.0.1",
"minimist": "^1.2.0",
"minimist": "^1.2.6",
"strip-bom": "^3.0.0"
},
"dependencies": {
"minimist": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
"dev": true
}
}
},
"tslib": {

112
packages/noco-docs/content/en/getting-started/installation.md

@ -298,7 +298,6 @@ npm start
<alert>
If your service fails to start, you may check the logs in ECS console or in Cloudwatch. Generally it fails due to the connection between ECS container and NC_DB. Make sure the security groups have the correct inbound and outbound rules.
</alert>
```
</details>
@ -444,62 +443,61 @@ npm start
See [here](https://gist.github.com/Zamana/e9281d736f9e9ce5882c6f4b140a590e) provided by [C. R. Zamana](https://github.com/Zamana).
## Production Setup
It is mandatory to configure `NC_DB` environment variables for production usecases.
### Environment variables
| Variable | Mandatory | Comments | If absent | |
|------------------------------------|-----------|-------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|---|
| NC_DB | Yes | See our database URLs | A local SQLite will be created in root folder | |
| NC_DB_JSON | Yes | Can be used instead of `NC_DB` and value should be valid knex connection JSON | | |
| NC_DB_JSON_FILE | Yes | Can be used instead of `NC_DB` and value should be a valid path to knex connection JSON | | |
| DATABASE_URL | No | JDBC URL Format. Can be used instead of NC_DB. | | |
| DATABASE_URL_FILE | No | Can be used instead of DATABASE_URL: path to file containing JDBC URL Format. | | |
| NC_AUTH_JWT_SECRET | Yes | JWT secret used for auth and storing other secrets | A Random secret will be generated | |
| PORT | No | For setting app running port | `8080` | |
| DB_QUERY_LIMIT_DEFAULT | No | Default pagination limit | 25 | |
| DB_QUERY_LIMIT_MAX | No | Maximum allowed pagination limit | 1000 | |
| DB_QUERY_LIMIT_MIN | No | Minimum allowed pagination limit | 1 | |
| NC_TOOL_DIR | No | App directory to keep metadata and app related files | Defaults to current working directory. In docker maps to `/usr/app/data/` for mounting volume. | |
| NC_PUBLIC_URL | Yes | Used for sending Email invitations | Best guess from http request params | |
| NC_JWT_EXPIRES_IN | No | JWT token expiry time | `10h` | |
| NC_CONNECT_TO_EXTERNAL_DB_DISABLED | No | Disable Project creation with external database | | |
| NC_INVITE_ONLY_SIGNUP | No | <strong>Removed</strong> since version <kbd>0.99.0</kbd> and now it's recommended to use [super admin settings menu](/setup-and-usages/account-settings#enable--disable-signup). <br><br>Allow users to signup only via invite url, value should be any non-empty string. | | |
| NUXT_PUBLIC_NC_BACKEND_URL | No | Custom Backend URL | ``http://localhost:8080`` will be used | |
| NC_REQUEST_BODY_SIZE | No | Request body size [limit](https://expressjs.com/en/resources/middleware/body-parser.html#limit) | `1048576` | |
| NC_EXPORT_MAX_TIMEOUT | No | After NC_EXPORT_MAX_TIMEOUT csv gets downloaded in batches | Default value 5000(in millisecond) will be used | |
| NC_DISABLE_TELE | No | Disable telemetry | | |
| NC_DASHBOARD_URL | No | Custom dashboard url path | `/dashboard` | |
| NC_GOOGLE_CLIENT_ID | No | Google client id to enable google authentication | | |
| NC_GOOGLE_CLIENT_SECRET | No | Google client secret to enable google authentication | | |
| NC_MIGRATIONS_DISABLED | No | Disable NocoDB migration | | |
| NC_MIN | No | If set to any non-empty string the default splash screen(initial welcome animation) and matrix screensaver will disable | | |
| NC_SENTRY_DSN | No | For Sentry monitoring | | |
| NC_REDIS_URL | No | Custom Redis URL. Example: `redis://:authpassword@127.0.0.1:6380/4` | Meta data will be stored in memory | |
| NC_DISABLE_ERR_REPORT | No | Disable error reporting | | |
| NC_DISABLE_CACHE | No | To be used only while debugging. On setting this to `true` - meta data be fetched from db instead of redis/cache. | `false` | |
| NC_BASEURL_INTERNAL | No | Used as base url for internal(server) API calls | Default value in docker will be `http://localhost:$PORT` and in all other case it's populated from request object | |
| AWS_ACCESS_KEY_ID | No | For Litestream - S3 access key id | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
| AWS_SECRET_ACCESS_KEY | No | For Litestream - S3 secret access key | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
| AWS_BUCKET | No | For Litestream - S3 bucket | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
| AWS_BUCKET_PATH | No | For Litestream - S3 bucket path (like folder within S3 bucket) | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
| NC_SMTP_FROM | No | For SMTP plugin - Email sender address | | |
| NC_SMTP_HOST | No | For SMTP plugin - SMTP host value | | |
| NC_SMTP_PORT | No | For SMTP plugin - SMTP port value | | |
| NC_SMTP_USERNAME | No | For SMTP plugin (Optional) - SMTP username value for authentication | | |
| NC_SMTP_PASSWORD | No | For SMTP plugin (Optional) - SMTP password value for authentication | | |
| NC_SMTP_SECURE | No | For SMTP plugin (Optional) - To enable secure set value as `true` any other value treated as false | | |
| NC_SMTP_IGNORE_TLS | No | For SMTP plugin (Optional) - To ignore tls set value as `true` any other value treated as false. For more info visit https://nodemailer.com/smtp/ | | |
| NC_S3_BUCKET_NAME | No | For S3 storage plugin - AWS S3 bucket name | | |
| NC_S3_REGION | No | For S3 storage plugin - AWS S3 region | | |
| NC_S3_ACCESS_KEY | No | For S3 storage plugin - AWS access key credential for accessing resource | | |
| NC_S3_ACCESS_SECRET | No | For S3 storage plugin - AWS access secret credential for accessing resource | | |
| NC_ADMIN_EMAIL | No | For updating/creating super admin with provided email and password | | |
| NC_ATTACHMENT_FIELD_SIZE | No | For setting the attachment field size(in Bytes) | Defaults to 20MB | |
| NC_ADMIN_PASSWORD | No | For updating/creating super admin with provided email and password. Your password should have at least 8 letters with one uppercase, one number and one special letter(Allowed special chars <code>$&+,:;=?@#&#124;'.^*()%!_-"</code> ) | | |
| NODE_OPTIONS | No | For passing Node.js [options](https://nodejs.org/api/cli.html#node_optionsoptions) to instance | | |
| NC_MINIMAL_DBS | No | Create a new SQLite file for each project. All the db files are stored in `nc_minimal_dbs` folder in current working directory. (This option restricts project creation on external sources) | | |
## Environment Variables
Here is the list of the environment variables that you can use. Even though they are optional, it is **recommended** to configure `NC_DB`, `NC_AUTH_JWT_SECRET`, and `NC_PUBLIC_URL` for production use cases.
| Variable | Comments | If absent | |
|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|---|
| NC_DB | See our database URLs | A local SQLite will be created in root folder if `NC_DB` is not provided | |
| NC_DB_JSON | Can be used instead of `NC_DB` and value should be valid knex connection JSON | | |
| NC_DB_JSON_FILE | Can be used instead of `NC_DB` and value should be a valid path to knex connection JSON | | |
| DATABASE_URL | JDBC URL Format. Can be used instead of NC_DB. | | |
| DATABASE_URL_FILE | Can be used instead of DATABASE_URL: path to file containing JDBC URL Format. | | |
| NC_AUTH_JWT_SECRET | JWT secret used for auth and storing other secrets | A random secret will be generated | |
| PORT | For setting app running port | `8080` | |
| DB_QUERY_LIMIT_DEFAULT | Default pagination limit | 25 | |
| DB_QUERY_LIMIT_MAX | Maximum allowed pagination limit | 1000 | |
| DB_QUERY_LIMIT_MIN | Minimum allowed pagination limit | 1 | |
| NC_TOOL_DIR | App directory to keep metadata and app related files | Defaults to current working directory. In docker maps to `/usr/app/data/` for mounting volume. | |
| NC_PUBLIC_URL | Used for sending Email invitations | Best guess from http request params | |
| NC_JWT_EXPIRES_IN | JWT token expiry time | `10h` | |
| NC_CONNECT_TO_EXTERNAL_DB_DISABLED | Disable Project creation with external database | | |
| NC_INVITE_ONLY_SIGNUP | Removed since version 0.99.0 and now it's recommended to use [super admin settings menu](/setup-and-usages/account-settings#enable--disable-signup). Allow users to signup only via invite url, value should be any non-empty string. | | |
| NUXT_PUBLIC_NC_BACKEND_URL | Custom Backend URL | ``http://localhost:8080`` will be used | |
| NC_REQUEST_BODY_SIZE | Request body size [limit](https://expressjs.com/en/resources/middleware/body-parser.html#limit) | `1048576` | |
| NC_EXPORT_MAX_TIMEOUT | After NC_EXPORT_MAX_TIMEOUT csv gets downloaded in batches | Default value 5000(in millisecond) will be used | |
| NC_DISABLE_TELE | Disable telemetry | | |
| NC_DASHBOARD_URL | Custom dashboard url path | `/dashboard` | |
| NC_GOOGLE_CLIENT_ID | Google client id to enable google authentication | | |
| NC_GOOGLE_CLIENT_SECRET | Google client secret to enable google authentication | | |
| NC_MIGRATIONS_DISABLED | Disable NocoDB migration | | |
| NC_MIN | If set to any non-empty string the default splash screen(initial welcome animation) and matrix screensaver will disable | | |
| NC_SENTRY_DSN | For Sentry monitoring | | |
| NC_REDIS_URL | Custom Redis URL. Example: `redis://:authpassword@127.0.0.1:6380/4` | Meta data will be stored in memory | |
| NC_DISABLE_ERR_REPORT | Disable error reporting | | |
| NC_DISABLE_CACHE | To be used only while debugging. On setting this to `true` - meta data be fetched from db instead of redis/cache. | `false` | |
| NC_BASEURL_INTERNAL | Used as base url for internal(server) API calls | Default value in docker will be `http://localhost:$PORT` and in all other case it's populated from request object | |
| AWS_ACCESS_KEY_ID | For Litestream - S3 access key id | If Litestream is configured and `NC_DB` is not present. SQLite gets backed up to S3 | |
| AWS_SECRET_ACCESS_KEY | For Litestream - S3 secret access key | If Litestream is configured and `NC_DB` is not present. SQLite gets backed up to S3 | |
| AWS_BUCKET | For Litestream - S3 bucket | If Litestream is configured and `NC_DB` is not present. SQLite gets backed up to S3 | |
| AWS_BUCKET_PATH | For Litestream - S3 bucket path (like folder within S3 bucket) | If Litestream is configured and `NC_DB` is not present. SQLite gets backed up to S3 | |
| NC_SMTP_FROM | For SMTP plugin - Email sender address | | |
| NC_SMTP_HOST | For SMTP plugin - SMTP host value | | |
| NC_SMTP_PORT | For SMTP plugin - SMTP port value | | |
| NC_SMTP_USERNAME | For SMTP plugin (Optional) - SMTP username value for authentication | | |
| NC_SMTP_PASSWORD | For SMTP plugin (Optional) - SMTP password value for authentication | | |
| NC_SMTP_SECURE | For SMTP plugin (Optional) - To enable secure set value as `true` any other value treated as false | | |
| NC_SMTP_IGNORE_TLS | For SMTP plugin (Optional) - To ignore tls set value as `true` any other value treated as false. For more info visit https://nodemailer.com/smtp/ | | |
| NC_S3_BUCKET_NAME | For S3 storage plugin - AWS S3 bucket name | | |
| NC_S3_REGION | For S3 storage plugin - AWS S3 region | | |
| NC_S3_ACCESS_KEY | For S3 storage plugin - AWS access key credential for accessing resource | | |
| NC_S3_ACCESS_SECRET | For S3 storage plugin - AWS access secret credential for accessing resource | | |
| NC_ADMIN_EMAIL | For updating/creating super admin with provided email and password | | |
| NC_ATTACHMENT_FIELD_SIZE | For setting the attachment field size(in Bytes) | Defaults to 20MB | |
| NC_ADMIN_PASSWORD | For updating/creating super admin with provided email and password. Your password should have at least 8 letters with one uppercase, one number and one special letter(Allowed special chars $&+,:;=?@#\|'.^*()%!_-" ) | | |
| NODE_OPTIONS | For passing Node.js [options](https://nodejs.org/api/cli.html#node_optionsoptions) to instance | | |
| NC_MINIMAL_DBS | Create a new SQLite file for each project. All the db files are stored in `nc_minimal_dbs` folder in current working directory. (This option restricts project creation on external sources) | | |
## Sample Demos

2
packages/noco-docs/content/en/setup-and-usages/dashboard.md

@ -15,7 +15,7 @@ Enter your work email and your password.
<img width="1492" alt="image" src="https://user-images.githubusercontent.com/35857179/194793294-fa027496-c3c3-44eb-a613-2ba3e3bd26c1.png">
<alert id="password-conditions">
Your password has at least 8 letters with one uppercase, one number and one special letter
Your password has at least 8 letters. No other constraints on case, numbers or special characters.
</alert>
## Initialize Your First Project

99
packages/noco-docs/content/en/setup-and-usages/meta-management.md

@ -1,81 +1,92 @@
---
title: 'Team & Settings > Project Metadata'
description: 'NocoDB Project Metadata'
title: 'Team & Settings > Data Sources'
description: 'NocoDB Data-Source sync, access control & re-config'
position: 600
category: 'Product'
menuTitle: 'Team & Settings > Project Metadata'
menuTitle: 'Team & Settings > Data Sources'
---
Project Metadata includes Database Metadata, UI Access Control and Miscellaneous.
`Data Sources` sub-menu includes
- Database Metadata
- UI Access Control
- ERD
- Add/Remove new data source
- Edit existing data source configuration
- Edit data source visibility options
To access it, click the down arrow button next to Project Name on the top left side, then select `Team & Settings` and clicking `Project Metadata`.
Note that, currently only one external data source can be added per project.
<img width="322" alt="image" src="https://user-images.githubusercontent.com/35857179/194856648-67936db0-ee4d-4060-be3d-af9f86ef8fc6.png"> | <img width="471" alt="image" src="https://user-images.githubusercontent.com/35857179/194850848-869c69a4-e9b6-4a84-8cc0-7fd4b01eb1ad.png">
|--|--|
To access it, click the down arrow button next to Project Name on the top left side, then select `Team & Settings` and clicking `Data Sources`.
<!-- ## Project Metadata
<!-- ![Screenshot 2022-12-29 at 4 26 27 PM](https://user-images.githubusercontent.com/86527202/209941709-1bfdbb01-ebd0-4c85-a966-2a8b4fc6ade7.png) -->
![Screenshot 2022-12-29 at 4 29 24 PM](https://user-images.githubusercontent.com/86527202/209941906-a9c8d48d-d604-4a2f-8ffb-7a9a494bac6b.png)
![Screenshot 2022-12-29 at 4 27 14 PM](https://user-images.githubusercontent.com/86527202/209941716-70f2aaa7-b035-42b2-835e-eb2ca348be42.png)
The metadata is stored in meta directory in project level, database level, and API level.
Under ``Project Metadata``, you can perform the following operations.
<!-- ![Screenshot 2022-12-29 at 3 54 55 PM](https://user-images.githubusercontent.com/86527202/209938195-7384b4d8-0289-447f-bd39-1ec600cd1723.png) -->
<!-- <img width="322" alt="image" src="https://user-images.githubusercontent.com/86527202/209941709-1bfdbb01-ebd0-4c85-a966-2a8b4fc6ade7.png"> | <img alt="image" src="https://user-images.githubusercontent.com/86527202/209941716-70f2aaa7-b035-42b2-835e-eb2ca348be42.png"> -->
<!-- |--|--| -->
![Screenshot 2022-12-29 at 4 15 00 PM](https://user-images.githubusercontent.com/86527202/209940452-5b867b71-b9f1-4e64-af69-14715ab73be7.png)
- Export all metadata from the meta tables to meta directory
- Import all metadata from the meta directory to meta tables
- Export project meta to zip file and download
- Import project meta zip file and restart
- Clear all metadata from meta tables
<alert>
Import won't work with zip files exported from the older version of apps (< 0.11.6). <br>
Import / Export will only transfer metadata and files related to the project and not any table data in the project.
</alert>
## Sync Metadata
## Migration Example
Go to `Data Sources`, click ``Sync Metadata``, you can see your metadata sync status. If it is out of sync, you can sync the schema. See <a href="./sync-schema">Sync Schema</a> for more.0
### Export Metadata
![Screenshot 2022-12-29 at 4 19 35 PM](https://user-images.githubusercontent.com/86527202/209940903-396650b4-e219-494a-863f-c3f1beb51c5e.png)
From the source project, go to `Project Metadata`. Under ``Export / Import Metadata`` tab, select ``Export zip``, click ``Submit``. This step extracts project metadata and stores it in compressed (zip) format.
![image](https://user-images.githubusercontent.com/35857179/161904400-b926494a-4533-41e4-85c3-5c6ca9ea0803.png)
### Import Metadata
From the destination project, go to `Project Metadata`. Under ``Export / Import Metadata`` tab, select ``Import zip``, select ``meta.zip`` file stored in previous step. This step imports project metadata from compressed file (zip) selected and restarts the project.
![image](https://user-images.githubusercontent.com/35857179/161904452-da0ac683-1715-438a-9c9c-91b34f8f45ba.png) -->
## Database Metadata
Go to `Project Metadata`, under ``Metadata``, you can see your metadata sync status. If it is out of sync, you can sync the schema. See <a href="./sync-schema">Sync Schema</a> for more.
<img width="1333" alt="image" src="https://user-images.githubusercontent.com/35857179/194850034-5330458e-85a9-4a3c-87a3-dd2f3edc5b46.png">
<!-- <img width="1333" alt="image" src="https://user-images.githubusercontent.com/35857179/194850034-5330458e-85a9-4a3c-87a3-dd2f3edc5b46.png"> -->
## UI Access Control
Go to `Project Metadata`, under ``UI Access Control``, you can control the access to each table by roles.
Go to `Data Sources`, click ``UI ACL``, you can control the access to each table by roles.
<img width="1336" alt="image" src="https://user-images.githubusercontent.com/35857179/194850281-9030f4c5-06bc-4780-b8fd-5d0c209867e0.png">
<!-- <img width="1336" alt="image" src="https://user-images.githubusercontent.com/35857179/194850281-9030f4c5-06bc-4780-b8fd-5d0c209867e0.png"> -->
![Screenshot 2022-12-29 at 4 20 57 PM](https://user-images.githubusercontent.com/86527202/209941141-deed80a9-7682-48e1-8de9-9c965c990d2d.png)
## ERD
Go to `Project Metadata`, under ``ERD View``, you can see the ERD of your database.
Go to `Data Sources`, click ``ERD``, you can see the ERD of your database.
<img width="1338" alt="image" src="https://user-images.githubusercontent.com/35857179/194850416-54bc49cf-c32f-45e8-aea1-62b07645c26e.png">
![Screenshot 2022-12-29 at 4 21 55 PM](https://user-images.githubusercontent.com/86527202/209941168-b53d2898-8448-47fa-a8b3-6f3572f6b3a2.png)
<!-- <img width="1338" alt="image" src="https://user-images.githubusercontent.com/35857179/194850416-54bc49cf-c32f-45e8-aea1-62b07645c26e.png"> -->
### Junction table names within ERD
- Enable `Show M2M Tables` within Miscellaneous tab
- Enable `Show M2M Tables` within `Project Settings` menu
- Double click on `Show Columns` to see additional checkboxes get enabled.
- Enabling which you should be able to see junction tables and their table names.
<img width="1681" alt="Show Junction table names for many to many table" src="https://user-images.githubusercontent.com/5435402/192140913-9da37700-28fe-404d-88e8-35ba0c8e2f53.png">
## Miscellaneous
## Edit external database configuration parameters
Go to `Data Sources`, click ``Edit``, you can re-configure database credentials.
Please make sure database configuration parameters are valid. Any incorrect parameters could lead to schema loss!
![Screenshot 2022-12-29 at 4 22 08 PM](https://user-images.githubusercontent.com/86527202/209941211-de9670c9-a73c-4719-9957-eeaf05f3a7ee.png)
## Unlink data source
Go to `Data Sources`, click ``Delete`` against the data source that you wish to un-link.
![Screenshot 2022-12-29 at 4 31 16 PM](https://user-images.githubusercontent.com/86527202/209942178-5ae40f14-0e87-41f7-9630-e2bf6f59a906.png)
## Data source visibility
Go to `Data Sources`, toggle ``Radio-button`` against the data source that you wish to hide/un-hide.
![Screenshot 2022-12-29 at 4 31 16 PM 2](https://user-images.githubusercontent.com/86527202/209942198-627f7f14-761b-4709-b9ca-fde5111fa207.png)
<!-- ## Miscellaneous
- Enabling, `Show M2M Tables` will show junction tables between many to many tables.
<img width="1340" alt="image" src="https://user-images.githubusercontent.com/35857179/194850461-3e88752a-ba4f-4ead-9426-9a9e57020061.png">
-->

21
packages/noco-docs/content/en/setup-and-usages/project-settings.md

@ -0,0 +1,21 @@
---
title: 'Team & Settings > Project settings'
description: 'General project configuration options'
position: 612
category: 'Product'
menuTitle: 'Team & Settings > Project Settings'
---
## Overview
Generic project configuration options are retained under `Project Settings` menu. To access it, click the down arrow button next to Project Name on the top left side, then select `Team & Settings`.
<img width="322" alt="image" src="https://user-images.githubusercontent.com/35857179/194856648-67936db0-ee4d-4060-be3d-af9f86ef8fc6.png">
Then, under SETTINGS, click `Project Settings`.
## Miscellaneous
- Enabling, `Show M2M Tables` will show junction tables between many to many tables.
![Screenshot 2022-12-29 at 7 05 04 PM](https://user-images.githubusercontent.com/86527202/209961654-ffe8ddc6-c7e2-4c0d-9762-2b57fb883cfa.png)

2
packages/noco-docs/content/en/setup-and-usages/sync-schema.md

@ -1,7 +1,7 @@
---
title: 'Sync Schema'
description: 'Schema changes made to database from outside NocoDB GUI can be synced'
position: 610
position: 613
category: 'Product'
menuTitle: 'Sync Schema'
---

9233
packages/noco-docs/package-lock.json generated

File diff suppressed because it is too large Load Diff

17
packages/nocodb-sdk/package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "nocodb-sdk",
"version": "0.100.2",
"version": "0.101.0-beta.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "nocodb-sdk",
"version": "0.100.2",
"version": "0.101.0-beta.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
@ -2654,11 +2654,10 @@
"license": "MIT"
},
"node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"license": "MIT",
"dependencies": {
"minimist": "^1.2.0"
},
@ -5823,9 +5822,9 @@
"dev": true
},
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"

17
packages/nocodb-sdk/src/lib/formulaHelpers.ts

@ -8,21 +8,28 @@ export const jsepCurlyHook = {
jsep.hooks.add('gobble-token', function gobbleCurlyLiteral(env) {
const OCURLY_CODE = 123; // {
const CCURLY_CODE = 125; // }
let start = -1;
const { context } = env;
if (
!jsep.isIdentifierStart(context.code) &&
context.code === OCURLY_CODE
) {
if (start == -1) {
start = context.index;
}
context.index += 1;
const nodes = context.gobbleExpressions(CCURLY_CODE);
context.gobbleExpressions(CCURLY_CODE);
if (context.code === CCURLY_CODE) {
context.index += 1;
env.node = {
type: jsep.IDENTIFIER,
// column name with space would break it down to jsep.IDENTIFIER + jsep.LITERAL
// either take node.name for jsep.IDENTIFIER
// or take node.value for jsep.LITERAL
name: nodes.map((node) => node.name || node.value).join(' '),
name: /{{(.*?)}}/.test(context.expr)
? // start would be the position of the first curly bracket
// add 2 to point to the first character for expressions like {{col1}}
context.expr.slice(start + 2, context.index - 1)
: // start would be the position of the first curly bracket
// add 1 to point to the first character for expressions like {col1}
context.expr.slice(start + 1, context.index - 1),
};
return env.node;
} else {

511
packages/nocodb/package-lock.json generated

@ -52,7 +52,7 @@
"isomorphic-dompurify": "^0.19.0",
"jsep": "^1.3.6",
"jsonfile": "^6.1.0",
"jsonwebtoken": "^8.5.1",
"jsonwebtoken": "^9.0.0",
"knex": "2.2.0",
"lodash": "^4.17.19",
"lru-cache": "^6.0.0",
@ -68,7 +68,7 @@
"nc-lib-gui": "0.101.0-beta.0",
"nc-plugin": "0.1.2",
"ncp": "^2.0.0",
"nocodb-sdk": "0.101.0-beta.0",
"nocodb-sdk": "file:../nocodb-sdk",
"nodemailer": "^6.4.10",
"object-hash": "^3.0.0",
"os-locale": "^5.0.0",
@ -154,7 +154,6 @@
},
"../nocodb-sdk": {
"version": "0.101.0-beta.0",
"extraneous": true,
"license": "AGPL-3.0-or-later",
"dependencies": {
"axios": "^0.21.1",
@ -492,6 +491,54 @@
"node": "10 || 12 || 14 || 16 || 18"
}
},
"node_modules/@azure/msal-node/node_modules/jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"engines": {
"node": ">=4",
"npm": ">=1.4.28"
}
},
"node_modules/@azure/msal-node/node_modules/jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"dependencies": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/@azure/msal-node/node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/@azure/msal-node/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"bin": {
"semver": "bin/semver"
}
},
"node_modules/@azure/storage-blob": {
"version": "12.12.0",
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.12.0.tgz",
@ -9380,9 +9427,9 @@
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
},
"node_modules/json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"bin": {
"json5": "lib/cli.js"
@ -9403,24 +9450,18 @@
}
},
"node_modules/jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
"integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"lodash": "^4.17.21",
"ms": "^2.1.1",
"semver": "^5.6.0"
"semver": "^7.3.8"
},
"engines": {
"node": ">=4",
"npm": ">=1.4.28"
"node": ">=12",
"npm": ">=6"
}
},
"node_modules/jsonwebtoken/node_modules/jwa": {
@ -9443,11 +9484,17 @@
}
},
"node_modules/jsonwebtoken/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver"
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/jsprim": {
@ -9857,9 +9904,9 @@
}
},
"node_modules/luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==",
"version": "1.28.1",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.1.tgz",
"integrity": "sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw==",
"engines": {
"node": "*"
}
@ -11175,13 +11222,8 @@
"dev": true
},
"node_modules/nocodb-sdk": {
"version": "0.101.0-beta.0",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.101.0-beta.0.tgz",
"integrity": "sha512-/h12sltRNdbCXop/iGYyWCHQ0iU8CKYNn7VrMrTA+u1kykHBu1ja/zhF6Kk98+m5XGNYAasASxLOFzk2GHvwCw==",
"dependencies": {
"axios": "^0.21.1",
"jsep": "^1.3.6"
}
"resolved": "../nocodb-sdk",
"link": true
},
"node_modules/node-abort-controller": {
"version": "3.0.1",
@ -12662,6 +12704,54 @@
"passport-strategy": "^1.0.0"
}
},
"node_modules/passport-jwt/node_modules/jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"engines": {
"node": ">=4",
"npm": ">=1.4.28"
}
},
"node_modules/passport-jwt/node_modules/jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"dependencies": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/passport-jwt/node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/passport-jwt/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"bin": {
"semver": "bin/semver"
}
},
"node_modules/passport-local": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
@ -14491,6 +14581,46 @@
"node": ">=8"
}
},
"node_modules/snowflake-sdk/node_modules/jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"engines": {
"node": ">=4",
"npm": ">=1.4.28"
}
},
"node_modules/snowflake-sdk/node_modules/jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"dependencies": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/snowflake-sdk/node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/snowflake-sdk/node_modules/mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
@ -14531,6 +14661,14 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/snowflake-sdk/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"bin": {
"semver": "bin/semver"
}
},
"node_modules/snowflake-sdk/node_modules/tmp": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
@ -16370,9 +16508,9 @@
}
},
"node_modules/tsconfig-paths/node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@ -16466,6 +16604,46 @@
"follow-redirects": "^1.14.8"
}
},
"node_modules/twilio/node_modules/jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"engines": {
"node": ">=4",
"npm": ">=1.4.28"
}
},
"node_modules/twilio/node_modules/jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"dependencies": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/twilio/node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/twilio/node_modules/q": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/q/-/q-2.0.3.tgz",
@ -16476,6 +16654,14 @@
"weak-map": "^1.0.5"
}
},
"node_modules/twilio/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"bin": {
"semver": "bin/semver"
}
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@ -17596,9 +17782,9 @@
}
},
"node_modules/webpack-cli/node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@ -18011,9 +18197,9 @@
}
},
"node_modules/webpack/node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@ -19057,6 +19243,49 @@
"@azure/msal-common": "^7.6.0",
"jsonwebtoken": "^8.5.1",
"uuid": "^8.3.0"
},
"dependencies": {
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
}
},
"jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"requires": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
}
}
},
"@azure/storage-blob": {
@ -26050,9 +26279,9 @@
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
},
"json5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
"integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true
},
"jsonfile": {
@ -26065,20 +26294,14 @@
}
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
"integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"lodash": "^4.17.21",
"ms": "^2.1.1",
"semver": "^5.6.0"
"semver": "^7.3.8"
},
"dependencies": {
"jwa": {
@ -26101,9 +26324,12 @@
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
@ -26437,9 +26663,9 @@
}
},
"luxon": {
"version": "1.28.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ=="
"version": "1.28.1",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.1.tgz",
"integrity": "sha512-gYHAa180mKrNIUJCbwpmD0aTu9kV0dREDrwNnuyFAsO1Wt0EVYSZelPnJlbj9HplzXX/YWXHFTL45kvZ53M0pw=="
},
"mailersend": {
"version": "1.3.2",
@ -27510,12 +27736,22 @@
"dev": true
},
"nocodb-sdk": {
"version": "0.101.0-beta.0",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.101.0-beta.0.tgz",
"integrity": "sha512-/h12sltRNdbCXop/iGYyWCHQ0iU8CKYNn7VrMrTA+u1kykHBu1ja/zhF6Kk98+m5XGNYAasASxLOFzk2GHvwCw==",
"version": "file:../nocodb-sdk",
"requires": {
"@typescript-eslint/eslint-plugin": "^4.0.1",
"@typescript-eslint/parser": "^4.0.1",
"axios": "^0.21.1",
"jsep": "^1.3.6"
"cspell": "^4.1.0",
"eslint": "^7.8.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-functional": "^3.0.2",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-prettier": "^4.0.0",
"jsep": "^1.3.6",
"npm-run-all": "^4.1.5",
"prettier": "^2.1.1",
"typescript": "^4.0.2"
}
},
"node-abort-controller": {
@ -28657,6 +28893,49 @@
"requires": {
"jsonwebtoken": "^8.2.0",
"passport-strategy": "^1.0.0"
},
"dependencies": {
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
}
},
"jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"requires": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
}
}
},
"passport-local": {
@ -30095,6 +30374,42 @@
"is-docker": "^2.0.0"
}
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
}
},
"jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"requires": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
@ -30117,6 +30432,11 @@
"glob": "^7.1.3"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
"tmp": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
@ -31538,9 +31858,9 @@
},
"dependencies": {
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
@ -31620,6 +31940,42 @@
"follow-redirects": "^1.14.8"
}
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
}
},
"jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"requires": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"q": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/q/-/q-2.0.3.tgz",
@ -31629,6 +31985,11 @@
"pop-iterate": "^1.0.1",
"weak-map": "^1.0.5"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
}
}
},
@ -32537,9 +32898,9 @@
}
},
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
@ -32834,9 +33195,9 @@
"dev": true
},
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"

6
packages/nocodb/package.json

@ -92,7 +92,7 @@
"isomorphic-dompurify": "^0.19.0",
"jsep": "^1.3.6",
"jsonfile": "^6.1.0",
"jsonwebtoken": "^8.5.1",
"jsonwebtoken": "^9.0.0",
"knex": "2.2.0",
"lodash": "^4.17.19",
"lru-cache": "^6.0.0",
@ -108,7 +108,7 @@
"nc-lib-gui": "0.101.0-beta.0",
"nc-plugin": "0.1.2",
"ncp": "^2.0.0",
"nocodb-sdk": "0.101.0-beta.0",
"nocodb-sdk": "file:../nocodb-sdk",
"nodemailer": "^6.4.10",
"object-hash": "^3.0.0",
"os-locale": "^5.0.0",
@ -183,4 +183,4 @@
"prettier": {
"singleQuote": true
}
}
}

2
packages/nocodb/src/lib/Noco.ts

@ -104,7 +104,7 @@ export default class Noco {
constructor() {
process.env.PORT = process.env.PORT || '8080';
// todo: move
process.env.NC_VERSION = '0098005';
process.env.NC_VERSION = '0100002';
// if env variable NC_MINIMAL_DBS is set, then disable project creation with external sources
if (process.env.NC_MINIMAL_DBS) {

132
packages/nocodb/src/lib/db/sql-client/lib/mysql/mysql.queries.ts

@ -212,7 +212,7 @@ AND t.table_name=?;`,
kcu.TABLE_NAME as tn,
kcu.COLUMN_NAME as cn,
kcu.POSITION_IN_UNIQUE_CONSTRAINT as puc,
kcu.REFERENCED_TABLE_NAME as rtn,
kcu.REFERENCED_TABLE_NAME as rtn,
kcu.REFERENCED_COLUMN_NAME as rcn,
rc.MATCH_OPTION as mo,
rc.UPDATE_RULE as ur,
@ -222,7 +222,8 @@ AND t.table_name=?;`,
information_schema.KEY_COLUMN_USAGE AS kcu
INNER JOIN information_schema.REFERENTIAL_CONSTRAINTS AS rc ON
kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
Group by kcu.CONSTRAINT_NAME,
Group by
kcu.CONSTRAINT_NAME,
kcu.TABLE_NAME,
kcu.COLUMN_NAME,
kcu.POSITION_IN_UNIQUE_CONSTRAINT,
@ -230,71 +231,90 @@ AND t.table_name=?;`,
kcu.REFERENCED_COLUMN_NAME,
rc.MATCH_OPTION,
rc.UPDATE_RULE,
rc.DELETE_RULE ,kcu.table_schema
rc.DELETE_RULE ,
kcu.table_schema
Having
kcu.table_schema = ?
AND kcu.referenced_column_name IS NOT NULL
AND kcu.table_name=?`,
AND kcu.table_name =?`,
paramsHints: ['database', 'tn'],
},
},
relationListAll: {
default: {
sql: `
sql: `SELECT
kcu.constraint_name AS cstn,
kcu.table_name AS tn,
kcu.column_name AS cn,
kcu.position_in_unique_constraint AS puc,
kcu.referenced_table_name AS rtn,
kcu.referenced_column_name AS rcn,
rc.match_option AS mo,
rc.update_rule AS ur,
rc.delete_rule AS dr,
kcu.table_schema AS ts
FROM
(
SELECT
table_schema,
constraint_name,
table_name,
column_name,
position_in_unique_constraint,
referenced_table_name,
referenced_column_name
FROM
information_schema.KEY_COLUMN_USAGE
WHERE
table_schema = :databaseName) AS kcu
INNER JOIN
(
SELECT
constraint_schema,
match_option,
update_rule,
delete_rule,
constraint_name
FROM
information_schema.REFERENTIAL_CONSTRAINTS
WHERE
constraint_schema = :databaseName) AS rc ON
kcu.constraint_name = rc.constraint_name
AND kcu.table_schema = rc.constraint_schema
INNER JOIN
(
SELECT
table_schema,
table_name,
column_name
FROM
information_schema.COLUMNS
WHERE
table_schema = :databaseName
AND table_name IN (
SELECT
kcu.CONSTRAINT_NAME AS cstn,
kcu.TABLE_NAME AS tn,
kcu.COLUMN_NAME AS cn,
kcu.POSITION_IN_UNIQUE_CONSTRAINT AS puc,
kcu.REFERENCED_TABLE_NAME AS rtn,
kcu.REFERENCED_COLUMN_NAME AS rcn,
rc.MATCH_OPTION AS mo,
rc.UPDATE_RULE AS ur,
rc.DELETE_RULE AS dr,
kcu.table_schema AS ts
table_name
FROM
(SELECT
table_schema,
CONSTRAINT_NAME,
TABLE_NAME,
COLUMN_NAME,
POSITION_IN_UNIQUE_CONSTRAINT,
REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME
FROM
information_schema.KEY_COLUMN_USAGE
WHERE
table_schema = :databaseName) AS kcu
INNER JOIN
(SELECT
CONSTRAINT_SCHEMA,
MATCH_OPTION,
UPDATE_RULE,
DELETE_RULE,
CONSTRAINT_NAME
FROM
information_schema.REFERENTIAL_CONSTRAINTS
WHERE
CONSTRAINT_SCHEMA = :databaseName) AS rc ON kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
AND kcu.table_schema = rc.CONSTRAINT_SCHEMA
INNER JOIN
(SELECT
table_schema, TABLE_NAME, COLUMN_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
table_schema = :databaseName AND TABLE_NAME IN (SELECT
TABLE_NAME
FROM
INFORMATION_SCHEMA.TABLES
WHERE
table_schema = :databaseName
AND LOWER(TABLE_TYPE) = 'base table')) AS col ON col.table_schema = kcu.table_schema
AND col.table_name = kcu.TABLE_NAME
AND kcu.REFERENCED_COLUMN_NAME IS NOT NULL
GROUP BY cstn , tn , rcn , cn , puc , rtn ,cn, mo , ur , dr , ts`,
information_schema.TABLES
WHERE
table_schema = :databaseName
AND Lower(table_type) = 'base table')) AS col ON
col.table_schema = kcu.table_schema
AND col.table_name = kcu.table_name
AND kcu.referenced_column_name IS NOT NULL
GROUP BY
cstn ,
tn ,
rcn ,
cn ,
puc ,
rtn ,
cn,
mo ,
ur ,
dr ,
ts`,
paramsHints: ['database'],
},
},

14
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts

@ -1206,14 +1206,14 @@ class BaseModelSqlv2 {
private async getSelectQueryBuilderForFormula(column: Column<any>) {
const formula = await column.getColOptions<FormulaColumn>();
if (formula.error) throw new Error(`Formula error: ${formula.error}`);
const selectQb = await formulaQueryBuilderv2(
const qb = await formulaQueryBuilderv2(
formula.formula,
null,
this.dbDriver,
this.model
this.model,
column
);
return selectQb;
return qb;
}
async getProto() {
@ -1502,7 +1502,6 @@ class BaseModelSqlv2 {
const selectQb = await this.getSelectQueryBuilderForFormula(
column
);
// todo: verify syntax of as ? / ??
qb.select(
this.dbDriver.raw(`?? as ??`, [
selectQb.builder,
@ -1510,7 +1509,10 @@ class BaseModelSqlv2 {
])
);
} catch {
continue;
// return dummy select
qb.select(
this.dbDriver.raw(`'ERR' as ??`, [sanitize(column.title)])
);
}
}
break;

2
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts

@ -246,7 +246,7 @@ const parseConditionV2 = async (
const model = await column.getModel();
const formula = await column.getColOptions<FormulaColumn>();
const builder = (
await formulaQueryBuilderv2(formula.formula, null, knex, model)
await formulaQueryBuilderv2(formula.formula, null, knex, model, column)
).builder;
return parseConditionV2(
new Filter({ ...filter, value: knex.raw('?', [filter.value]) } as any),

86
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts

@ -1,6 +1,7 @@
import jsep from 'jsep';
import mapFunctionName from '../mapFunctionName';
import Model from '../../../../../models/Model';
import Column from '../../../../../models/Column';
import genRollupSelectv2 from '../genRollupSelectv2';
import RollupColumn from '../../../../../models/RollupColumn';
import FormulaColumn from '../../../../../models/FormulaColumn';
@ -9,6 +10,8 @@ import LinkToAnotherRecordColumn from '../../../../../models/LinkToAnotherRecord
import LookupColumn from '../../../../../models/LookupColumn';
import { jsepCurlyHook, UITypes } from 'nocodb-sdk';
import { validateDateWithUnknownFormat } from '../helpers/formulaFnHelper';
import { CacheGetType, CacheScope } from '../../../../../utils/globals';
import NocoCache from '../../../../../cache/NocoCache';
// todo: switch function based on database
@ -45,16 +48,16 @@ const getAggregateFn: (fnName: string) => (args: { qb; knex?; cn }) => any = (
}
};
export default async function formulaQueryBuilderv2(
async function _formulaQueryBuilder(
_tree,
alias,
knex: XKnex,
model: Model,
aliasToColumn = {}
) {
// register jsep curly hook
jsep.plugins.register(jsepCurlyHook);
const tree = jsep(_tree);
// formula may include double curly brackets in previous version
// convert to single curly bracket here for compatibility
const tree = jsep(_tree.replaceAll('{{', '{').replaceAll('}}', '}'));
const columnIdToUidt = {};
@ -66,7 +69,7 @@ export default async function formulaQueryBuilderv2(
case UITypes.Formula:
{
const formulOption = await col.getColOptions<FormulaColumn>();
const { builder } = await formulaQueryBuilderv2(
const { builder } = await _formulaQueryBuilder(
formulOption.formula,
alias,
knex,
@ -340,7 +343,7 @@ export default async function formulaQueryBuilderv2(
const formulaOption =
await lookupColumn.getColOptions<FormulaColumn>();
const lookupModel = await lookupColumn.getModel();
const { builder } = await formulaQueryBuilderv2(
const { builder } = await _formulaQueryBuilder(
formulaOption.formula,
'',
knex,
@ -771,3 +774,74 @@ export default async function formulaQueryBuilderv2(
};
return { builder: fn(tree, alias) };
}
function getTnPath(tb: Model, knex) {
const schema = knex.searchPath?.();
if (knex.clientType() === 'mssql' && schema) {
return knex.raw('??.??', [schema, tb.table_name]);
} else if (knex.clientType() === 'snowflake') {
return [
knex.client.config.connection.database,
knex.client.config.connection.schema,
tb.table_name,
].join('.');
} else {
return tb.table_name;
}
}
export default async function formulaQueryBuilderv2(
_tree,
alias,
knex: XKnex,
model: Model,
column?: Column,
aliasToColumn = {}
) {
// register jsep curly hook once only
jsep.plugins.register(jsepCurlyHook);
// generate qb
const qb = await _formulaQueryBuilder(
_tree,
alias,
knex,
model,
aliasToColumn
);
try {
// dry run qb.builder to see if it will break the grid view or not
// if so, set formula error and show empty selectQb instead
await knex(getTnPath(model, knex)).select(qb.builder).as('dry-run-only');
// if column is provided, i.e. formula has been created
if (column) {
const formula = await column.getColOptions<FormulaColumn>();
// clean the previous formula error if the formula works this time
if (formula.error) {
await FormulaColumn.update(formula.id, {
error: null,
});
}
}
} catch (e) {
console.error(e);
if (column) {
const formula = await column.getColOptions<FormulaColumn>();
// add formula error to show in UI
await FormulaColumn.update(formula.id, {
error: e.message,
});
// update cache to reflect the error in UI
const key = `${CacheScope.COL_FORMULA}:${column.id}`;
let o = await NocoCache.get(key, CacheGetType.TYPE_OBJECT);
if (o) {
o = { ...o, error: e.message };
// set cache
await NocoCache.set(key, o);
}
}
throw new Error(`Formula error: ${e.message}`);
}
return qb;
}

15
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts

@ -138,6 +138,21 @@ const pg = {
.toQuery()} THEN 1 ELSE 0 END ${args.colAlias}`
);
},
SUBSTR: ({ fn, knex, pt, colAlias }: MapFnArgs) => {
const str = fn(pt.arguments[0]);
const positionFrom = fn(pt.arguments[1] ?? 1);
const numberOfCharacters = fn(pt.arguments[2] ?? '');
return knex.raw(
`SUBSTR(${str}::TEXT, ${positionFrom}${
numberOfCharacters ? ', ' + numberOfCharacters : ''
})${colAlias}`
);
},
MOD: ({ fn, knex, pt, colAlias }: MapFnArgs) => {
const x = fn(pt.arguments[0]);
const y = fn(pt.arguments[1]);
return knex.raw(`MOD((${x})::NUMERIC, (${y})::NUMERIC) ${colAlias}`);
},
};
export default pg;

53
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts

@ -83,19 +83,25 @@ const sqlite3 = {
);
},
DATETIME_DIFF: ({ fn, knex, pt, colAlias }: MapFnArgs) => {
let datetime_expr1 = fn(pt.arguments[0]).bindings[0];
let datetime_expr2 = fn(pt.arguments[1]).bindings[0];
let datetime_expr1 = fn(pt.arguments[0]);
let datetime_expr2 = fn(pt.arguments[1]);
// JULIANDAY takes YYYY-MM-DD
datetime_expr1 = convertToTargetFormat(
datetime_expr1,
getDateFormat(datetime_expr1),
'YYYY-MM-DD'
);
datetime_expr2 = convertToTargetFormat(
datetime_expr2,
getDateFormat(datetime_expr2),
'YYYY-MM-DD'
);
if (datetime_expr1.sql === '?' && datetime_expr1.bindings?.[0]) {
datetime_expr1 = `'${convertToTargetFormat(
datetime_expr1.bindings[0],
getDateFormat(datetime_expr1.bindings[0]),
'YYYY-MM-DD'
)}'`;
}
if (datetime_expr2.sql === '?' && datetime_expr2.bindings?.[0]) {
datetime_expr2 = `'${convertToTargetFormat(
datetime_expr2.bindings[0],
getDateFormat(datetime_expr2.bindings[0]),
'YYYY-MM-DD'
)}'`;
}
const rawUnit = pt.arguments[2]
? fn(pt.arguments[2]).bindings[0]
: 'seconds';
@ -103,36 +109,31 @@ const sqlite3 = {
const unit = convertUnits(rawUnit, 'sqlite');
switch (unit) {
case 'seconds':
sql = `ROUND((JULIANDAY('${datetime_expr1}') - JULIANDAY('${datetime_expr2}')) * 86400)`;
sql = `(strftime('%s', ${datetime_expr1}) - strftime('%s', ${datetime_expr2}))`;
break;
case 'minutes':
sql = `ROUND((JULIANDAY('${datetime_expr1}') - JULIANDAY('${datetime_expr2}')) * 1440)`;
sql = `(strftime('%s', ${datetime_expr1}) - strftime('%s', ${datetime_expr2})) / 60`;
break;
case 'hours':
sql = `ROUND((JULIANDAY('${datetime_expr1}') - JULIANDAY('${datetime_expr2}')) * 24)`;
sql = `(strftime('%s', ${datetime_expr1}) - strftime('%s', ${datetime_expr2})) / 3600`;
break;
case 'milliseconds':
sql = `ROUND((JULIANDAY('${datetime_expr1}') - JULIANDAY('${datetime_expr2}')) * 86400000)`;
sql = `(strftime('%s', ${datetime_expr1}) - strftime('%s', ${datetime_expr2})) * 1000`;
break;
case 'weeks':
sql = `ROUND((JULIANDAY('${datetime_expr1}') - JULIANDAY('${datetime_expr2}')) / 7)`;
sql = `ROUND((JULIANDAY(${datetime_expr1}) - JULIANDAY(${datetime_expr2})) / 7)`;
break;
case 'months':
sql = `(ROUND((JULIANDAY('${datetime_expr1}') - JULIANDAY('${datetime_expr2}')) / 365))
* 12 + (ROUND((JULIANDAY('${datetime_expr1}') - JULIANDAY('${datetime_expr2}')) / 365 / 12))`;
sql = `(strftime('%Y', ${datetime_expr1}) - strftime('%Y', ${datetime_expr2})) * 12 + (strftime('%m', ${datetime_expr1}) - strftime('%m', ${datetime_expr2})) `;
break;
case 'quarters':
sql = `
ROUND((JULIANDAY('${datetime_expr1}')) / 365 / 4) -
ROUND((JULIANDAY('${datetime_expr2}')) / 365 / 4) +
(ROUND((JULIANDAY('${datetime_expr1}') - JULIANDAY('${datetime_expr2}')) / 365)) * 4
`;
sql = `(strftime('%Y', ${datetime_expr1}) - strftime('%Y', ${datetime_expr2})) * 4 + (strftime('%m', ${datetime_expr1}) - strftime('%m', ${datetime_expr2})) / 3`;
break;
case 'years':
sql = `ROUND((JULIANDAY('${datetime_expr1}') - JULIANDAY('${datetime_expr2}')) / 365)`;
sql = `strftime('%Y', ${datetime_expr1}) - strftime('%Y', ${datetime_expr2})`;
break;
case 'days':
sql = `JULIANDAY('${datetime_expr1}') - JULIANDAY('${datetime_expr2}')`;
sql = `JULIANDAY(${datetime_expr1}) - JULIANDAY(${datetime_expr2})`;
break;
default:
sql = '';

6
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/sortV2.ts

@ -51,7 +51,8 @@ export default async function sortV2(
).formula,
null,
knex,
model
model,
column
)
).builder;
qb.orderBy(builder, sort.direction || 'asc');
@ -161,7 +162,8 @@ export default async function sortV2(
).formula,
null,
knex,
model
model,
column
)
).builder;

21
packages/nocodb/src/lib/meta/api/columnApis.ts

@ -40,6 +40,7 @@ import { metaApiMetrics } from '../helpers/apiMetrics';
import FormulaColumn from '../../models/FormulaColumn';
import KanbanView from '../../models/KanbanView';
import { MetaTable } from '../../utils/globals';
import formulaQueryBuilderv2 from '../../db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2';
const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 10);
@ -523,6 +524,16 @@ export async function columnAdd(
colBody.formula_raw || colBody.formula,
table.columns
);
try {
// test the query to see if it is valid in db level
const dbDriver = NcConnectionMgrv2.get(base);
await formulaQueryBuilderv2(colBody.formula, null, dbDriver, table);
} catch (e) {
console.error(e);
NcError.badRequest('Invalid Formula');
}
await Column.insert({
...colBody,
fk_model_id: table.id,
@ -759,6 +770,16 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
colBody.formula_raw || colBody.formula,
table.columns
);
try {
// test the query to see if it is valid in db level
const dbDriver = NcConnectionMgrv2.get(base);
await formulaQueryBuilderv2(colBody.formula, null, dbDriver, table);
} catch (e) {
console.error(e);
NcError.badRequest('Invalid Formula');
}
await Column.update(column.id, {
// title: colBody.title,
...column,

13
packages/nocodb/src/lib/meta/api/sync/helpers/job.ts

@ -246,7 +246,7 @@ export default async (
count: UITypes.Count,
lookup: UITypes.Lookup,
autoNumber: UITypes.AutoNumber,
barcode: UITypes.Barcode,
barcode: UITypes.SingleLineText,
button: UITypes.Button,
};
@ -1401,10 +1401,6 @@ export default async (
} else rec[key] = `${value?.name} <${value?.email}>`;
break;
case UITypes.Barcode:
rec[key] = value.text;
break;
case UITypes.Button:
rec[key] = `${value?.label} <${value?.url}>`;
break;
@ -1473,6 +1469,13 @@ export default async (
}
break;
case UITypes.SingleLineText:
// Barcode data
if (value?.text) {
rec[key] = value.text;
}
break;
default:
break;
}

6
packages/nocodb/src/lib/meta/helpers/populateSamplePayload.ts

@ -84,12 +84,12 @@ async function getSampleColumnValue(column: Column): Promise<any> {
break;
case UITypes.SingleLineText:
{
return 'Text';
return 'Sample Text';
}
break;
case UITypes.LongText:
{
return 'Long text';
return 'Sample Long text';
}
break;
case UITypes.Attachment:
@ -189,7 +189,7 @@ async function getSampleColumnValue(column: Column): Promise<any> {
break;
case UITypes.Formula:
{
return 'output';
return 'Sample Output';
}
break;
case UITypes.Rollup:

2
packages/nocodb/src/lib/models/Base.ts

@ -278,7 +278,7 @@ export default class Base implements BaseType {
ncMeta
);
for (const model of models) {
await model.delete(ncMeta);
await model.delete(ncMeta, true);
}
await NocoCache.deepDel(
CacheScope.BASE,

13
packages/nocodb/src/lib/models/Filter.ts

@ -1,6 +1,7 @@
import Noco from '../Noco';
import Model from './Model';
import Column from './Column';
import Hook from './Hook';
import {
CacheDelDirection,
CacheGetType,
@ -10,6 +11,7 @@ import {
import View from './View';
import { FilterType, UITypes } from 'nocodb-sdk';
import NocoCache from '../cache/NocoCache';
import { NcError } from '../meta/helpers/catchError';
export default class Filter {
id: string;
@ -90,7 +92,16 @@ export default class Filter {
}),
};
if (!(filter.project_id && filter.base_id)) {
const model = await Column.get({ colId: filter.fk_column_id }, ncMeta);
let model: { project_id?: string; base_id?: string };
if (filter.fk_view_id) {
model = await View.get(filter.fk_view_id, ncMeta);
} else if (filter.fk_hook_id) {
model = await Hook.get(filter.fk_hook_id, ncMeta);
} else if (filter.fk_column_id) {
model = await Column.get({ colId: filter.fk_column_id }, ncMeta);
} else {
NcError.badRequest('Invalid filter');
}
insertObj.project_id = model.project_id;
insertObj.base_id = model.base_id;
}

27
packages/nocodb/src/lib/models/Model.ts

@ -345,7 +345,7 @@ export default class Model implements TableType {
});
}
async delete(ncMeta = Noco.ncMeta): Promise<boolean> {
async delete(ncMeta = Noco.ncMeta, force = false): Promise<boolean> {
await Audit.deleteRowComments(this.id);
for (const view of await this.getViews(true)) {
@ -391,6 +391,31 @@ export default class Model implements TableType {
}
}
if (force) {
const leftOverColumns = await ncMeta.metaList2(
null,
null,
MetaTable.COL_RELATIONS,
{
condition: {
fk_related_model_id: this.id,
},
}
);
for (const col of leftOverColumns) {
await NocoCache.deepDel(
CacheScope.COL_RELATION,
`${CacheScope.COL_RELATION}:${col.fk_column_id}`,
CacheDelDirection.CHILD_TO_PARENT
);
}
await ncMeta.metaDelete(null, null, MetaTable.COL_RELATIONS, {
fk_related_model_id: this.id,
});
}
await NocoCache.deepDel(
CacheScope.COLUMN,
`${CacheScope.COLUMN}:${this.id}`,

2
packages/nocodb/src/lib/version-upgrader/NcUpgrader.ts

@ -8,6 +8,7 @@ import ncProjectEnvUpgrader0011045 from './ncProjectEnvUpgrader0011045';
import ncProjectUpgraderV2_0090000 from './ncProjectUpgraderV2_0090000';
import ncDataTypesUpgrader from './ncDataTypesUpgrader';
import ncProjectRolesUpgrader from './ncProjectRolesUpgrader';
import ncFilterUpgrader from './ncFilterUpgrader';
const log = debug('nc:version-upgrader');
import boxen from 'boxen';
@ -35,6 +36,7 @@ export default class NcUpgrader {
{ name: '0090000', handler: ncProjectUpgraderV2_0090000 },
{ name: '0098004', handler: ncDataTypesUpgrader },
{ name: '0098005', handler: ncProjectRolesUpgrader },
{ name: '0100002', handler: ncFilterUpgrader },
];
if (!(await ctx.ncMeta.knexConnection?.schema?.hasTable?.('nc_store'))) {
return;

34
packages/nocodb/src/lib/version-upgrader/ncFilterUpgrader.ts

@ -0,0 +1,34 @@
import { NcUpgraderCtx } from './NcUpgrader';
import { MetaTable } from '../utils/globals';
import View from '../models/View';
import Hook from '../models/Hook';
import Column from '../models/Column';
// before 0.101.0, an incorrect project_id was inserted when
// a filter is created without specifying the column
// this upgrader is to retrieve the correct project id from either view, hook, or column
// and update the project id
export default async function ({ ncMeta }: NcUpgraderCtx) {
const filters = await ncMeta.metaList2(null, null, MetaTable.FILTER_EXP);
for (const filter of filters) {
let model: { project_id?: string; base_id?: string };
if (filter.fk_view_id) {
model = await View.get(filter.fk_view_id, ncMeta);
} else if (filter.fk_hook_id) {
model = await Hook.get(filter.fk_hook_id, ncMeta);
} else if (filter.fk_column_id) {
model = await Column.get({ colId: filter.fk_column_id }, ncMeta);
} else {
continue;
}
if (filter.project_id != model.project_id) {
await ncMeta.metaUpdate(
null,
null,
MetaTable.FILTER_EXP,
{ base_id: model.base_id, project_id: model.project_id },
filter.id
);
}
}
}

14
tests/playwright/package-lock.json generated

@ -14,7 +14,7 @@
"xlsx": "^0.18.5"
},
"devDependencies": {
"@playwright/test": "^1.27.1",
"@playwright/test": "1.27.1",
"@typescript-eslint/eslint-plugin": "^4.0.1",
"@typescript-eslint/parser": "^4.0.1",
"axios": "^0.24.0",
@ -2726,9 +2726,9 @@
"dev": true
},
"node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@ -6911,9 +6911,9 @@
"dev": true
},
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
"integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"

13
tests/playwright/pages/Dashboard/common/Cell/DateTimeCell.ts

@ -33,7 +33,18 @@ export class DateTimeCellPageObject extends BasePage {
date: string;
}) {
// title date format needs to be YYYY-MM-DD
await this.rootPage.locator(`td[title="${date}"]`).click();
const [year, month, day] = date.split('-');
// configure year
await this.rootPage.locator('.ant-picker-year-btn').click();
await this.rootPage.locator(`td[title="${year}"]`).click();
// configure month
await this.rootPage.locator('.ant-picker-month-btn').click();
await this.rootPage.locator(`td[title="${year}-${month}"]`).click();
// configure day
await this.rootPage.locator(`td[title="${year}-${month}-${day}"]`).click();
}
async selectTime({

12
tests/playwright/tests/columnFormula.spec.ts

@ -66,10 +66,22 @@ const formulaDataByDbType = (context: NcContext) => [
formula: `DATETIME_DIFF("2022/10/14", "2023/10/14", "y")`,
result: ['-1', '-1', '-1', '-1', '-1'],
},
{
formula: `DATETIME_DIFF(NOW(), "2023/10/14", "y")`,
result: ['0', '0', '0', '0', '0'],
},
{
formula: `DATETIME_DIFF("2023/10/14", NOW(), "y")`,
result: ['0', '0', '0', '0', '0'],
},
{
formula: `DATETIME_DIFF("2022/10/14", "2023/10/14", "d")`,
result: ['-365', '-365', '-365', '-365', '-365'],
},
{
formula: `DATETIME_DIFF("2022/10/14", NOW(), "d")`,
result: ['-90', '-90', '-90', '-90', '-90'],
},
{
formula: `CONCAT(UPPER({City}), LOWER({City}), TRIM(' trimmed '))`,
result: [

3
tests/playwright/tests/language.spec.ts

@ -7,10 +7,12 @@ const langMenu = [
'help-translate',
'ar.json',
'bn_IN.json',
'cs.json',
'da.json',
'de.json',
'en.json',
'es.json',
'eu.json',
'fa.json',
'fi.json',
'fr.json',
@ -28,6 +30,7 @@ const langMenu = [
'pt.json',
'pt_BR.json',
'ru.json',
'sk.json',
'sl.json',
'sv.json',
'th.json',

Loading…
Cancel
Save