Browse Source

Merge pull request #7908 from nocodb/pre-release

0.204.7 Pre-release
pull/7909/head 0.204.7
Pranav C 8 months ago committed by GitHub
parent
commit
7446edb12f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      packages/nc-gui/assets/style.scss
  2. 2
      packages/nc-gui/components/account/AppStore.vue
  3. 2
      packages/nc-gui/components/account/License.vue
  4. 2
      packages/nc-gui/components/cell/attachment/utils.ts
  5. 4
      packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue
  6. 2
      packages/nc-gui/components/nc/Select.vue
  7. 2
      packages/nc-gui/components/project/ShareBaseDlg.vue
  8. 6
      packages/nc-gui/components/smartsheet/Kanban.vue
  9. 2
      packages/nc-gui/components/smartsheet/column/AttachmentOptions.vue
  10. 95
      packages/nc-gui/components/smartsheet/column/SelectOptions.vue
  11. 21
      packages/nc-gui/components/smartsheet/details/Api.vue
  12. 35
      packages/nc-gui/components/smartsheet/details/Fields.vue
  13. 6
      packages/nc-gui/components/smartsheet/grid/usePaginationShortcuts.ts
  14. 2
      packages/nc-gui/composables/useMultiSelect/convertCellData.ts
  15. 5
      packages/nc-gui/lang/ar.json
  16. 5
      packages/nc-gui/lang/bn_IN.json
  17. 5
      packages/nc-gui/lang/cs.json
  18. 5
      packages/nc-gui/lang/da.json
  19. 5
      packages/nc-gui/lang/de.json
  20. 5
      packages/nc-gui/lang/es.json
  21. 5
      packages/nc-gui/lang/eu.json
  22. 5
      packages/nc-gui/lang/fa.json
  23. 5
      packages/nc-gui/lang/fi.json
  24. 5
      packages/nc-gui/lang/fr.json
  25. 5
      packages/nc-gui/lang/he.json
  26. 5
      packages/nc-gui/lang/hi.json
  27. 5
      packages/nc-gui/lang/hr.json
  28. 5
      packages/nc-gui/lang/id.json
  29. 5
      packages/nc-gui/lang/it.json
  30. 5
      packages/nc-gui/lang/ja.json
  31. 5
      packages/nc-gui/lang/ko.json
  32. 5
      packages/nc-gui/lang/lv.json
  33. 5
      packages/nc-gui/lang/nl.json
  34. 5
      packages/nc-gui/lang/no.json
  35. 5
      packages/nc-gui/lang/pl.json
  36. 5
      packages/nc-gui/lang/pt.json
  37. 5
      packages/nc-gui/lang/pt_BR.json
  38. 5
      packages/nc-gui/lang/ru.json
  39. 5
      packages/nc-gui/lang/sk.json
  40. 5
      packages/nc-gui/lang/sl.json
  41. 5
      packages/nc-gui/lang/sv.json
  42. 5
      packages/nc-gui/lang/th.json
  43. 5
      packages/nc-gui/lang/tr.json
  44. 5
      packages/nc-gui/lang/uk.json
  45. 5
      packages/nc-gui/lang/vi.json
  46. 5
      packages/nc-gui/lang/zh-Hans.json
  47. 5
      packages/nc-gui/lang/zh-Hant.json
  48. 2
      packages/nc-gui/lib/acl.ts
  49. 16
      packages/nc-gui/package.json
  50. 2
      packages/nc-gui/pages/account/index/users/[[nestedPage]].vue
  51. 23
      packages/noco-docs/docs/020.getting-started/030.terminologies.md
  52. 3
      packages/noco-docs/docs/020.getting-started/050.self-hosted/020.environment-variables.md
  53. 324
      packages/noco-docs/package-lock.json
  54. 2
      packages/nocodb-sdk/package.json
  55. 6
      packages/nocodb/package.json
  56. 11
      packages/nocodb/src/middlewares/extract-ids/extract-ids.middleware.ts
  57. 34
      packages/nocodb/src/models/BaseUser.ts
  58. 1
      packages/nocodb/src/models/User.ts
  59. 2
      packages/nocodb/src/utils/acl.ts
  60. 1190
      pnpm-lock.yaml
  61. 6
      scripts/pkg-executable/package.json

12
packages/nc-gui/assets/style.scss

