Browse Source

feat: allow virtual column add/edit/remove - backend

pull/8708/head
Pranav C 5 months ago
parent
commit
0b184fc3ca
  1. 10
      packages/nc-gui/components/smartsheet/column/EditOrAdd.vue
  2. 11
      packages/nc-gui/components/smartsheet/column/UITypesOptionsWithSearch.vue
  3. 10
      packages/nocodb-sdk/src/lib/UITypes.ts
  4. 1
      packages/nocodb-sdk/src/lib/index.ts
  5. 28
      packages/nocodb/src/services/columns.service.ts

10
packages/nc-gui/components/smartsheet/column/EditOrAdd.vue

@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { ColumnReqType, ColumnType } from 'nocodb-sdk' import type { ColumnReqType, ColumnType } from 'nocodb-sdk'
import { UITypes, UITypesName, isLinksOrLTAR, isSelfReferencingTableColumn, isSystemColumn, isVirtualCol } from 'nocodb-sdk' import { UITypes, UITypesName, isLinksOrLTAR, isSelfReferencingTableColumn, isSystemColumn, isVirtualCol, readonlyMetaAllowedTypes } from 'nocodb-sdk'
import MdiPlusIcon from '~icons/mdi/plus-circle-outline' import MdiPlusIcon from '~icons/mdi/plus-circle-outline'
import MdiMinusIcon from '~icons/mdi/minus-circle-outline' import MdiMinusIcon from '~icons/mdi/minus-circle-outline'
import MdiIdentifierIcon from '~icons/mdi/identifier' import MdiIdentifierIcon from '~icons/mdi/identifier'
@ -101,14 +101,6 @@ const onlyNameUpdateOnEditColumns = [
UITypes.Barcode, UITypes.Barcode,
] ]
const readonlyMetaAllowedTypes = [
UITypes.Lookup,
UITypes.Rollup,
UITypes.Formula,
UITypes.Barcode,
UITypes.QrCode,
]
// To close column type dropdown on escape and // To close column type dropdown on escape and
// close modal only when the type popup is close // close modal only when the type popup is close
const isColumnTypeOpen = ref(false) const isColumnTypeOpen = ref(false)

11
packages/nc-gui/components/smartsheet/column/UITypesOptionsWithSearch.vue

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { UITypes, UITypesName } from 'nocodb-sdk' import { UITypes, UITypesName, readonlyMetaAllowedTypes } from 'nocodb-sdk'
const props = defineProps<{ const props = defineProps<{
options: typeof uiTypes options: typeof uiTypes
@ -65,15 +65,6 @@ onMounted(() => {
activeFieldIndex.value = options.value.findIndex((o) => o.name === UITypes.SingleLineText) activeFieldIndex.value = options.value.findIndex((o) => o.name === UITypes.SingleLineText)
}) })
const readonlyMetaAllowedTypes = [
UITypes.Lookup,
UITypes.Rollup,
UITypes.Formula,
UITypes.Barcode,
UITypes.QrCode,
]
const isDisabledUIType = (type: UITypes) => { const isDisabledUIType = (type: UITypes) => {
return isMetaReadOnly.value && !readonlyMetaAllowedTypes.includes(type) return isMetaReadOnly.value && !readonlyMetaAllowedTypes.includes(type)
} }

10
packages/nocodb-sdk/src/lib/UITypes.ts

@ -254,3 +254,13 @@ export const isSelectTypeCol = (
); );
}; };
export default UITypes; export default UITypes;
export const readonlyMetaAllowedTypes = [
UITypes.Lookup,
UITypes.Rollup,
UITypes.Formula,
UITypes.Barcode,
UITypes.QrCode,
]

1
packages/nocodb-sdk/src/lib/index.ts

@ -20,6 +20,7 @@ export {
isHiddenCol, isHiddenCol,
getEquivalentUIType, getEquivalentUIType,
isSelectTypeCol, isSelectTypeCol,
readonlyMetaAllowedTypes,
} from '~/lib/UITypes'; } from '~/lib/UITypes';
export { default as CustomAPI, FileType } from '~/lib/CustomAPI'; export { default as CustomAPI, FileType } from '~/lib/CustomAPI';
export { default as TemplateGenerator } from '~/lib/TemplateGenerator'; export { default as TemplateGenerator } from '~/lib/TemplateGenerator';

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

@ -5,7 +5,9 @@ import {
isCreatedOrLastModifiedTimeCol, isCreatedOrLastModifiedTimeCol,
isLinksOrLTAR, isLinksOrLTAR,
isVirtualCol, isVirtualCol,
readonlyMetaAllowedTypes,
RelationTypes, RelationTypes,
SourceRestriction,
substituteColumnAliasWithIdInFormula, substituteColumnAliasWithIdInFormula,
substituteColumnIdWithAliasInFormula, substituteColumnIdWithAliasInFormula,
UITypes, UITypes,
@ -197,6 +199,16 @@ export class ColumnsService {
Source.get(context, table.source_id), Source.get(context, table.source_id),
); );
// check if source is readonly and column type is not allowed
if (
source?.meta?.[SourceRestriction.META_READONLY] &&
(!readonlyMetaAllowedTypes.includes(column.uidt) ||
(param.column.uidt &&
!readonlyMetaAllowedTypes.includes(param.column.uidt as UITypes)))
) {
NcError.sourceMetaReadOnly(source.alias);
}
const sqlClient = await reuseOrSave('sqlClient', reuse, async () => const sqlClient = await reuseOrSave('sqlClient', reuse, async () =>
NcConnectionMgrv2.getSqlClient(source), NcConnectionMgrv2.getSqlClient(source),
); );
@ -1482,6 +1494,14 @@ export class ColumnsService {
Source.get(context, table.source_id), Source.get(context, table.source_id),
); );
// check if source is readonly and column type is not allowed
if (
source?.meta?.[SourceRestriction.META_READONLY] &&
!readonlyMetaAllowedTypes.includes(param.column.uidt as UITypes)
) {
NcError.sourceMetaReadOnly(source.alias);
}
const base = await reuseOrSave('base', reuse, async () => const base = await reuseOrSave('base', reuse, async () =>
source.getProject(context), source.getProject(context),
); );
@ -2042,6 +2062,14 @@ export class ColumnsService {
Source.get(context, table.source_id, false, ncMeta), Source.get(context, table.source_id, false, ncMeta),
); );
// check if source is readonly and column type is not allowed
if (
source?.meta?.[SourceRestriction.META_READONLY] &&
!readonlyMetaAllowedTypes.includes(column.uidt)
) {
NcError.sourceMetaReadOnly(source.alias);
}
const sqlMgr = await reuseOrSave('sqlMgr', reuse, async () => const sqlMgr = await reuseOrSave('sqlMgr', reuse, async () =>
ProjectMgrv2.getSqlMgr(context, { id: source.base_id }, ncMeta), ProjectMgrv2.getSqlMgr(context, { id: source.base_id }, ncMeta),
); );

Loading…
Cancel
Save