From 423ff2265b015108d2b2f5afda1925716e4262b1 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Thu, 8 Jun 2023 11:45:45 +0530 Subject: [PATCH 001/208] feat: when connecting external db populate rollup for LTAR and hide LTAR by default Signed-off-by: Pranav C --- packages/nocodb/src/helpers/populateMeta.ts | 48 +++++++++++++++++++ packages/nocodb/src/services/bases.service.ts | 3 ++ .../nocodb/src/services/projects.service.ts | 3 ++ 3 files changed, 54 insertions(+) diff --git a/packages/nocodb/src/helpers/populateMeta.ts b/packages/nocodb/src/helpers/populateMeta.ts index 39ca7d1d2b..9e90114430 100644 --- a/packages/nocodb/src/helpers/populateMeta.ts +++ b/packages/nocodb/src/helpers/populateMeta.ts @@ -1,5 +1,6 @@ import { ModelTypes, UITypes, ViewTypes } from 'nocodb-sdk'; import { isVirtualCol, RelationTypes } from 'nocodb-sdk'; +import { GridViewColumn } from '../models'; import Column from '../models/Column'; import Model from '../models/Model'; import NcConnectionMgrv2 from '../utils/common/NcConnectionMgrv2'; @@ -9,6 +10,7 @@ import getTableNameAlias, { getColumnNameAlias } from '../helpers/getTableName'; import getColumnUiType from '../helpers/getColumnUiType'; import mapDefaultDisplayValue from '../helpers/mapDefaultDisplayValue'; import { getUniqueColumnAliasName } from './getUniqueName'; +import type { RollupColumn } from '../models'; import type LinkToAnotherRecordColumn from '../models/LinkToAnotherRecordColumn'; import type Base from '../models/Base'; import type Project from '../models/Project'; @@ -435,3 +437,49 @@ export async function populateMeta(base: Base, project: Project): Promise { return info; } + +export async function populateRollupColumnAndHideLTAR( + base: Base, + project: Project, +) { + for (const model of await Model.list({ + project_id: project.id, + base_id: base.id, + })) { + const columns = await model.getColumns(); + const hmAndMmLTARColumns = columns.filter( + (c) => + c.uidt === UITypes.LinkToAnotherRecord && + c.colOptions.type !== RelationTypes.BELONGS_TO && + !c.system, + ); + + const views = await model.getViews(); + + for (const column of hmAndMmLTARColumns) { + const relatedModel = await column + .getColOptions() + .then((colOpt) => colOpt.getRelatedTable()); + await relatedModel.getColumns(); + const pkId = + relatedModel.primaryKey?.id || (await relatedModel.getColumns())[0]?.id; + + await Column.insert({ + uidt: 'Rollup', + title: getUniqueColumnAliasName( + await model.getColumns(), + `${relatedModel.title} Count`, + ), + fk_rollup_column_id: pkId, + fk_model_id: model.id, + rollup_function: 'count', + fk_relation_column_id: column.id, + }); + + const viewCol = await GridViewColumn.list(views[0].id).then((cols) => + cols.find((c) => c.fk_column_id === column.id), + ); + await GridViewColumn.update(viewCol.id, { show: false }); + } + } +} diff --git a/packages/nocodb/src/services/bases.service.ts b/packages/nocodb/src/services/bases.service.ts index 48bd9e6130..f68b6c01ee 100644 --- a/packages/nocodb/src/services/bases.service.ts +++ b/packages/nocodb/src/services/bases.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { T } from 'nc-help'; import { populateMeta, validatePayload } from '../helpers'; +import { populateRollupColumnAndHideLTAR } from '../helpers/populateMeta' import { syncBaseMigration } from '../helpers/syncMigration'; import { Base, Project } from '../models'; import type { BaseReqType } from 'nocodb-sdk'; @@ -69,6 +70,8 @@ export class BasesService { const info = await populateMeta(base, project); + await populateRollupColumnAndHideLTAR(base, project); + T.emit('evt_api_created', info); delete base.config; diff --git a/packages/nocodb/src/services/projects.service.ts b/packages/nocodb/src/services/projects.service.ts index eb93634a4f..f5ace226c6 100644 --- a/packages/nocodb/src/services/projects.service.ts +++ b/packages/nocodb/src/services/projects.service.ts @@ -7,6 +7,7 @@ import { OrgUserRoles } from 'nocodb-sdk'; import { populateMeta, validatePayload } from '../helpers'; import { NcError } from '../helpers/catchError'; import { extractPropsAndSanitize } from '../helpers/extractProps'; +import { populateRollupColumnAndHideLTAR } from '../helpers/populateMeta' import syncMigration from '../helpers/syncMigration'; import { Project, ProjectUser } from '../models'; import Noco from '../Noco'; @@ -167,6 +168,8 @@ export class ProjectsService { for (const base of await project.getBases()) { const info = await populateMeta(base, project); + await populateRollupColumnAndHideLTAR(base, project); + T.emit('evt_api_created', info); delete base.config; } From b4727b5a18bde810758b320d338f4436f736c8cd Mon Sep 17 00:00:00 2001 From: Pranav C Date: Thu, 8 Jun 2023 14:49:00 +0530 Subject: [PATCH 002/208] feat: on column LTAR creation - hide LTAR and add rollup(MM and HM) Signed-off-by: Pranav C --- packages/nocodb/src/helpers/columnHelpers.ts | 40 ++++++++++++++++++- .../nocodb/src/services/columns.service.ts | 23 ++++++++--- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/packages/nocodb/src/helpers/columnHelpers.ts b/packages/nocodb/src/helpers/columnHelpers.ts index 99c46ee305..c606b973dd 100644 --- a/packages/nocodb/src/helpers/columnHelpers.ts +++ b/packages/nocodb/src/helpers/columnHelpers.ts @@ -1,5 +1,6 @@ import { customAlphabet } from 'nanoid'; import { UITypes } from 'nocodb-sdk'; +import { GridViewColumn, RollupColumn } from '../models' import Column from '../models/Column'; import { getUniqueColumnAliasName } from '../helpers/getUniqueName'; import validateParams from '../helpers/validateParams'; @@ -61,7 +62,7 @@ export async function createHmAndBtColumn( await parent.getColumns(), type === 'hm' ? alias : `${child.title} List`, ); - await Column.insert({ + const col = await Column.insert({ title, fk_model_id: parent.id, uidt: UITypes.LinkToAnotherRecord, @@ -74,6 +75,11 @@ export async function createHmAndBtColumn( fk_col_name: fkColName, fk_index_name: fkColName, }); + + if (!isSystemCol) + await populateRollupForLTAR({ + column: col, + }); } } @@ -206,3 +212,35 @@ export const generateFkName = (parent: TableType, child: TableType) => { .slice(0, 10)}_${randomID(15)}`; return constraintName; }; + + + +export async function populateRollupForLTAR({ column }: { column: Column }) { + const model = await column.getModel(); + + const views = await model.getViews(); + + const relatedModel = await column + .getColOptions() + .then((colOpt) => colOpt.getRelatedTable()); + await relatedModel.getColumns(); + const pkId = + relatedModel.primaryKey?.id || (await relatedModel.getColumns())[0]?.id; + + await Column.insert({ + uidt: 'Rollup', + title: getUniqueColumnAliasName( + await model.getColumns(), + `${relatedModel.title} Count`, + ), + fk_rollup_column_id: pkId, + fk_model_id: model.id, + rollup_function: 'count', + fk_relation_column_id: column.id, + }); + + const viewCol = await GridViewColumn.list(views[0].id).then((cols) => + cols.find((c) => c.fk_column_id === column.id), + ); + await GridViewColumn.update(viewCol.id, { show: false }); +} diff --git a/packages/nocodb/src/services/columns.service.ts b/packages/nocodb/src/services/columns.service.ts index 3c73a88770..487c4adae1 100644 --- a/packages/nocodb/src/services/columns.service.ts +++ b/packages/nocodb/src/services/columns.service.ts @@ -12,13 +12,13 @@ import formulaQueryBuilderv2 from '../db/formulav2/formulaQueryBuilderv2'; import ProjectMgrv2 from '../db/sql-mgr/v2/ProjectMgrv2'; import { createHmAndBtColumn, - generateFkName, + generateFkName, populateRollupForLTAR, randomID, validateLookupPayload, validatePayload, validateRequiredField, validateRollupPayload, -} from '../helpers'; +} from '../helpers' import { NcError } from '../helpers/catchError'; import getColumnPropsFromUIDT from '../helpers/getColumnPropsFromUIDT'; import { @@ -32,6 +32,7 @@ import { Base, Column, FormulaColumn, + GridViewColumn, KanbanView, Model, } from '../models'; @@ -39,7 +40,11 @@ import Noco from '../Noco'; import NcConnectionMgrv2 from '../utils/common/NcConnectionMgrv2'; import { MetaTable } from '../utils/globals'; import { MetaService } from '../meta/meta.service'; -import type { LinkToAnotherRecordColumn, Project } from '../models'; +import type { + LinkToAnotherRecordColumn, + Project, + RollupColumn, +} from '../models'; import type SqlMgrv2 from '../db/sql-mgr/v2/SqlMgrv2'; import type { ColumnReqType, @@ -1759,7 +1764,7 @@ export class ColumnsService { true, ); - await Column.insert({ + const col1 = await Column.insert({ title: getUniqueColumnAliasName( await child.getColumns(), `${parent.title} List`, @@ -1780,7 +1785,7 @@ export class ColumnsService { fk_related_model_id: parent.id, virtual: (param.column as LinkToAnotherColumnReqType).virtual, }); - await Column.insert({ + const col2 = await Column.insert({ title: getUniqueColumnAliasName( await parent.getColumns(), param.column.title ?? `${child.title} List`, @@ -1801,6 +1806,13 @@ export class ColumnsService { virtual: (param.column as LinkToAnotherColumnReqType).virtual, }); + await populateRollupForLTAR({ + column: col1, + }) + await populateRollupForLTAR({ + column: col2, + }) + // todo: create index for virtual relations as well // create index for foreign key in pg if (param.base.type === 'pg') { @@ -1869,4 +1881,5 @@ export class ColumnsService { await Column.update(column.id, colBody); } } + } From 694c97693e4407c09c2a5139cd69421cc6605166 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Thu, 8 Jun 2023 22:42:07 +0530 Subject: [PATCH 003/208] feat: Link type column ( WIP ) Signed-off-by: Pranav C --- .../components/smartsheet/VirtualCell.vue | 2 + .../smartsheet/column/EditOrAdd.vue | 2 +- .../nc-gui/components/virtual-cell/Link.vue | 75 +++++++++++++++++++ packages/nc-gui/utils/virtualCell.ts | 1 + packages/nocodb-sdk/src/lib/Api.ts | 8 +- packages/nocodb-sdk/src/lib/UITypes.ts | 2 + packages/nocodb/src/db/BaseModelSqlv2.ts | 13 ++-- packages/nocodb/src/helpers/columnHelpers.ts | 2 +- packages/nocodb/src/models/Column.ts | 2 + packages/nocodb/src/schema/swagger.json | 8 +- .../nocodb/src/services/columns.service.ts | 11 ++- 11 files changed, 106 insertions(+), 20 deletions(-) create mode 100644 packages/nc-gui/components/virtual-cell/Link.vue diff --git a/packages/nc-gui/components/smartsheet/VirtualCell.vue b/packages/nc-gui/components/smartsheet/VirtualCell.vue index 26d820b37c..b6e535cd41 100644 --- a/packages/nc-gui/components/smartsheet/VirtualCell.vue +++ b/packages/nc-gui/components/smartsheet/VirtualCell.vue @@ -18,6 +18,7 @@ import { isMm, isQrCode, isRollup, + isLink, provide, toRef, } from '#imports' @@ -99,6 +100,7 @@ onUnmounted(() => { + diff --git a/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue b/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue index cce3f4b78c..8facb75ec0 100644 --- a/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue +++ b/packages/nc-gui/components/smartsheet/column/EditOrAdd.vue @@ -209,7 +209,7 @@ useEventListener('keydown', (e: KeyboardEvent) => { diff --git a/packages/nc-gui/components/virtual-cell/Link.vue b/packages/nc-gui/components/virtual-cell/Link.vue new file mode 100644 index 0000000000..1077a67c9a --- /dev/null +++ b/packages/nc-gui/components/virtual-cell/Link.vue @@ -0,0 +1,75 @@ + + + diff --git a/packages/nc-gui/utils/virtualCell.ts b/packages/nc-gui/utils/virtualCell.ts index 9338df7834..b761006f2a 100644 --- a/packages/nc-gui/utils/virtualCell.ts +++ b/packages/nc-gui/utils/virtualCell.ts @@ -19,3 +19,4 @@ export const isFormula = (column: ColumnType) => column.uidt === UITypes.Formula export const isQrCode = (column: ColumnType) => column.uidt === UITypes.QrCode export const isBarcode = (column: ColumnType) => column.uidt === UITypes.Barcode export const isCount = (column: ColumnType) => column.uidt === UITypes.Count +export const isLink = (column: ColumnType) => column.uidt === UITypes.Link diff --git a/packages/nocodb-sdk/src/lib/Api.ts b/packages/nocodb-sdk/src/lib/Api.ts index 122abbfcf9..f0a6f9a05c 100644 --- a/packages/nocodb-sdk/src/lib/Api.ts +++ b/packages/nocodb-sdk/src/lib/Api.ts @@ -433,7 +433,8 @@ export interface ColumnType { | 'Time' | 'URL' | 'Year' - | 'QrCode'; + | 'QrCode' + | 'Link'; /** Is Unsigned? */ un?: BoolType; /** Is unique? */ @@ -1468,7 +1469,7 @@ export interface LinkToAnotherColumnReqType { /** The type of the relationship */ type: 'bt' | 'hm' | 'mm'; /** Abstract type of the relationship */ - uidt: 'LinkToAnotherRecord'; + uidt: 'LinkToAnotherRecord' | 'Link'; /** Is this relationship virtual? */ virtual?: BoolType; } @@ -1720,7 +1721,8 @@ export interface NormalColumnRequestType { | 'Time' | 'URL' | 'Year' - | 'QrCode'; + | 'QrCode' + | 'Link'; /** Is this column unique? */ un?: BoolType; /** Is this column unique? */ diff --git a/packages/nocodb-sdk/src/lib/UITypes.ts b/packages/nocodb-sdk/src/lib/UITypes.ts index ce9059c7a9..62b0b4dfaa 100644 --- a/packages/nocodb-sdk/src/lib/UITypes.ts +++ b/packages/nocodb-sdk/src/lib/UITypes.ts @@ -38,6 +38,7 @@ enum UITypes { Barcode = 'Barcode', QrCode = 'QrCode', Button = 'Button', + Link = 'Link', } export const numericUITypes = [ @@ -79,6 +80,7 @@ export function isVirtualCol( UITypes.Barcode, UITypes.Rollup, UITypes.Lookup, + UITypes.Link, // UITypes.Count, ].includes((typeof col === 'object' ? col?.uidt : col)); } diff --git a/packages/nocodb/src/db/BaseModelSqlv2.ts b/packages/nocodb/src/db/BaseModelSqlv2.ts index b15aa4b355..bc47c46ac9 100644 --- a/packages/nocodb/src/db/BaseModelSqlv2.ts +++ b/packages/nocodb/src/db/BaseModelSqlv2.ts @@ -1677,10 +1677,10 @@ class BaseModelSqlv2 { `${alias || this.model.table_name}.${column.column_name}`, ); break; - case 'LinkToAnotherRecord': - case 'Lookup': + case UITypes.LinkToAnotherRecord: + case UITypes.Lookup: break; - case 'QrCode': { + case UITypes.QrCode: { const qrCodeColumn = await column.getColOptions(); const qrValueColumn = await Column.get({ colId: qrCodeColumn.fk_qr_value_column_id, @@ -1715,7 +1715,7 @@ class BaseModelSqlv2 { break; } - case 'Barcode': { + case UITypes.Barcode: { const barcodeColumn = await column.getColOptions(); const barcodeValueColumn = await Column.get({ colId: barcodeColumn.fk_barcode_value_column_id, @@ -1752,7 +1752,7 @@ class BaseModelSqlv2 { break; } - case 'Formula': + case UITypes.Formula: { try { const selectQb = await this.getSelectQueryBuilderForFormula( @@ -1776,7 +1776,8 @@ class BaseModelSqlv2 { } } break; - case 'Rollup': + case UITypes.Rollup: + case UITypes.Link: qb.select( ( await genRollupSelectv2({ diff --git a/packages/nocodb/src/helpers/columnHelpers.ts b/packages/nocodb/src/helpers/columnHelpers.ts index c606b973dd..d8b4e59c1e 100644 --- a/packages/nocodb/src/helpers/columnHelpers.ts +++ b/packages/nocodb/src/helpers/columnHelpers.ts @@ -228,7 +228,7 @@ export async function populateRollupForLTAR({ column }: { column: Column }) { relatedModel.primaryKey?.id || (await relatedModel.getColumns())[0]?.id; await Column.insert({ - uidt: 'Rollup', + uidt: UITypes.Link, title: getUniqueColumnAliasName( await model.getColumns(), `${relatedModel.title} Count`, diff --git a/packages/nocodb/src/models/Column.ts b/packages/nocodb/src/models/Column.ts index 78ae4edc9f..06f26e8696 100644 --- a/packages/nocodb/src/models/Column.ts +++ b/packages/nocodb/src/models/Column.ts @@ -193,6 +193,7 @@ export default class Column implements ColumnType { ); break; } + case UITypes.Link: case UITypes.Rollup: { await RollupColumn.insert( { @@ -417,6 +418,7 @@ export default class Column implements ColumnType { res = await LookupColumn.read(this.id, ncMeta); break; case UITypes.Rollup: + case UITypes.Link: res = await RollupColumn.read(this.id, ncMeta); break; case UITypes.LinkToAnotherRecord: diff --git a/packages/nocodb/src/schema/swagger.json b/packages/nocodb/src/schema/swagger.json index 84d509f0ef..6d3f7916cd 100644 --- a/packages/nocodb/src/schema/swagger.json +++ b/packages/nocodb/src/schema/swagger.json @@ -14887,7 +14887,8 @@ "Time", "URL", "Year", - "QrCode" + "QrCode", + "Link" ], "type": "string" }, @@ -17424,7 +17425,7 @@ "description": "The type of the relationship" }, "uidt": { - "enum": ["LinkToAnotherRecord"], + "enum": ["LinkToAnotherRecord", "Link"], "type": "string", "description": "Abstract type of the relationship" }, @@ -17974,7 +17975,8 @@ "Time", "URL", "Year", - "QrCode" + "QrCode", + "Link" ], "type": "string", "description": "UI Data Type" diff --git a/packages/nocodb/src/services/columns.service.ts b/packages/nocodb/src/services/columns.service.ts index 487c4adae1..ad611e556e 100644 --- a/packages/nocodb/src/services/columns.service.ts +++ b/packages/nocodb/src/services/columns.service.ts @@ -12,13 +12,14 @@ import formulaQueryBuilderv2 from '../db/formulav2/formulaQueryBuilderv2'; import ProjectMgrv2 from '../db/sql-mgr/v2/ProjectMgrv2'; import { createHmAndBtColumn, - generateFkName, populateRollupForLTAR, + generateFkName, + populateRollupForLTAR, randomID, validateLookupPayload, validatePayload, validateRequiredField, validateRollupPayload, -} from '../helpers' +} from '../helpers'; import { NcError } from '../helpers/catchError'; import getColumnPropsFromUIDT from '../helpers/getColumnPropsFromUIDT'; import { @@ -43,7 +44,6 @@ import { MetaService } from '../meta/meta.service'; import type { LinkToAnotherRecordColumn, Project, - RollupColumn, } from '../models'; import type SqlMgrv2 from '../db/sql-mgr/v2/SqlMgrv2'; import type { @@ -1808,10 +1808,10 @@ export class ColumnsService { await populateRollupForLTAR({ column: col1, - }) + }); await populateRollupForLTAR({ column: col2, - }) + }); // todo: create index for virtual relations as well // create index for foreign key in pg @@ -1881,5 +1881,4 @@ export class ColumnsService { await Column.update(column.id, colBody); } } - } From 0bd165b67e4db73e064460b61c7c09e38d86f236 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Fri, 9 Jun 2023 15:39:16 +0530 Subject: [PATCH 004/208] feat: make Links column similar to LTAR Signed-off-by: Pranav C --- .../nc-gui/components/virtual-cell/Link.vue | 79 +++++++++++++------ packages/nc-gui/package-lock.json | 14 ++++ packages/nc-gui/package.json | 1 + 3 files changed, 68 insertions(+), 26 deletions(-) diff --git a/packages/nc-gui/components/virtual-cell/Link.vue b/packages/nc-gui/components/virtual-cell/Link.vue index 1077a67c9a..d50509ec39 100644 --- a/packages/nc-gui/components/virtual-cell/Link.vue +++ b/packages/nc-gui/components/virtual-cell/Link.vue @@ -1,22 +1,20 @@ -