Browse Source

feat: Link type column ( WIP )

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/5848/head
Pranav C 1 year ago
parent
commit
694c97693e
  1. 2
      packages/nc-gui/components/smartsheet/VirtualCell.vue
  2. 2
      packages/nc-gui/components/smartsheet/column/EditOrAdd.vue
  3. 75
      packages/nc-gui/components/virtual-cell/Link.vue
  4. 1
      packages/nc-gui/utils/virtualCell.ts
  5. 8
      packages/nocodb-sdk/src/lib/Api.ts
  6. 2
      packages/nocodb-sdk/src/lib/UITypes.ts
  7. 13
      packages/nocodb/src/db/BaseModelSqlv2.ts
  8. 2
      packages/nocodb/src/helpers/columnHelpers.ts
  9. 2
      packages/nocodb/src/models/Column.ts
  10. 8
      packages/nocodb/src/schema/swagger.json
  11. 11
      packages/nocodb/src/services/columns.service.ts

2
packages/nc-gui/components/smartsheet/VirtualCell.vue

@ -18,6 +18,7 @@ import {
isMm, isMm,
isQrCode, isQrCode,
isRollup, isRollup,
isLink,
provide, provide,
toRef, toRef,
} from '#imports' } from '#imports'
@ -99,6 +100,7 @@ onUnmounted(() => {
<LazyVirtualCellManyToMany v-else-if="isMm(column)" /> <LazyVirtualCellManyToMany v-else-if="isMm(column)" />
<LazyVirtualCellBelongsTo v-else-if="isBt(column)" /> <LazyVirtualCellBelongsTo v-else-if="isBt(column)" />
<LazyVirtualCellRollup v-else-if="isRollup(column)" /> <LazyVirtualCellRollup v-else-if="isRollup(column)" />
<LazyVirtualCellLink v-else-if="isLink(column)" />
<LazyVirtualCellFormula v-else-if="isFormula(column)" /> <LazyVirtualCellFormula v-else-if="isFormula(column)" />
<LazyVirtualCellQrCode v-else-if="isQrCode(column)" /> <LazyVirtualCellQrCode v-else-if="isQrCode(column)" />
<LazyVirtualCellBarcode v-else-if="isBarcode(column)" /> <LazyVirtualCellBarcode v-else-if="isBarcode(column)" />

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

@ -209,7 +209,7 @@ useEventListener('keydown', (e: KeyboardEvent) => {
<LazySmartsheetColumnDateTimeOptions v-if="formState.uidt === UITypes.DateTime" v-model:value="formState" /> <LazySmartsheetColumnDateTimeOptions v-if="formState.uidt === UITypes.DateTime" v-model:value="formState" />
<LazySmartsheetColumnRollupOptions v-if="formState.uidt === UITypes.Rollup" v-model:value="formState" /> <LazySmartsheetColumnRollupOptions v-if="formState.uidt === UITypes.Rollup" v-model:value="formState" />
<LazySmartsheetColumnLinkedToAnotherRecordOptions <LazySmartsheetColumnLinkedToAnotherRecordOptions
v-if="!isEdit && formState.uidt === UITypes.LinkToAnotherRecord" v-if="!isEdit && (formState.uidt === UITypes.LinkToAnotherRecord || formState.uidt === UITypes.Link)"
v-model:value="formState" v-model:value="formState"
/> />
<LazySmartsheetColumnSpecificDBTypeOptions v-if="formState.uidt === UITypes.SpecificDBType" /> <LazySmartsheetColumnSpecificDBTypeOptions v-if="formState.uidt === UITypes.SpecificDBType" />

75
packages/nc-gui/components/virtual-cell/Link.vue

@ -0,0 +1,75 @@
<script setup lang="ts">
import { CellValueInj, inject, useShowNotEditableWarning } from '#imports'
import { Ref } from 'vue'
const value = inject(CellValueInj)
const column = inject(ColumnInj)!
const relColumn = computed(() => {
return column.value?.related_column
}
const cellValue = inject(CellValueInj)!
const row = inject(RowInj)!
const reloadRowTrigger = inject(ReloadRowDataHookInj, createEventHook())
const isForm = inject(IsFormInj)
const readOnly = inject(ReadonlyInj, ref(false))
const isLocked = inject(IsLockedInj)
const isUnderLookup = inject(IsUnderLookupInj, ref(false))
const listItemsDlg = ref(false)
const childListDlg = ref(false)
const { isUIAllowed } = useUIPermission()
const { state, isNew, removeLTARRef } = useSmartsheetRowStoreOrThrow()
const { relatedTableMeta, loadRelatedTableMeta, relatedTableDisplayValueProp, unlink } = useProvideLTARStore(
column as Ref<Required<ColumnType>>,
row,
isNew,
reloadRowTrigger.trigger,
)
</script>
<template>
<div>
<span class="text-center pl-3">
{{ value }}
</span>
<LazyVirtualCellComponentsListItems v-model="listItemsDlg" :column="relColumn" />
<LazyVirtualCellComponentsListChildItems
v-model="childListDlg"
:cell-value="localCellValue"
:column="relColumn"
@attach-record="onAttachRecord"
/>
</div>
</template>

1
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 isQrCode = (column: ColumnType) => column.uidt === UITypes.QrCode
export const isBarcode = (column: ColumnType) => column.uidt === UITypes.Barcode export const isBarcode = (column: ColumnType) => column.uidt === UITypes.Barcode
export const isCount = (column: ColumnType) => column.uidt === UITypes.Count export const isCount = (column: ColumnType) => column.uidt === UITypes.Count
export const isLink = (column: ColumnType) => column.uidt === UITypes.Link

8
packages/nocodb-sdk/src/lib/Api.ts

@ -433,7 +433,8 @@ export interface ColumnType {
| 'Time' | 'Time'
| 'URL' | 'URL'
| 'Year' | 'Year'
| 'QrCode'; | 'QrCode'
| 'Link';
/** Is Unsigned? */ /** Is Unsigned? */
un?: BoolType; un?: BoolType;
/** Is unique? */ /** Is unique? */
@ -1468,7 +1469,7 @@ export interface LinkToAnotherColumnReqType {
/** The type of the relationship */ /** The type of the relationship */
type: 'bt' | 'hm' | 'mm'; type: 'bt' | 'hm' | 'mm';
/** Abstract type of the relationship */ /** Abstract type of the relationship */
uidt: 'LinkToAnotherRecord'; uidt: 'LinkToAnotherRecord' | 'Link';
/** Is this relationship virtual? */ /** Is this relationship virtual? */
virtual?: BoolType; virtual?: BoolType;
} }
@ -1720,7 +1721,8 @@ export interface NormalColumnRequestType {
| 'Time' | 'Time'
| 'URL' | 'URL'
| 'Year' | 'Year'
| 'QrCode'; | 'QrCode'
| 'Link';
/** Is this column unique? */ /** Is this column unique? */
un?: BoolType; un?: BoolType;
/** Is this column unique? */ /** Is this column unique? */

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

@ -38,6 +38,7 @@ enum UITypes {
Barcode = 'Barcode', Barcode = 'Barcode',
QrCode = 'QrCode', QrCode = 'QrCode',
Button = 'Button', Button = 'Button',
Link = 'Link',
} }
export const numericUITypes = [ export const numericUITypes = [
@ -79,6 +80,7 @@ export function isVirtualCol(
UITypes.Barcode, UITypes.Barcode,
UITypes.Rollup, UITypes.Rollup,
UITypes.Lookup, UITypes.Lookup,
UITypes.Link,
// UITypes.Count, // UITypes.Count,
].includes(<UITypes>(typeof col === 'object' ? col?.uidt : col)); ].includes(<UITypes>(typeof col === 'object' ? col?.uidt : col));
} }

13
packages/nocodb/src/db/BaseModelSqlv2.ts

@ -1677,10 +1677,10 @@ class BaseModelSqlv2 {
`${alias || this.model.table_name}.${column.column_name}`, `${alias || this.model.table_name}.${column.column_name}`,
); );
break; break;
case 'LinkToAnotherRecord': case UITypes.LinkToAnotherRecord:
case 'Lookup': case UITypes.Lookup:
break; break;
case 'QrCode': { case UITypes.QrCode: {
const qrCodeColumn = await column.getColOptions<QrCodeColumn>(); const qrCodeColumn = await column.getColOptions<QrCodeColumn>();
const qrValueColumn = await Column.get({ const qrValueColumn = await Column.get({
colId: qrCodeColumn.fk_qr_value_column_id, colId: qrCodeColumn.fk_qr_value_column_id,
@ -1715,7 +1715,7 @@ class BaseModelSqlv2 {
break; break;
} }
case 'Barcode': { case UITypes.Barcode: {
const barcodeColumn = await column.getColOptions<BarcodeColumn>(); const barcodeColumn = await column.getColOptions<BarcodeColumn>();
const barcodeValueColumn = await Column.get({ const barcodeValueColumn = await Column.get({
colId: barcodeColumn.fk_barcode_value_column_id, colId: barcodeColumn.fk_barcode_value_column_id,
@ -1752,7 +1752,7 @@ class BaseModelSqlv2 {
break; break;
} }
case 'Formula': case UITypes.Formula:
{ {
try { try {
const selectQb = await this.getSelectQueryBuilderForFormula( const selectQb = await this.getSelectQueryBuilderForFormula(
@ -1776,7 +1776,8 @@ class BaseModelSqlv2 {
} }
} }
break; break;
case 'Rollup': case UITypes.Rollup:
case UITypes.Link:
qb.select( qb.select(
( (
await genRollupSelectv2({ await genRollupSelectv2({

2
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; relatedModel.primaryKey?.id || (await relatedModel.getColumns())[0]?.id;
await Column.insert<RollupColumn>({ await Column.insert<RollupColumn>({
uidt: 'Rollup', uidt: UITypes.Link,
title: getUniqueColumnAliasName( title: getUniqueColumnAliasName(
await model.getColumns(), await model.getColumns(),
`${relatedModel.title} Count`, `${relatedModel.title} Count`,

2
packages/nocodb/src/models/Column.ts

@ -193,6 +193,7 @@ export default class Column<T = any> implements ColumnType {
); );
break; break;
} }
case UITypes.Link:
case UITypes.Rollup: { case UITypes.Rollup: {
await RollupColumn.insert( await RollupColumn.insert(
{ {
@ -417,6 +418,7 @@ export default class Column<T = any> implements ColumnType {
res = await LookupColumn.read(this.id, ncMeta); res = await LookupColumn.read(this.id, ncMeta);
break; break;
case UITypes.Rollup: case UITypes.Rollup:
case UITypes.Link:
res = await RollupColumn.read(this.id, ncMeta); res = await RollupColumn.read(this.id, ncMeta);
break; break;
case UITypes.LinkToAnotherRecord: case UITypes.LinkToAnotherRecord:

8
packages/nocodb/src/schema/swagger.json

@ -14887,7 +14887,8 @@
"Time", "Time",
"URL", "URL",
"Year", "Year",
"QrCode" "QrCode",
"Link"
], ],
"type": "string" "type": "string"
}, },
@ -17424,7 +17425,7 @@
"description": "The type of the relationship" "description": "The type of the relationship"
}, },
"uidt": { "uidt": {
"enum": ["LinkToAnotherRecord"], "enum": ["LinkToAnotherRecord", "Link"],
"type": "string", "type": "string",
"description": "Abstract type of the relationship" "description": "Abstract type of the relationship"
}, },
@ -17974,7 +17975,8 @@
"Time", "Time",
"URL", "URL",
"Year", "Year",
"QrCode" "QrCode",
"Link"
], ],
"type": "string", "type": "string",
"description": "UI Data Type" "description": "UI Data Type"

11
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 ProjectMgrv2 from '../db/sql-mgr/v2/ProjectMgrv2';
import { import {
createHmAndBtColumn, createHmAndBtColumn,
generateFkName, populateRollupForLTAR, generateFkName,
populateRollupForLTAR,
randomID, randomID,
validateLookupPayload, validateLookupPayload,
validatePayload, validatePayload,
validateRequiredField, validateRequiredField,
validateRollupPayload, validateRollupPayload,
} from '../helpers' } from '../helpers';
import { NcError } from '../helpers/catchError'; import { NcError } from '../helpers/catchError';
import getColumnPropsFromUIDT from '../helpers/getColumnPropsFromUIDT'; import getColumnPropsFromUIDT from '../helpers/getColumnPropsFromUIDT';
import { import {
@ -43,7 +44,6 @@ import { MetaService } from '../meta/meta.service';
import type { import type {
LinkToAnotherRecordColumn, LinkToAnotherRecordColumn,
Project, Project,
RollupColumn,
} from '../models'; } from '../models';
import type SqlMgrv2 from '../db/sql-mgr/v2/SqlMgrv2'; import type SqlMgrv2 from '../db/sql-mgr/v2/SqlMgrv2';
import type { import type {
@ -1808,10 +1808,10 @@ export class ColumnsService {
await populateRollupForLTAR({ await populateRollupForLTAR({
column: col1, column: col1,
}) });
await populateRollupForLTAR({ await populateRollupForLTAR({
column: col2, column: col2,
}) });
// todo: create index for virtual relations as well // todo: create index for virtual relations as well
// create index for foreign key in pg // create index for foreign key in pg
@ -1881,5 +1881,4 @@ export class ColumnsService {
await Column.update(column.id, colBody); await Column.update(column.id, colBody);
} }
} }
} }

Loading…
Cancel
Save