@ -65,7 +65,7 @@ main {
}
.nc-scrollbar-md {
overflow-y: scroll;
overflow-y: auto !important;
overflow-x: hidden;
scrollbar-width: thin !important;
@ -89,7 +89,7 @@ main {
}
.nc-scrollbar-lg {
overflow-y: scroll;
overflow-y: auto !important;
overflow-x: hidden;
scrollbar-width: thin !important;
@ -113,7 +113,7 @@ main {
}
.nc-scrollbar-x-md {
overflow-x: scroll;
overflow-x: auto !important;
scrollbar-width: thin !important;
@ -141,7 +141,7 @@ main {
}
.nc-scrollbar-dark-md {
overflow-y: scroll;
overflow-y: auto !important;
overflow-x: hidden;
scrollbar-width: thin !important;
@ -174,7 +174,7 @@ main {
}
.nc-scrollbar-x-md-dark {
overflow-x: scroll;
overflow-x: auto !important;
scrollbar-width: thin !important;
@ -204,7 +204,7 @@ main {
}
.nc-scrollbar-x-lg {
overflow-x: scroll;
overflow-x: auto !important;
&::-webkit-scrollbar {
width: 8px;

2
packages/nc-gui/components/account/AppStore.vue

@ -1,5 +1,5 @@
<template>
<div class="h-full overflow-y-scroll scrollbar-thin-dull pt-2 px-5">
<div class="h-full overflow-y-auto scrollbar-thin-dull pt-2 px-5">
<div class="text-xl mt-4 mb-8 text-left font-weight-bold">{{ $t('title.appStore') }}</div>
<div>
<LazyDashboardSettingsAppStore />

2
packages/nc-gui/components/account/License.vue

@ -36,7 +36,7 @@ loadLicense()
</script>
<template>
<div class="h-full overflow-y-scroll scrollbar-thin-dull">
<div class="h-full overflow-y-auto scrollbar-thin-dull">
<!-- <div class="text-xl mt-4 mb-8 text-center font-weight-bold">License</div>-->
<!-- <div class="mx-auto w-150">-->
<!-- <div>-->

2
packages/nc-gui/components/cell/attachment/utils.ts

@ -76,7 +76,7 @@ export const [useProvideAttachmentCell, useAttachmentCell] = useInjectionState(
// Maximum Number of Attachments per cell
maxNumberOfAttachments: Math.max(1, +appInfo.value.ncMaxAttachmentsAllowed || 50) || 50,
// Maximum File Size per file
maxAttachmentSize: Math.max(1, +appInfo.value.ncMaxAttachmentsAllowed || 20) || 20,
maxAttachmentSize: Math.max(1, +appInfo.value.ncAttachmentFieldSize || 20) || 20,
supportedAttachmentMimeTypes: ['*'],
}),
}

4
packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue

@ -527,7 +527,7 @@ const projectDelete = () => {
v-if="base?.sources?.[0]?.enabled"
key="erd"
data-testid="nc-sidebar-base-relations"
@click="openErdView(base?.sources?.[0]!)"
@click="openErdView(base?.sources?.[0])"
>
<div v-e="['c:base:erd']" class="flex gap-2 items-center">
<GeneralIcon icon="erd" />
@ -766,7 +766,7 @@ const projectDelete = () => {
</div>
</NcMenuItem>
<NcDivider />
<NcMenuItem v-if="isUIAllowed('table-delete')" class="!hover:bg-red-50" @click="tableDelete">
<NcMenuItem v-if="isUIAllowed('tableDelete')" class="!hover:bg-red-50" @click="tableDelete">
<div class="nc-base-option-item flex gap-2 items-center text-red-600">
<GeneralIcon icon="delete" />
{{ $t('general.delete') }}

2
packages/nc-gui/components/nc/Select.vue

@ -109,7 +109,7 @@ const onChange = (value: string) => {
@apply !rounded-xl py-1.5;
.rc-virtual-list-holder {
overflow-y: scroll;
overflow-y: auto;
overflow-x: hidden;
font-weight: 500;

2
packages/nc-gui/components/project/ShareBaseDlg.vue

@ -234,7 +234,7 @@ const onRoleChange = (role: keyof typeof RoleLabels) => (inviteData.roles = role
<div class="flex justify-between gap-3 w-full">
<div
ref="divRef"
class="flex items-center border-1 gap-1 w-full overflow-x-scroll nc-scrollbar-x-md items-center h-10 rounded-lg !min-w-96"
class="flex items-center border-1 gap-1 w-full overflow-x-auto nc-scrollbar-x-md items-center h-10 rounded-lg !min-w-96"
tabindex="0"
:class="{
'border-primary/100': isDivFocused,

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

@ -513,7 +513,10 @@ const getRowId = (row: RowType) => {
</div>
</a-layout-header>
<a-layout-content class="overflow-y-hidden mt-1" style="max-height: calc(100% - 11rem)">
<a-layout-content
class="overflow-y-hidden mt-1"
:style="{ maxHeight: isUIAllowed('dataInsert') ? 'calc(100% - 11rem)' : 'calc(100% - 8rem)' }"
>
<div :ref="kanbanListRef" class="nc-kanban-list h-full nc-scrollbar-dark-md" :data-stack-title="stack.title">
<!-- Draggable Record Card -->
<Draggable
@ -665,6 +668,7 @@ const getRowId = (row: RowType) => {
</div>
<div
v-if="isUIAllowed('dataInsert')"
class="flex flex-row w-full mt-3 justify-between items-center cursor-pointer bg-white px-4 py-2 rounded-lg border-gray-100 border-1 shadow-sm shadow-gray-100"
@click="
() => {

2
packages/nc-gui/components/smartsheet/column/AttachmentOptions.vue

@ -30,7 +30,7 @@ vModel.value.meta = {
// Maximum Number of Attachments per cell
maxNumberOfAttachments: Math.max(1, +appInfo.value.ncMaxAttachmentsAllowed || 50) || 50,
// Maximum File Size per file
maxAttachmentSize: Math.max(1, +appInfo.value.ncMaxAttachmentsAllowed || 20) || 20,
maxAttachmentSize: Math.max(1, +appInfo.value.ncAttachmentFieldSize || 20) || 20,
// allow all mime types by default
supportedAttachmentMimeTypes: ['*'],
}),

95
packages/nc-gui/components/smartsheet/column/SelectOptions.vue

@ -11,6 +11,8 @@ interface Option {
id?: string
fk_colum_id?: string
order?: number
status?: 'remove'
index?: number
}
const props = defineProps<{
@ -30,7 +32,7 @@ const { optionsMagic: _optionsMagic } = useNocoEe()
const optionsWrapperDomRef = ref<HTMLElement>()
const options = ref<(Option & { status?: 'remove'; index?: number })[]>([])
const options = ref<Option[]>([])
const isAddingOption = ref(false)
@ -39,15 +41,14 @@ const OPTIONS_PAGE_COUNT = 20
const loadedOptionAnchor = ref(OPTIONS_PAGE_COUNT)
const isReverseLazyLoad = ref(false)
const renderedOptions = ref<(Option & { status?: 'remove'; index?: number })[]>([])
const savedDefaultOption = ref<Option | null>(null)
const savedCdf = ref<string | null>(null)
const renderedOptions = ref<Option[]>([])
const savedDefaultOption = ref<Option[]>([])
const colorMenus = ref<any>({})
const colors = ref(enumColor.light)
const defaultOption = ref()
const defaultOption = ref<Option[]>([])
const isKanban = inject(IsKanbanInj, ref(false))
@ -115,15 +116,15 @@ onMounted(() => {
}
if (vModel.value.cdf && typeof vModel.value.cdf === 'string') {
const fndDefaultOption = options.value.find((el) => el.title === vModel.value.cdf)
if (!fndDefaultOption) {
const fndDefaultOption = options.value.filter((el) => el.title === vModel.value.cdf)
if (!fndDefaultOption.length) {
vModel.value.cdf = vModel.value.cdf.replace(/^'/, '').replace(/'$/, '')
}
}
const fndDefaultOption = options.value.find((el) => el.title === vModel.value.cdf)
if (fndDefaultOption) {
defaultOption.value = fndDefaultOption
const fndDefaultOption = options.value.filter((el) => el.title === vModel.value.cdf)
if (fndDefaultOption.length) {
defaultOption.value = vModel.value.uidt === UITypes.SingleSelect ? [fndDefaultOption[0]] : fndDefaultOption
}
})
@ -206,17 +207,32 @@ const removeRenderedOption = (index: number) => {
const optionId = renderedOptions.value[index]?.id
if (optionId === defaultOption.value?.id) {
savedDefaultOption.value = { ...defaultOption.value }
savedCdf.value = vModel.value.cdf
defaultOption.value = null
vModel.value.cdf = null
const removedDefaultOption = defaultOption.value.find((o) => o.id === optionId)
if (removedDefaultOption) {
if (vModel.value.uidt === UITypes.SingleSelect) {
savedDefaultOption.value = [removedDefaultOption]
defaultOption.value = []
vModel.value.cdf = null
} else {
savedDefaultOption.value = [...savedDefaultOption.value, removedDefaultOption]
defaultOption.value = defaultOption.value.filter((o) => o.id !== optionId)
vModel.value.cdf = defaultOption.value.map((o) => o.title).join(',')
}
}
}
const optionChanged = (changedId: string) => {
if (changedId && changedId === defaultOption.value?.id) {
vModel.value.cdf = defaultOption.value.title
const optionChanged = (changedElement: Option) => {
const changedDefaultOptionIndex = defaultOption.value.findIndex((o) => o.id === changedElement.id)
if (changedDefaultOptionIndex !== -1) {
if (vModel.value.uidt === UITypes.SingleSelect) {
defaultOption.value[changedDefaultOptionIndex].title = changedElement.title
vModel.value.cdf = changedElement.title
} else {
defaultOption.value[changedDefaultOptionIndex].title = changedElement.title
vModel.value.cdf = defaultOption.value.map((o) => o.title).join(',')
}
}
syncOptions()
}
@ -235,11 +251,18 @@ const undoRemoveRenderedOption = (index: number) => {
const optionId = renderedOptions.value[index]?.id
if (optionId === savedDefaultOption.value?.id) {
defaultOption.value = { ...savedDefaultOption.value }
vModel.value.cdf = savedCdf.value
savedDefaultOption.value = null
savedCdf.value = null
const addedDefaultOption = savedDefaultOption.value.find((o) => o.id === optionId)
if (addedDefaultOption) {
if (vModel.value.uidt === UITypes.SingleSelect) {
defaultOption.value = [addedDefaultOption]
vModel.value.cdf = addedDefaultOption.title
savedDefaultOption.value = []
} else {
defaultOption.value = [...defaultOption.value, addedDefaultOption]
vModel.value.cdf = defaultOption.value.map((o) => o.title).join(',')
savedDefaultOption.value = savedDefaultOption.value.filter((o) => o.id !== optionId)
}
}
}
@ -251,12 +274,26 @@ const undoRemoveRenderedOption = (index: number) => {
// })
// Removes the Select Option from cdf if the option is removed
watch(vModel.value, (next) => {
watch(vModel, (next) => {
const cdfs = (next.cdf ?? '').toString().split(',')
const values = (next.colOptions.options ?? []).map((col) => {
return col.title.replace(/^'/, '').replace(/'$/, '')
})
const newCdf = cdfs.filter((c: string) => values.includes(c)).join(',')
const valuesMap = (next.colOptions.options ?? []).reduce((acc, c) => {
acc[c.title.replace(/^'|'$/g, '')] = c
return acc
}, {})
defaultOption.value = []
const newCdf = cdfs
.filter((c: string) => {
if (valuesMap[c]) {
defaultOption.value.push(valuesMap[c])
return true
}
return false
})
.join(',')
next.cdf = newCdf.length === 0 ? null : newCdf
})
@ -365,7 +402,7 @@ const loadListData = async ($state: any) => {
:data-testid="`select-column-option-input-${index}`"
:disabled="element.status === 'remove'"
@keydown.enter.prevent="element.title?.trim() && addNewOption()"
@change="optionChanged(element.id)"
@change="optionChanged(element)"
/>
</div>

21
packages/nc-gui/components/smartsheet/details/Api.vue

@ -82,11 +82,7 @@ const selectedClient = ref<string | undefined>(langs[0].clients && langs[0].clie
const selectedLangName = ref(langs[0].name)
const apiUrl = computed(
() =>
new URL(
`/api/v1/db/data/noco/${base.value?.id}/${meta.value?.id}/views/${view.value?.id}`,
(appInfo.value && appInfo.value.ncSiteUrl) || '/',
).href,
() => new URL(`/api/v2/tables/${meta.value?.id}/records`, (appInfo.value && appInfo.value.ncSiteUrl) || '/').href,
)
const snippet = computed(
@ -95,12 +91,15 @@ const snippet = computed(
method: 'GET',
headers: [{ name: 'xc-auth', value: token.value, comment: 'JWT Auth token' }],
url: apiUrl.value,
queryString: Object.entries(queryParams.value || {}).map(([name, value]) => {
return {
name,
value: String(value),
}
}),
queryString: [
...Object.entries(queryParams.value || {}).map(([name, value]) => {
return {
name,
value: String(value),
}
}),
{ name: 'viewId', value: view.value?.id },
],
}),
)

35
packages/nc-gui/components/smartsheet/details/Fields.vue

@ -271,29 +271,24 @@ const onFieldUpdate = (state: TableExplorerColumn) => {
const col = fields.value.find((col) => compareCols(col, state))
if (!col) return
const diffs = diff(col, state) as Partial<TableExplorerColumn>
// hack to prevent update status `Updated Field` when clicking on field first time
let isUpdated = true
if (
[UITypes.SingleSelect, UITypes.MultiSelect].includes(col.uidt) &&
Object.keys(diffs).length === 1 &&
diffs?.colOptions?.options &&
(diffs?.colOptions?.options?.length === 0 ||
(diffs?.colOptions?.options[0]?.index !== undefined && Object.keys(diffs?.colOptions?.options[0] || {}).length === 1))
) {
isUpdated = false
}
if (!isUpdated) {
let field = fields.value.find((field) => compareCols(field, state))
if (field) {
field = state
if (state.colOptions && [UITypes.SingleSelect, UITypes.MultiSelect].includes(col.uidt)) {
state = {
...state,
colOptions: {
...(state.colOptions || {}),
options: ((state.colOptions as SelectOptionsType)?.options || []).map((option) => {
if (option?.index !== undefined) {
delete option.index
}
return option
}),
},
}
}
if (Object.keys(diffs).length === 0 || (Object.keys(diffs).length === 1 && 'altered' in diffs) || !isUpdated) {
const diffs = diff(col, state) as Partial<TableExplorerColumn>
if (Object.keys(diffs).length === 0 || (Object.keys(diffs).length === 1 && 'altered' in diffs)) {
ops.value = ops.value.filter((op) => op.op === 'add' || !compareCols(op.column, state))
} else {
const field = ops.value.find((op) => compareCols(op.column, state))

6
packages/nc-gui/components/smartsheet/grid/usePaginationShortcuts.ts

@ -56,9 +56,7 @@ const usePaginationShortcuts = ({
if (!e.altKey) return
e.preventDefault()
const page = 1
await changePageWithLoading(page)
await changePageWithLoading(getTotalPages())
}
const onUp = async (e: KeyboardEvent) => {
@ -67,7 +65,7 @@ const usePaginationShortcuts = ({
if (!e.altKey) return
e.preventDefault()
await changePageWithLoading(getTotalPages())
await changePageWithLoading(1)
}
return {

2
packages/nc-gui/composables/useMultiSelect/convertCellData.ts

@ -146,7 +146,7 @@ export default function convertCellData(
// Maximum Number of Attachments per cell
maxNumberOfAttachments: Math.max(1, +args.appInfo.ncMaxAttachmentsAllowed || 50) || 50,
// Maximum File Size per file
maxAttachmentSize: Math.max(1, +args.appInfo.ncMaxAttachmentsAllowed || 20) || 20,
maxAttachmentSize: Math.max(1, +args.appInfo.ncAttachmentFieldSize || 20) || 20,
supportedAttachmentMimeTypes: ['*'],
}),
}

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Name des Arbeitsbereichs ändern",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Establecer por defecto"
},
"selectFieldsFromRightPannelToAddHere": "Selecciona los campos del panel derecho para añadirlos aquí",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Seleccionar Año",
@ -681,7 +682,7 @@
"sourceNameRequired": "Se requiere el nombre de la fuente",
"changeWsName": "Cambiar el nombre del espacio de trabajo",
"pressEnter": "Pulsa Enter",
"newFormLoaded": "El nuevo formulario se cargará después de",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "Nuevo campo",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Appuyez sur Entrée",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Imposta default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Nome sorgente obbligatorio",
"changeWsName": "Cambia nome area di lavoro",
"pressEnter": "Premi Invio",
"newFormLoaded": "Il nuovo form verrà caricato dopo",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "Nuovo campo",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "기본값 설정"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "소스 이름이 필요합니다",
"changeWsName": "작업 공간 이름 변경",
"pressEnter": "Enter를 누르세요",
"newFormLoaded": "새로운 폼이 로드되었습니다.",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Ustaw domyślne"
},
"selectFieldsFromRightPannelToAddHere": "Wybierz pole z panelu po prawej stronie aby tutaj dodać",
"noOptionsFound": "Nie znaleziono opcji"
"noOptionsFound": "Nie znaleziono opcji",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Wybierz rok",
@ -681,7 +682,7 @@
"sourceNameRequired": "nazwa źródła jest wymagana",
"changeWsName": "Zmień nazwę przestrzeni roboczej",
"pressEnter": "Naciśnij Enter",
"newFormLoaded": "Nowy formularz zostanie załadowany po",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "Nowe pole",

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

@ -429,7 +429,8 @@
"setDefault": "Definir como padrão"
},
"selectFieldsFromRightPannelToAddHere": "Seleccione campos do painel direito para adicionar aqui",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Selecionar ano",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Установить по умолчанию"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Имя источника обязательно",
"changeWsName": "Изменить название рабочего пространства",
"pressEnter": "Нажмите Enter",
"newFormLoaded": "Новая форма будет загружена после",
"newFormLoaded": "Loading new form in",
"webhook": "Вебхук",
"multiField": {
"newField": "Новое поле",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

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

@ -429,7 +429,8 @@
"setDefault": "设为默认"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "必须填写源名称",
"changeWsName": "更改工作区名称",
"pressEnter": "按回车键",
"newFormLoaded": "新表格将在",
"newFormLoaded": "Loading new form in",
"webhook": "网络钩子",
"multiField": {
"newField": "新建字段",

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

@ -429,7 +429,8 @@
"setDefault": "Set Default"
},
"selectFieldsFromRightPannelToAddHere": "Select fields from right panel to add here",
"noOptionsFound": "No options found"
"noOptionsFound": "No options found",
"surveyFormSubmitConfirmMsg": "Are you sure you want to submit this form?"
},
"labels": {
"selectYear": "Select Year",
@ -681,7 +682,7 @@
"sourceNameRequired": "Source name is required",
"changeWsName": "Change Workspace Name",
"pressEnter": "Press Enter",
"newFormLoaded": "New form will be loaded after",
"newFormLoaded": "Loading new form in",
"webhook": "Webhook",
"multiField": {
"newField": "New field",

2
packages/nc-gui/lib/acl.ts

@ -34,8 +34,6 @@ const rolePermissions = {
baseDelete: true,
baseDuplicate: true,
newUser: true,
tableRename: true,
tableDelete: true,
viewCreateOrEdit: true,
baseReorder: true,
},

16
packages/nc-gui/package.json

@ -82,11 +82,11 @@
"qrcode": "^1.5.3",
"rfdc": "^1.3.1",
"showdown": "^2.1.0",
"socket.io-client": "^4.7.4",
"socket.io-client": "^4.7.5",
"sortablejs": "^1.15.2",
"splitpanes": "^3.1.5",
"tinycolor2": "^1.6.0",
"turndown": "^7.1.2",
"turndown": "^7.1.3",
"unique-names-generator": "^4.7.1",
"v3-infinite-loading": "^1.3.1",
"validator": "^13.11.0",
@ -117,15 +117,15 @@
"@iconify-json/ion": "^1.1.15",
"@iconify-json/la": "^1.1.8",
"@iconify-json/logos": "^1.1.42",
"@iconify-json/lucide": "^1.1.172",
"@iconify-json/material-symbols": "^1.1.74",
"@iconify-json/lucide": "^1.1.175",
"@iconify-json/material-symbols": "^1.1.75",
"@iconify-json/mdi": "^1.1.64",
"@iconify-json/mi": "^1.1.8",
"@iconify-json/ph": "^1.1.11",
"@iconify-json/ri": "^1.1.20",
"@iconify-json/simple-icons": "^1.1.94",
"@iconify-json/simple-icons": "^1.1.96",
"@iconify-json/system-uicons": "^1.1.12",
"@iconify-json/tabler": "^1.1.106",
"@iconify-json/tabler": "^1.1.109",
"@iconify-json/vscode-icons": "^1.1.33",
"@intlify/unplugin-vue-i18n": "^0.13.0",
"@nuxt/image": "^1.3.0",
@ -144,10 +144,10 @@
"@types/turndown": "^5.0.4",
"@types/validator": "^13.11.9",
"@types/vue-barcode-reader": "^0.0.3",
"@unocss/nuxt": "^0.58.5",
"@unocss/nuxt": "^0.58.6",
"@vitest/ui": "^0.34.7",
"@vue/compiler-sfc": "^3.4.21",
"@vue/test-utils": "^2.4.4",
"@vue/test-utils": "^2.4.5",
"@vueuse/nuxt": "^10.7.2",
"@windicss/plugin-animations": "^1.0.9",
"@windicss/plugin-question-mark": "^0.1.1",

2
packages/nc-gui/pages/account/index/users/[[nestedPage]].vue

@ -5,7 +5,7 @@ const { isUIAllowed } = useRoles()
</script>
<template>
<div class="h-full overflow-y-scroll scrollbar-thin-dull pt-2">
<div class="h-full overflow-y-auto scrollbar-thin-dull pt-2">
<template
v-if="
$route.params.nestedPage === 'password-reset' ||

23
packages/noco-docs/docs/020.getting-started/030.terminologies.md

@ -30,17 +30,16 @@ The layout below shows the main parts of NocoDB's user interface.
| Term | Description |
|-----------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Base | A base is a collection of one or more tables, often related and linked to one another. Alternative term `Project` |
| Base Owner | Member who had created base. There can be only one owner for a base & ownership is non-transferable |
| Base member | Base member with specific access permissions. Alternative term `Member` `User` |
| Cell | A cell represents the space created where a column and a row intersect within a grid-like structure. It serves as the fundamental unit for storing data |
| Field | A field or column in a table is a container for values that share the same data type. Alternative term `Column` |
| Modal | In the context of user interfaces, a modal is a type of dialog or overlay that appears on top of the main content or interface and requires user interaction before the user can proceed. Modals are often used to gather user input, display alerts, or confirm actions. They typically "block" the rest of the interface until the user dismisses them, making them a focused and attention-grabbing element |
| Record | A record represents a row in a table. Alternative term `Row` |
| Table | A base is housed in tables, where data is logically arranged into rows and columns. A base can have multiple tables. Alternative term `Model` |
| Term | Description |
| Base | A base is a collection of one or more data sources that each contain one or more tables, often related and linked to one another. Alternative term: `Project` |
| Base owner | Member who created the base. There can be only one owner for a base and ownership is non-transferable. |
| Base member | Base member with specific access permissions. Alternative terms: `Member`, `User` |
| Cell | A cell represents the space created where a column and a row intersect within a grid-like structure. It serves as the fundamental unit for storing data. |
| Field | A field or column in a table is a container for values that share the same data type. Alternative term: `Column` |
| Modal | In the context of user interfaces, a modal is a type of dialog or overlay that appears on top of the main content or interface and requires user interaction before the user can proceed. Modals are often used to gather user input, display alerts, or confirm actions. They typically "block" the rest of the interface until the user dismisses them, making them a focused and attention-grabbing element. |
| Record | A record represents a row in a table. Alternative term: `Row` |
| Table | A table is a matrix where data is logically arranged into rows and columns. A base can have multiple tables. Alternative term: `Model` |
| View | A view defines how data within a table is presented and interacted with. Default view type is the grid view; other supported view types include form, gallery, and kanban views. |
| Webhook | A webhook is a mechanism that allows one system to send real-time data to another system or application. It enables automated notifications and data synchronization between different services or platforms by triggering predefined actions or events in response to specific events or updates in the source system. |
| Workspace Owner | Member who had created workspace. There can be only one owner for a workspace & ownership is non-transferable |
| Workspace member | Workspace member with specific access permissions. Alternative term `Member` `User` |
| Workspace | A workspace is a collection of one or more bases. It offers collaborative access to bases by enabling you to bring together interconnected tables, views, and various elements into a unified and organized entity |
| Workspace | A workspace is a collection of one or more bases. It offers collaborative access to bases by enabling you to bring together interconnected tables, views, and various elements into a unified and organized entity. |
| Workspace owner | Member who had created the workspace. There can be only one owner for a workspace and ownership is non-transferable. |
| Workspace member | Workspace member with specific access permissions. Alternative terms: `Member`, `User` |

3
packages/noco-docs/docs/020.getting-started/050.self-hosted/020.environment-variables.md

@ -59,8 +59,9 @@ For production use-cases, it is **recommended** to configure
| 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_MAX_ATTACHMENTS_ALLOWED | Maximum Number of attachments per cell | |
| NC_ADMIN_EMAIL | For updating/creating super admin with provided email and password | |
| 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) | |

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

@ -26,12 +26,12 @@
"sass": "^1.71.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.0.1",
"@docusaurus/module-type-aliases": "3.1.1",
"@tsconfig/docusaurus": "^1.0.7",
"typescript": "^4.9.5"
},
"engines": {
"node": ">=16.14.2"
"node": ">=16.20.2"
}
},
"node_modules/@algolia/autocomplete-core": {
@ -2339,13 +2339,12 @@
}
},
"node_modules/@docusaurus/module-type-aliases": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.0.1.tgz",
"integrity": "sha512-DEHpeqUDsLynl3AhQQiO7AbC7/z/lBra34jTcdYuvp9eGm01pfH1wTVq8YqWZq6Jyx0BgcVl/VJqtE9StRd9Ag==",
"dev": true,
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.1.1.tgz",
"integrity": "sha512-xBJyx0TMfAfVZ9ZeIOb1awdXgR4YJMocIEzTps91rq+hJDFJgJaylDtmoRhUxkwuYmNK1GJpW95b7DLztSBJ3A==",
"dependencies": {
"@docusaurus/react-loadable": "5.5.2",
"@docusaurus/types": "3.0.1",
"@docusaurus/types": "3.1.1",
"@types/history": "^4.7.11",
"@types/react": "*",
"@types/react-router-config": "*",
@ -2412,26 +2411,6 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-content-blog/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-content-docs": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.1.1.tgz",
@ -2461,45 +2440,6 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/module-type-aliases": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.1.1.tgz",
"integrity": "sha512-xBJyx0TMfAfVZ9ZeIOb1awdXgR4YJMocIEzTps91rq+hJDFJgJaylDtmoRhUxkwuYmNK1GJpW95b7DLztSBJ3A==",
"dependencies": {
"@docusaurus/react-loadable": "5.5.2",
"@docusaurus/types": "3.1.1",
"@types/history": "^4.7.11",
"@types/react": "*",
"@types/react-router-config": "*",
"@types/react-router-dom": "*",
"react-helmet-async": "*",
"react-loadable": "npm:@docusaurus/react-loadable@5.5.2"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
}
},
"node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-content-pages": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.1.1.tgz",
@ -2522,26 +2462,6 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-content-pages/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-debug": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.1.1.tgz",
@ -2562,26 +2482,6 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-debug/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-google-analytics": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.1.1.tgz",
@ -2600,26 +2500,6 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-google-analytics/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-google-gtag": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.1.1.tgz",
@ -2639,26 +2519,6 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-google-gtag/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-google-tag-manager": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.1.1.tgz",
@ -2677,26 +2537,6 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-google-tag-manager/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-ideal-image": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-ideal-image/-/plugin-ideal-image-3.1.1.tgz",
@ -2728,26 +2568,6 @@
}
}
},
"node_modules/@docusaurus/plugin-ideal-image/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-sitemap": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.1.1.tgz",
@ -2771,26 +2591,6 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/plugin-sitemap/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/preset-classic": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.1.1.tgz",
@ -2818,26 +2618,6 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/preset-classic/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/react-loadable": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz",
@ -2912,45 +2692,6 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/module-type-aliases": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.1.1.tgz",
"integrity": "sha512-xBJyx0TMfAfVZ9ZeIOb1awdXgR4YJMocIEzTps91rq+hJDFJgJaylDtmoRhUxkwuYmNK1GJpW95b7DLztSBJ3A==",
"dependencies": {
"@docusaurus/react-loadable": "5.5.2",
"@docusaurus/types": "3.1.1",
"@types/history": "^4.7.11",
"@types/react": "*",
"@types/react-router-config": "*",
"@types/react-router-dom": "*",
"react-helmet-async": "*",
"react-loadable": "npm:@docusaurus/react-loadable@5.5.2"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
}
},
"node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/theme-classic/node_modules/clsx": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz",
@ -3000,45 +2741,6 @@
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/theme-common/node_modules/@docusaurus/module-type-aliases": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.1.1.tgz",
"integrity": "sha512-xBJyx0TMfAfVZ9ZeIOb1awdXgR4YJMocIEzTps91rq+hJDFJgJaylDtmoRhUxkwuYmNK1GJpW95b7DLztSBJ3A==",
"dependencies": {
"@docusaurus/react-loadable": "5.5.2",
"@docusaurus/types": "3.1.1",
"@types/history": "^4.7.11",
"@types/react": "*",
"@types/react-router-config": "*",
"@types/react-router-dom": "*",
"react-helmet-async": "*",
"react-loadable": "npm:@docusaurus/react-loadable@5.5.2"
},
"peerDependencies": {
"react": "*",
"react-dom": "*"
}
},
"node_modules/@docusaurus/theme-common/node_modules/@docusaurus/types": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
"joi": "^17.9.2",
"react-helmet-async": "^1.3.0",
"utility-types": "^3.10.0",
"webpack": "^5.88.1",
"webpack-merge": "^5.9.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/@docusaurus/theme-common/node_modules/clsx": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz",
@ -3110,11 +2812,11 @@
}
},
"node_modules/@docusaurus/types": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.0.1.tgz",
"integrity": "sha512-plyX2iU1tcUsF46uQ01pAd4JhexR7n0iiQ5MSnBFX6M6NSJgDYdru/i1/YNPKOnQHBoXGLHv0dNT6OAlDWNjrg==",
"devOptional": true,
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz",
"integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==",
"dependencies": {
"@mdx-js/mdx": "^3.0.0",
"@types/history": "^4.7.11",
"@types/react": "*",
"commander": "^5.1.0",
@ -7034,9 +6736,9 @@
}
},
"node_modules/follow-redirects": {
"version": "1.15.5",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
"integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",

2
packages/nocodb-sdk/package.json

@ -39,7 +39,7 @@
"preinstall": "npx only-allow pnpm"
},
"dependencies": {
"axios": "^1.6.7",
"axios": "^1.6.8",
"jsep": "^1.3.8",
"dayjs": "^1.11.10"
},

6
packages/nocodb/package.json

@ -162,7 +162,7 @@
"rxjs": "^7.8.1",
"slash": "^3.0.0",
"slug": "^8.2.3",
"socket.io": "^4.7.4",
"socket.io": "^4.7.5",
"sql-query-identifier": "^2.6.0",
"sqlite3": "^5.1.7",
"tedious": "^16.6.1",
@ -177,14 +177,14 @@
"devDependencies": {
"@nestjs/cli": "^10.3.2",
"@nestjs/schematics": "^10.1.1",
"@nestjs/testing": "^10.3.3",
"@nestjs/testing": "^10.3.4",
"@nestjsplus/dyn-schematics": "^1.0.12",
"@types/ejs": "^3.1.5",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.12",
"@types/mocha": "^10.0.6",
"@types/multer": "^1.4.11",
"@types/node": "20.11.25",
"@types/node": "20.11.29",
"@types/passport-google-oauth20": "^2.0.14",
"@types/passport-jwt": "^3.0.13",
"@types/supertest": "^2.0.16",

11
packages/nocodb/src/middlewares/extract-ids/extract-ids.middleware.ts

@ -11,6 +11,7 @@ import type {
NestMiddleware,
} from '@nestjs/common';
import {
Audit,
Base,
Column,
Filter,
@ -159,6 +160,16 @@ export class ExtractIdsMiddleware implements NestMiddleware, CanActivate {
id: req.query?.fk_model_id,
});
req.ncBaseId = model?.base_id;
} else if (
[
'/api/v1/db/meta/audits/:auditId/comment',
'/api/v2/meta/audits/:auditId/comment',
].some((auditPatchPath) => req.route.path === auditPatchPath) &&
req.method === 'PATCH' &&
req.params.auditId
) {
const audit = await Audit.get(params.auditId);
req.ncBaseId = audit?.base_id;
}
// extract base id from query params only if it's userMe endpoint or webhook plugin list
else if (

34
packages/nocodb/src/models/BaseUser.ts

@ -163,6 +163,15 @@ export default class BaseUser {
const cachedList = await NocoCache.getList(CacheScope.BASE_USER, [base_id]);
let { list: baseUsers } = cachedList;
const { isNoneList } = cachedList;
const fullVersionCols = [
'invite_token',
'main_roles',
'created_at',
'base_id',
'roles',
];
if (!isNoneList && !baseUsers.length) {
const queryBuilder = ncMeta
.knex(MetaTable.USERS)
@ -170,15 +179,11 @@ export default class BaseUser {
`${MetaTable.USERS}.id`,
`${MetaTable.USERS}.email`,
`${MetaTable.USERS}.display_name`,
...(mode === 'full'
? [
`${MetaTable.USERS}.invite_token`,
`${MetaTable.USERS}.roles as main_roles`,
`${MetaTable.USERS}.created_at as created_at`,
`${MetaTable.PROJECT_USERS}.base_id`,
`${MetaTable.PROJECT_USERS}.roles as roles`,
]
: []),
`${MetaTable.USERS}.invite_token`,
`${MetaTable.USERS}.roles as main_roles`,
`${MetaTable.USERS}.created_at as created_at`,
`${MetaTable.PROJECT_USERS}.base_id`,
`${MetaTable.PROJECT_USERS}.roles as roles`,
);
queryBuilder.leftJoin(MetaTable.PROJECT_USERS, function () {
@ -206,6 +211,17 @@ export default class BaseUser {
]);
}
if (mode === 'full') {
return baseUsers;
}
// remove full version props if viewer
for (const user of baseUsers) {
for (const prop of fullVersionCols) {
delete user[prop];
}
}
return baseUsers;
}

1
packages/nocodb/src/models/User.ts

@ -294,6 +294,7 @@ export default class User implements UserType {
const user = await this.get(userId, ncMeta);
if (!user) NcError.badRequest('User not found');
// todo: skip base user cache delete based on flag
const bases = await BaseUser.getProjectsList(userId, {}, ncMeta);
for (const base of bases) {

2
packages/nocodb/src/utils/acl.ts

@ -92,6 +92,7 @@ const permissionScopes = {
'swaggerJson',
'commentList',
'commentsCount',
'commentUpdate',
'hideAllColumns',
'showAllColumns',
'auditRowUpdate',
@ -197,6 +198,7 @@ const rolePermissions:
commentList: true,
commentsCount: true,
commentRow: true,
commentUpdate: true,
},
},
[ProjectRoles.EDITOR]: {

1190
pnpm-lock.yaml

File diff suppressed because it is too large Load Diff

6
scripts/pkg-executable/package.json

@ -27,10 +27,10 @@
"author": "",
"license": "ISC",
"dependencies": {
"@nestjs/common": "^10.3.3",
"@nestjs/core": "^10.3.3",
"@nestjs/common": "^10.3.4",
"@nestjs/core": "^10.3.4",
"express": "^4.18.3",
"nocodb": "0.204.4"
"nocodb": "0.204.5"
},
"overrides": {
"sqlite3": "5.1.6"

Loading…
Cancel
Save