diff --git a/packages/nc-gui/components/smartsheet/header/Menu.vue b/packages/nc-gui/components/smartsheet/header/Menu.vue index d52777e577..bdbf357df7 100644 --- a/packages/nc-gui/components/smartsheet/header/Menu.vue +++ b/packages/nc-gui/components/smartsheet/header/Menu.vue @@ -132,8 +132,6 @@ const duplicateColumn = async () => { } try { - await $api.dbTableColumn.create(meta!.value!.id!, columnCreatePayload) - await getMeta(meta!.value!.id!, true) const gridViewColumnList = await $api.dbViewColumn.list(view.value?.id as string) @@ -145,9 +143,15 @@ const duplicateColumn = async () => { let newColumnOrder = (gridViewColumnList[currentColumnIndex].order! + gridViewColumnList[currentColumnIndex + 1]?.order) / 2 - await $api.dbViewColumn.update(view.value!.id!, gridViewColumnList[gridViewColumnList.length - 1].id, { - order: newColumnOrder, + await $api.dbTableColumn.create(meta!.value!.id!, { + ...columnCreatePayload, + columnOrder: { + order: newColumnOrder, + viewId: view.value?.id as string, + }, }) + await getMeta(meta!.value!.id!, true) + eventBus.emit(SmartsheetStoreEvents.FIELD_RELOAD) } catch (e: any) { diff --git a/packages/nocodb-sdk/src/lib/Api.ts b/packages/nocodb-sdk/src/lib/Api.ts index 8388bb2f4e..ff2870a132 100644 --- a/packages/nocodb-sdk/src/lib/Api.ts +++ b/packages/nocodb-sdk/src/lib/Api.ts @@ -571,91 +571,109 @@ export interface HookLogType { updated_at?: string; } -export type ColumnReqType = - | { - uidt?: - | 'ID' - | 'SingleLineText' - | 'LongText' - | 'Attachment' - | 'Checkbox' - | 'MultiSelect' - | 'SingleSelect' - | 'Collaborator' - | 'Date' - | 'Year' - | 'Time' - | 'PhoneNumber' - | 'Email' - | 'URL' - | 'Number' - | 'Decimal' - | 'Currency' - | 'Percent' - | 'Duration' - | 'Rating' - | 'Count' - | 'DateTime' - | 'CreateTime' - | 'LastModifiedTime' - | 'AutoNumber' - | 'Geometry' - | 'JSON' - | 'SpecificDBType' - | 'Barcode' - | 'Button'; - id?: string; - base_id?: string; - fk_model_id?: string; - title?: string; - dt?: string; - np?: string; - ns?: string; - clen?: string | number; - cop?: string; - pk?: boolean; - pv?: boolean; - rqd?: boolean; - column_name?: string; - un?: boolean; - ct?: string; - ai?: boolean; - unique?: boolean; - cdf?: string; - cc?: string; - csn?: string; - dtx?: string; - dtxp?: string; - dtxs?: string; - au?: boolean; - ''?: string; - } - | { - uidt: 'LinkToAnotherRecord'; - title: string; - parentId: string; - childId: string; - type: 'hm' | 'bt' | 'mm'; - } - | { - uidt?: 'Rollup'; - title?: string; - fk_relation_column_id?: string; - fk_rollup_column_id?: string; - rollup_function?: string; - } - | { - uidt?: 'Lookup'; - title?: string; - fk_relation_column_id?: string; - fk_lookup_column_id?: string; - } - | { - uidt?: string; - formula_raw?: string; - formula?: string; - title?: string; - }; +export interface NormalColumnRequestType { + uidt?: + | 'ID' + | 'SingleLineText' + | 'LongText' + | 'Attachment' + | 'Checkbox' + | 'MultiSelect' + | 'SingleSelect' + | 'Collaborator' + | 'Date' + | 'Year' + | 'Time' + | 'PhoneNumber' + | 'Email' + | 'URL' + | 'Number' + | 'Decimal' + | 'Currency' + | 'Percent' + | 'Duration' + | 'Rating' + | 'Count' + | 'DateTime' + | 'CreateTime' + | 'LastModifiedTime' + | 'AutoNumber' + | 'Geometry' + | 'JSON' + | 'SpecificDBType' + | 'Barcode' + | 'Button'; + id?: string; + base_id?: string; + fk_model_id?: string; + title?: string; + dt?: string; + np?: string; + ns?: string; + clen?: string | number; + cop?: string; + pk?: boolean; + pv?: boolean; + rqd?: boolean; + column_name?: string; + un?: boolean; + ct?: string; + ai?: boolean; + unique?: boolean; + cdf?: string; + cc?: string; + csn?: string; + dtx?: string; + dtxp?: string; + dtxs?: string; + au?: boolean; +} + +export interface LinkToAnotherColumnReqType { + uidt: 'LinkToAnotherRecord'; + title: string; + virtual?: boolean; + parentId: string; + childId: string; + type: 'hm' | 'bt' | 'mm'; +} + +export interface RollupColumnReqType { + uidt?: 'Rollup'; + title?: string; + fk_relation_column_id?: string; + fk_rollup_column_id?: string; + rollup_function?: string; +} + +export interface LookupColumnReqType { + uidt?: 'Lookup'; + title?: string; + fk_relation_column_id?: string; + fk_lookup_column_id?: string; +} + +export interface FormulaColumnReqType { + uidt?: string; + formula_raw?: string; + formula?: string; + title?: string; +} + +export type ColumnReqType = ( + | NormalColumnRequestType + | LinkToAnotherColumnReqType + | RollupColumnReqType + | FormulaColumnReqType + | LookupColumnReqType +) & { + column_name?: string; + title?: string; + columnOrder?: { + viewId?: string; + order?: number; + }; +}; export interface UserInfoType { id?: string; diff --git a/packages/nocodb/src/lib/meta/api/columnApis.ts b/packages/nocodb/src/lib/meta/api/columnApis.ts index 79dc490f28..00551e639f 100644 --- a/packages/nocodb/src/lib/meta/api/columnApis.ts +++ b/packages/nocodb/src/lib/meta/api/columnApis.ts @@ -15,9 +15,13 @@ import { import { AuditOperationSubTypes, AuditOperationTypes, + ColumnReqType, isVirtualCol, + LinkToAnotherColumnReqType, LinkToAnotherRecordType, + LookupColumnReqType, RelationTypes, + RollupColumnReqType, substituteColumnAliasWithIdInFormula, substituteColumnIdWithAliasInFormula, TableType, @@ -96,7 +100,10 @@ async function createHmAndBtColumn( } } -export async function columnAdd(req: Request, res: Response) { +export async function columnAdd( + req: Request, + res: Response +) { const table = await Model.getWithInfo({ id: req.params.tableId, }); @@ -121,7 +128,7 @@ export async function columnAdd(req: Request, res: Response) { NcError.badRequest('Duplicate column alias'); } - let colBody = req.body; + let colBody: any = req.body; switch (colBody.uidt) { case UITypes.Rollup: { @@ -137,7 +144,7 @@ export async function columnAdd(req: Request, res: Response) { const relation = await ( await Column.get({ - colId: req.body.fk_relation_column_id, + colId: (req.body as RollupColumnReqType).fk_relation_column_id, }) ).getColOptions(); @@ -163,7 +170,8 @@ export async function columnAdd(req: Request, res: Response) { const relatedTable = await relatedColumn.getModel(); if ( !(await relatedTable.getColumns()).find( - (c) => c.id === req.body.fk_rollup_column_id + (c) => + c.id === (req.body as RollupColumnReqType).fk_rollup_column_id ) ) throw new Error('Rollup column not found in related table'); @@ -183,7 +191,7 @@ export async function columnAdd(req: Request, res: Response) { const relation = await ( await Column.get({ - colId: req.body.fk_relation_column_id, + colId: (req.body as LookupColumnReqType).fk_relation_column_id, }) ).getColOptions(); @@ -209,7 +217,8 @@ export async function columnAdd(req: Request, res: Response) { const relatedTable = await relatedColumn.getModel(); if ( !(await relatedTable.getColumns()).find( - (c) => c.id === req.body.fk_lookup_column_id + (c) => + c.id === (req.body as LookupColumnReqType).fk_lookup_column_id ) ) throw new Error('Lookup column not found in related table'); @@ -227,14 +236,21 @@ export async function columnAdd(req: Request, res: Response) { validateParams(['parentId', 'childId', 'type'], req.body); // get parent and child models - const parent = await Model.getWithInfo({ id: req.body.parentId }); - const child = await Model.getWithInfo({ id: req.body.childId }); + const parent = await Model.getWithInfo({ + id: (req.body as LinkToAnotherColumnReqType).parentId, + }); + const child = await Model.getWithInfo({ + id: (req.body as LinkToAnotherColumnReqType).childId, + }); let childColumn: Column; const sqlMgr = await ProjectMgrv2.getSqlMgr({ id: base.project_id, }); - if (req.body.type === 'hm' || req.body.type === 'bt') { + if ( + (req.body as LinkToAnotherColumnReqType).type === 'hm' || + (req.body as LinkToAnotherColumnReqType).type === 'bt' + ) { // populate fk column name const fkColName = getUniqueColumnName( await child.getColumns(), @@ -285,7 +301,7 @@ export async function columnAdd(req: Request, res: Response) { childColumn = await Column.get({ colId: id }); // ignore relation creation if virtual - if (!req.body.virtual) { + if (!(req.body as LinkToAnotherColumnReqType).virtual) { // create relation await sqlMgr.sqlOpPlus(base, 'relationCreate', { childColumn: fkColName, @@ -315,11 +331,11 @@ export async function columnAdd(req: Request, res: Response) { child, parent, childColumn, - req.body.type, - req.body.title, - req.body.virtual + (req.body as LinkToAnotherColumnReqType).type as RelationTypes, + (req.body as LinkToAnotherColumnReqType).title, + (req.body as LinkToAnotherColumnReqType).virtual ); - } else if (req.body.type === 'mm') { + } else if ((req.body as LinkToAnotherColumnReqType).type === 'mm') { const aTn = `${project?.prefix ?? ''}_nc_m2m_${randomID()}`; const aTnAlias = aTn; @@ -378,7 +394,7 @@ export async function columnAdd(req: Request, res: Response) { columns: associateTableCols, }); - if (!req.body.virtual) { + if (!(req.body as LinkToAnotherColumnReqType).virtual) { const rel1Args = { ...req.body, childTable: aTn, @@ -412,7 +428,7 @@ export async function columnAdd(req: Request, res: Response) { childCol, null, null, - req.body.virtual, + (req.body as LinkToAnotherColumnReqType).virtual, true ); await createHmAndBtColumn( @@ -421,7 +437,7 @@ export async function columnAdd(req: Request, res: Response) { parentCol, null, null, - req.body.virtual, + (req.body as LinkToAnotherColumnReqType).virtual, true ); diff --git a/packages/nocodb/src/lib/models/Column.ts b/packages/nocodb/src/lib/models/Column.ts index c8ff874115..969795e745 100644 --- a/packages/nocodb/src/lib/models/Column.ts +++ b/packages/nocodb/src/lib/models/Column.ts @@ -5,7 +5,7 @@ import RollupColumn from './RollupColumn'; import SelectOption from './SelectOption'; import Model from './Model'; import NocoCache from '../cache/NocoCache'; -import { AllowedColumnTypesForQrCode, ColumnType, UITypes } from 'nocodb-sdk'; +import { ColumnReqType, AllowedColumnTypesForQrCode, ColumnType, UITypes } from 'nocodb-sdk'; import { CacheDelDirection, CacheGetType, diff --git a/packages/nocodb/src/lib/models/GridViewColumn.ts b/packages/nocodb/src/lib/models/GridViewColumn.ts index f00bee3ea2..4d0215e9d3 100644 --- a/packages/nocodb/src/lib/models/GridViewColumn.ts +++ b/packages/nocodb/src/lib/models/GridViewColumn.ts @@ -70,9 +70,11 @@ export default class GridViewColumn implements GridColumnType { const insertObj = { fk_view_id: column.fk_view_id, fk_column_id: column.fk_column_id, - order: await ncMeta.metaGetNextOrder(MetaTable.GRID_VIEW_COLUMNS, { - fk_view_id: column.fk_view_id, - }), + order: + column?.order ?? + (await ncMeta.metaGetNextOrder(MetaTable.GRID_VIEW_COLUMNS, { + fk_view_id: column.fk_view_id, + })), show: column.show, project_id: column.project_id, base_id: column.base_id, diff --git a/packages/nocodb/src/lib/models/View.ts b/packages/nocodb/src/lib/models/View.ts index 3e79eb0bba..1d1d1db150 100644 --- a/packages/nocodb/src/lib/models/View.ts +++ b/packages/nocodb/src/lib/models/View.ts @@ -13,7 +13,13 @@ import GalleryView from './GalleryView'; import GridViewColumn from './GridViewColumn'; import Sort from './Sort'; import Filter from './Filter'; -import { isSystemColumn, UITypes, ViewType, ViewTypes } from 'nocodb-sdk'; +import { + ColumnReqType, + isSystemColumn, + UITypes, + ViewType, + ViewTypes, +} from 'nocodb-sdk'; import GalleryViewColumn from './GalleryViewColumn'; import FormViewColumn from './FormViewColumn'; import KanbanViewColumn from './KanbanViewColumn'; @@ -442,9 +448,9 @@ export default class View implements ViewType { param: { fk_column_id: any; fk_model_id: any; - order; + order?: number; show; - }, + } & Pick, ncMeta = Noco.ncMeta ) { const insertObj = { @@ -456,33 +462,21 @@ export default class View implements ViewType { const views = await this.list(param.fk_model_id, ncMeta); for (const view of views) { + const modifiedInsertObj = { ...insertObj, fk_view_id: view.id }; + + if (param.columnOrder?.viewId === view.id) { + modifiedInsertObj.order = param.columnOrder?.order; + } + switch (view.type) { case ViewTypes.GRID: - await GridViewColumn.insert( - { - ...insertObj, - fk_view_id: view.id, - }, - ncMeta - ); + await GridViewColumn.insert(modifiedInsertObj, ncMeta); break; case ViewTypes.GALLERY: - await GalleryViewColumn.insert( - { - ...insertObj, - fk_view_id: view.id, - }, - ncMeta - ); + await GalleryViewColumn.insert(modifiedInsertObj, ncMeta); break; case ViewTypes.KANBAN: - await KanbanViewColumn.insert( - { - ...insertObj, - fk_view_id: view.id, - }, - ncMeta - ); + await KanbanViewColumn.insert(modifiedInsertObj, ncMeta); break; } } diff --git a/scripts/sdk/swagger.json b/scripts/sdk/swagger.json index 5116c33b62..8498e11f39 100644 --- a/scripts/sdk/swagger.json +++ b/scripts/sdk/swagger.json @@ -8957,213 +8957,254 @@ } } }, - "ColumnReq": { - "oneOf": [ - { - "properties": { - "uidt": { - "type": "string", - "enum": [ - "ID", - "SingleLineText", - "LongText", - "Attachment", - "Checkbox", - "MultiSelect", - "SingleSelect", - "Collaborator", - "Date", - "Year", - "Time", - "PhoneNumber", - "Email", - "URL", - "Number", - "Decimal", - "Currency", - "Percent", - "Duration", - "Rating", - "Count", - "DateTime", - "CreateTime", - "LastModifiedTime", - "AutoNumber", - "Geometry", - "JSON", - "SpecificDBType", - "Barcode", - "Button" - ] - }, - "id": { - "type": "string" - }, - "base_id": { - "type": "string" - }, - "fk_model_id": { - "type": "string" - }, - "title": { - "type": "string" - }, - "dt": { - "type": "string" - }, - "np": { - "type": "string" - }, - "ns": { - "type": "string" - }, - "clen": { - "type": [ - "string", - "integer" - ] - }, - "cop": { - "type": "string" - }, - "pk": { - "type": "boolean" - }, - "pv": { - "type": "boolean" - }, - "rqd": { - "type": "boolean" - }, - "column_name": { - "type": "string" - }, - "un": { - "type": "boolean" - }, - "ct": { - "type": "string" - }, - "ai": { - "type": "boolean" - }, - "unique": { - "type": "boolean" - }, - "cdf": { - "type": "string" - }, - "cc": { - "type": "string" - }, - "csn": { - "type": "string" - }, - "dtx": { - "type": "string" - }, - "dtxp": { - "type": "string" - }, - "dtxs": { - "type": "string" - }, - "au": { - "type": "boolean" - }, - "": { - "type": "string" - } - } + "NormalColumnRequest": { + "properties": { + "uidt": { + "type": "string", + "enum": [ + "ID", + "SingleLineText", + "LongText", + "Attachment", + "Checkbox", + "MultiSelect", + "SingleSelect", + "Collaborator", + "Date", + "Year", + "Time", + "PhoneNumber", + "Email", + "URL", + "Number", + "Decimal", + "Currency", + "Percent", + "Duration", + "Rating", + "Count", + "DateTime", + "CreateTime", + "LastModifiedTime", + "AutoNumber", + "Geometry", + "JSON", + "SpecificDBType", + "Barcode", + "Button" + ] }, - { - "properties": { - "uidt": { - "type": "string", - "enum": [ - "LinkToAnotherRecord" - ] - }, - "title": { - "type": "string" - }, - "parentId": { - "type": "string" - }, - "childId": { - "type": "string" - }, - "type": { - "type": "string", - "enum": [ - "hm", - "bt", - "mm" - ] - } - }, - "required": [ - "uidt", - "title", - "parentId", - "childId", - "type" + "id": { + "type": "string" + }, + "base_id": { + "type": "string" + }, + "fk_model_id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "dt": { + "type": "string" + }, + "np": { + "type": "string" + }, + "ns": { + "type": "string" + }, + "clen": { + "type": [ + "string", + "integer" ] }, - { - "properties": { - "uidt": { - "type": "string", - "enum": [ - "Rollup" - ] - }, - "title": { - "type": "string" - }, - "fk_relation_column_id": { - "type": "string" - }, - "fk_rollup_column_id": { - "type": "string" - }, - "rollup_function": { - "type": "string" - } - } + "cop": { + "type": "string" + }, + "pk": { + "type": "boolean" + }, + "pv": { + "type": "boolean" + }, + "rqd": { + "type": "boolean" + }, + "column_name": { + "type": "string" + }, + "un": { + "type": "boolean" + }, + "ct": { + "type": "string" + }, + "ai": { + "type": "boolean" + }, + "unique": { + "type": "boolean" + }, + "cdf": { + "type": "string" + }, + "cc": { + "type": "string" + }, + "csn": { + "type": "string" + }, + "dtx": { + "type": "string" + }, + "dtxp": { + "type": "string" + }, + "dtxs": { + "type": "string" + }, + "au": { + "type": "boolean" + } + } + }, + "LinkToAnotherColumnReq": { + "properties": { + "uidt": { + "type": "string", + "enum": [ + "LinkToAnotherRecord" + ] + }, + "title": { + "type": "string" + }, + "virtual": { + "type": "boolean" + }, + "parentId": { + "type": "string" + }, + "childId": { + "type": "string" + }, + "type": { + "type": "string", + "enum": [ + "hm", + "bt", + "mm" + ] + } + }, + "required": [ + "uidt", + "title", + "parentId", + "childId", + "type" + ] + }, + "RollupColumnReq": { + "properties": { + "uidt": { + "type": "string", + "enum": [ + "Rollup" + ] + }, + "title": { + "type": "string" + }, + "fk_relation_column_id": { + "type": "string" + }, + "fk_rollup_column_id": { + "type": "string" }, + "rollup_function": { + "type": "string" + } + } + }, + "LookupColumnReq": { + "properties": { + "uidt": { + "type": "string", + "enum": [ + "Lookup" + ] + }, + "title": { + "type": "string" + }, + "fk_relation_column_id": { + "type": "string" + }, + "fk_lookup_column_id": { + "type": "string" + } + } + }, + "FormulaColumnReq": { + "properties": { + "uidt": { + "type": "string" + }, + "formula_raw": { + "type": "string" + }, + "formula": { + "type": "string" + }, + "title": { + "type": "string" + } + } + }, + "ColumnReq": { + "allOf": [ { - "properties": { - "uidt": { - "type": "string", - "enum": [ - "Lookup" - ] + "oneOf": [ + { + "$ref": "#/components/schemas/NormalColumnRequest" }, - "title": { - "type": "string" + { + "$ref": "#/components/schemas/LinkToAnotherColumnReq" }, - "fk_relation_column_id": { - "type": "string" + { + "$ref": "#/components/schemas/RollupColumnReq" }, - "fk_lookup_column_id": { - "type": "string" + { + "$ref": "#/components/schemas/FormulaColumnReq" + }, + { + "$ref": "#/components/schemas/LookupColumnReq" } - } + ] }, { + "type": "object", "properties": { - "uidt": { - "type": "string" - }, - "formula_raw": { - "type": "string" - }, - "formula": { + "column_name": { "type": "string" }, "title": { "type": "string" + }, + "columnOrder": { + "type": "object", + "properties": { + "viewId": { + "type": "string" + }, + "order": { + "type": "integer" + } + } } } }