diff --git a/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue b/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue
index 845f74d574..91004c235b 100644
--- a/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue
+++ b/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue
@@ -181,10 +181,10 @@ useEventListener('keydown', (e: KeyboardEvent) => {
-
+
-
+
+import { onMounted } from '@vue/runtime-core'
import type { ColumnType, LinkToAnotherRecordType, TableType } from 'nocodb-sdk'
import { UITypes, isSystemColumn } from 'nocodb-sdk'
import { getRelationName } from './utils'
@@ -14,7 +15,7 @@ const vModel = useVModel(props, 'value', emit)
const meta = $(inject(MetaInj, ref()))
-const { setAdditionalValidations, validateInfos, onDataTypeChange } = useColumnCreateStoreOrThrow()
+const { setAdditionalValidations, validateInfos, onDataTypeChange, isEdit } = useColumnCreateStoreOrThrow()
const { tables } = $(useProject())
@@ -51,12 +52,23 @@ const columns = $computed(() => {
}
return metas[selectedTable.id].columns.filter((c: ColumnType) => !isSystemColumn(c))
})
+
+
+onMounted(() => {
+ if (isEdit.value) {
+ vModel.value.fk_lookup_column_id = vModel.value.colOptions?.fk_lookup_column_id
+ vModel.value.fk_relation_column_id = vModel.value.colOptions?.fk_relation_column_id
+ // delete vModel.value.colOptions
+ }
+})
+
-
+
+import { onMounted } from '@vue/runtime-core'
import type { ColumnType, LinkToAnotherRecordType, TableType } from 'nocodb-sdk'
import { UITypes, isSystemColumn, isVirtualCol } from 'nocodb-sdk'
import { getRelationName } from './utils'
@@ -14,7 +15,7 @@ const vModel = useVModel(props, 'value', emit)
const meta = $(inject(MetaInj, ref()))
-const { setAdditionalValidations, validateInfos, onDataTypeChange } = useColumnCreateStoreOrThrow()
+const { setAdditionalValidations, validateInfos, onDataTypeChange, isEdit } = useColumnCreateStoreOrThrow()
const { tables } = $(useProject())
@@ -71,6 +72,16 @@ const columns = $computed(() => {
return metas[selectedTable.id].columns.filter((c: ColumnType) => !isVirtualCol(c.uidt as UITypes) && !isSystemColumn(c))
})
+
+
+onMounted(() => {
+ if (isEdit.value) {
+ vModel.value.fk_relation_column_id = vModel.value.colOptions?.fk_relation_column_id
+ vModel.value.fk_rollup_column_id = vModel.value.colOptions?.fk_rollup_column_id
+ vModel.value.rollup_function = vModel.value.colOptions?.rollup_function
+ // delete vModel.value.colOptions
+ }
+})
diff --git a/packages/nocodb/src/lib/meta/api/columnApis.ts b/packages/nocodb/src/lib/meta/api/columnApis.ts
index 69b9e1f962..269a9e73df 100644
--- a/packages/nocodb/src/lib/meta/api/columnApis.ts
+++ b/packages/nocodb/src/lib/meta/api/columnApis.ts
@@ -121,6 +121,95 @@ export async function columnGet(req: Request, res: Response) {
res.json(await Column.get({ colId: req.params.columnId }));
}
+async function validateRollupPayload(
+ payload: ColumnReqType & { uidt: UITypes }
+) {
+ validateParams(
+ [
+ 'title',
+ 'fk_relation_column_id',
+ 'fk_rollup_column_id',
+ 'rollup_function',
+ ],
+ payload
+ );
+
+ const relation = await (
+ await Column.get({
+ colId: (payload as RollupColumnReqType).fk_relation_column_id,
+ })
+ ).getColOptions();
+
+ if (!relation) {
+ throw new Error('Relation column not found');
+ }
+
+ let relatedColumn: Column;
+ switch (relation.type) {
+ case 'hm':
+ relatedColumn = await Column.get({
+ colId: relation.fk_child_column_id,
+ });
+ break;
+ case 'mm':
+ case 'bt':
+ relatedColumn = await Column.get({
+ colId: relation.fk_parent_column_id,
+ });
+ break;
+ }
+
+ const relatedTable = await relatedColumn.getModel();
+ if (
+ !(await relatedTable.getColumns()).find(
+ (c) => c.id === (payload as RollupColumnReqType).fk_rollup_column_id
+ )
+ )
+ throw new Error('Rollup column not found in related table');
+}
+
+async function validateLookupPayload(
+ payload: ColumnReqType & { uidt: UITypes }
+) {
+ validateParams(
+ ['title', 'fk_relation_column_id', 'fk_lookup_column_id'],
+ payload
+ );
+
+ const relation = await (
+ await Column.get({
+ colId: (payload as LookupColumnReqType).fk_relation_column_id,
+ })
+ ).getColOptions();
+
+ if (!relation) {
+ throw new Error('Relation column not found');
+ }
+
+ let relatedColumn: Column;
+ switch (relation.type) {
+ case 'hm':
+ relatedColumn = await Column.get({
+ colId: relation.fk_child_column_id,
+ });
+ break;
+ case 'mm':
+ case 'bt':
+ relatedColumn = await Column.get({
+ colId: relation.fk_parent_column_id,
+ });
+ break;
+ }
+
+ const relatedTable = await relatedColumn.getModel();
+ if (
+ !(await relatedTable.getColumns()).find(
+ (c) => c.id === (payload as LookupColumnReqType).fk_lookup_column_id
+ )
+ )
+ throw new Error('Lookup column not found in related table');
+}
+
export async function columnAdd(
req: Request,
res: Response
@@ -153,49 +242,7 @@ export async function columnAdd(
switch (colBody.uidt) {
case UITypes.Rollup:
{
- validateParams(
- [
- 'title',
- 'fk_relation_column_id',
- 'fk_rollup_column_id',
- 'rollup_function',
- ],
- req.body
- );
-
- const relation = await (
- await Column.get({
- colId: (req.body as RollupColumnReqType).fk_relation_column_id,
- })
- ).getColOptions();
-
- if (!relation) {
- throw new Error('Relation column not found');
- }
-
- let relatedColumn: Column;
- switch (relation.type) {
- case 'hm':
- relatedColumn = await Column.get({
- colId: relation.fk_child_column_id,
- });
- break;
- case 'mm':
- case 'bt':
- relatedColumn = await Column.get({
- colId: relation.fk_parent_column_id,
- });
- break;
- }
-
- const relatedTable = await relatedColumn.getModel();
- if (
- !(await relatedTable.getColumns()).find(
- (c) =>
- c.id === (req.body as RollupColumnReqType).fk_rollup_column_id
- )
- )
- throw new Error('Rollup column not found in related table');
+ await validateRollupPayload(req.body);
await Column.insert({
...colBody,
@@ -205,44 +252,7 @@ export async function columnAdd(
break;
case UITypes.Lookup:
{
- validateParams(
- ['title', 'fk_relation_column_id', 'fk_lookup_column_id'],
- req.body
- );
-
- const relation = await (
- await Column.get({
- colId: (req.body as LookupColumnReqType).fk_relation_column_id,
- })
- ).getColOptions();
-
- if (!relation) {
- throw new Error('Relation column not found');
- }
-
- let relatedColumn: Column;
- switch (relation.type) {
- case 'hm':
- relatedColumn = await Column.get({
- colId: relation.fk_child_column_id,
- });
- break;
- case 'mm':
- case 'bt':
- relatedColumn = await Column.get({
- colId: relation.fk_parent_column_id,
- });
- break;
- }
-
- const relatedTable = await relatedColumn.getModel();
- if (
- !(await relatedTable.getColumns()).find(
- (c) =>
- c.id === (req.body as LookupColumnReqType).fk_lookup_column_id
- )
- )
- throw new Error('Lookup column not found in related table');
+ await validateLookupPayload(req.body);
await Column.insert({
...colBody,
@@ -753,6 +763,30 @@ export async function columnSetAsPrimary(req: Request, res: Response) {
res.json(await Model.updatePrimaryColumn(column.fk_model_id, column.id));
}
+const isAllPropsPresent = (obj: Record, props: string[]) => {
+ return props.every((prop) => obj[prop]);
+};
+
+async function updateRollupOrLookup(colBody: any, column: Column) {
+ if (
+ UITypes.Lookup === column.uidt &&
+ isAllPropsPresent(colBody, ['fk_lookup_column_id', 'fk_relation_column_id'])
+ ) {
+ await validateLookupPayload(colBody);
+ await Column.update(column.id, colBody);
+ } else if (
+ UITypes.Rollup === column.uidt &&
+ isAllPropsPresent(colBody, [
+ 'fk_relation_column_id',
+ 'fk_rollup_column_id',
+ 'rollup_function',
+ ])
+ ) {
+ await validateRollupPayload(colBody);
+ await Column.update(column.id, colBody);
+ }
+}
+
export async function columnUpdate(req: Request, res: Response) {
const column = await Column.get({ colId: req.params.columnId });
@@ -824,6 +858,7 @@ export async function columnUpdate(req: Request, res: Response) {
title: colBody.title,
});
}
+ await updateRollupOrLookup(colBody, column);
} else {
NcError.notImplemented(
`Updating ${colBody.uidt} => ${colBody.uidt} is not implemented`