diff --git a/packages/nc-gui/components/smartsheet/Gallery.vue b/packages/nc-gui/components/smartsheet/Gallery.vue index f4f4a160f4..5b0a2f5088 100644 --- a/packages/nc-gui/components/smartsheet/Gallery.vue +++ b/packages/nc-gui/components/smartsheet/Gallery.vue @@ -7,6 +7,7 @@ import { IsFormInj, IsGalleryInj, IsGridInj, + IsPublicInj, MetaInj, NavigateDir, OpenNewRecordFormHookInj, @@ -62,6 +63,8 @@ provide(IsGridInj, ref(false)) provide(PaginationDataInj, paginationData) provide(ChangePageInj, changePage) +const isPublic = inject(IsPublicInj, ref(false)) + const fields = inject(FieldsInj, ref([])) const route = useRoute() @@ -125,6 +128,10 @@ const attachments = (record: any): Attachment[] => { } const expandForm = (row: RowType, state?: Record) => { + if (isPublic.value) { + return + } + const rowId = extractPkFromRow(row.row, meta.value!.columns!) if (rowId) { @@ -234,6 +241,7 @@ watch(view, async (nextView) => { :data-testid="`nc-gallery-card-${record.row.id}`" @click="expandFormClick($event, record)" @contextmenu="showContextMenu($event, { row: rowIndex })" + :style="isPublic ? { cursor: 'default' } : { cursor: 'pointer' }" > -
+
) { .catch(async (error) => { await state.signOut() - // todo: handle new user - navigateTo('/signIn') + if (!route.meta.public) navigateTo('/signIn') return Promise.reject(error) }) diff --git a/packages/nc-gui/composables/useMultiSelect/convertCellData.ts b/packages/nc-gui/composables/useMultiSelect/convertCellData.ts index 47eb6e8155..a6bb90685a 100644 --- a/packages/nc-gui/composables/useMultiSelect/convertCellData.ts +++ b/packages/nc-gui/composables/useMultiSelect/convertCellData.ts @@ -7,7 +7,6 @@ import { parseProp } from '#imports' export default function convertCellData( args: { from: UITypes; to: UITypes; value: any; column: ColumnType; appInfo: AppInfo }, isMysql = false, - isXcdbBase = false, ) { const { from, to, value } = args if (from === to && ![UITypes.Attachment, UITypes.Date, UITypes.DateTime, UITypes.Time, UITypes.Year].includes(to)) { diff --git a/packages/nc-gui/composables/useMultiSelect/index.ts b/packages/nc-gui/composables/useMultiSelect/index.ts index d217b0249d..b5d5fb4226 100644 --- a/packages/nc-gui/composables/useMultiSelect/index.ts +++ b/packages/nc-gui/composables/useMultiSelect/index.ts @@ -55,7 +55,7 @@ export function useMultiSelect( const { appInfo } = useGlobal() - const { isMysql, isXcdbBase } = useProject() + const { isMysql } = useProject() let clipboardContext = $ref<{ value: any; uidt: UITypes } | null>(null) @@ -359,7 +359,6 @@ export function useMultiSelect( appInfo: unref(appInfo), }, isMysql(meta.value?.base_id), - isXcdbBase(meta.value?.base_id), ) e.preventDefault() @@ -394,7 +393,6 @@ export function useMultiSelect( appInfo: unref(appInfo), }, isMysql(meta.value?.base_id), - isXcdbBase(meta.value?.base_id), ) e.preventDefault() syncCellData?.(activeCell) diff --git a/packages/nc-gui/context/index.ts b/packages/nc-gui/context/index.ts index 0ea07a931e..1b8e84baa0 100644 --- a/packages/nc-gui/context/index.ts +++ b/packages/nc-gui/context/index.ts @@ -38,3 +38,4 @@ export const ToggleDialogInj: InjectionKey = Symbol('toggle-dialog-inj export const CellClickHookInj: InjectionKey | undefined> = Symbol('cell-click-injection') export const SaveRowInj: InjectionKey<(() => void) | undefined> = Symbol('save-row-injection') export const CurrentCellInj: InjectionKey> = Symbol('current-cell-injection') +export const IsUnderLookupInj: InjectionKey> = Symbol('is-under-lookup-injection') diff --git a/packages/nocodb-sdk/src/lib/Api.ts b/packages/nocodb-sdk/src/lib/Api.ts index 5a3fa5ebe1..122abbfcf9 100644 --- a/packages/nocodb-sdk/src/lib/Api.ts +++ b/packages/nocodb-sdk/src/lib/Api.ts @@ -546,7 +546,39 @@ export interface FilterType { | 'notchecked' | 'notempty' | 'notnull' - | 'null'; + | 'null' + | null + | ( + | 'allof' + | 'anyof' + | 'blank' + | 'btw' + | 'checked' + | 'empty' + | 'eq' + | 'ge' + | 'gt' + | 'gte' + | 'in' + | 'is' + | 'isWithin' + | 'isnot' + | 'le' + | 'like' + | 'lt' + | 'lte' + | 'nallof' + | 'nanyof' + | 'nbtw' + | 'neq' + | 'nlike' + | 'not' + | 'notblank' + | 'notchecked' + | 'notempty' + | 'notnull' + | ('null' & null) + ); /** Comparison Sub-Operator */ comparison_sub_op?: | 'daysAgo' @@ -589,7 +621,7 @@ export interface FilterType { | ('yesterday' & null) ); /** Foreign Key to Column */ - fk_column_id?: IdType; + fk_column_id?: StringOrNullType; /** Foreign Key to Hook */ fk_hook_id?: StringOrNullType; /** Foreign Key to Model */ @@ -664,7 +696,39 @@ export interface FilterReqType { | 'notchecked' | 'notempty' | 'notnull' - | 'null'; + | 'null' + | null + | ( + | 'allof' + | 'anyof' + | 'blank' + | 'btw' + | 'checked' + | 'empty' + | 'eq' + | 'ge' + | 'gt' + | 'gte' + | 'in' + | 'is' + | 'isWithin' + | 'isnot' + | 'le' + | 'like' + | 'lt' + | 'lte' + | 'nallof' + | 'nanyof' + | 'nbtw' + | 'neq' + | 'nlike' + | 'not' + | 'notblank' + | 'notchecked' + | 'notempty' + | 'notnull' + | ('null' & null) + ); /** Comparison Sub-Operator */ comparison_sub_op?: | 'daysAgo' @@ -707,7 +771,7 @@ export interface FilterReqType { | ('yesterday' & null) ); /** Foreign Key to Column */ - fk_column_id?: IdType; + fk_column_id?: StringOrNullType; /** Belong to which filter ID */ fk_parent_id?: StringOrNullType; /** Is this filter grouped? */ diff --git a/packages/nocodb/src/schema/swagger.json b/packages/nocodb/src/schema/swagger.json index 34fae1d3d8..84d509f0ef 100644 --- a/packages/nocodb/src/schema/swagger.json +++ b/packages/nocodb/src/schema/swagger.json @@ -15197,38 +15197,45 @@ }, "comparison_op": { "description": "Comparison Operator", - "enum": [ - "allof", - "anyof", - "blank", - "btw", - "checked", - "empty", - "eq", - "ge", - "gt", - "gte", - "in", - "is", - "isWithin", - "isnot", - "le", - "like", - "lt", - "lte", - "nallof", - "nanyof", - "nbtw", - "neq", - "nlike", - "not", - "notblank", - "notchecked", - "notempty", - "notnull", - "null" - ], - "type": "string" + "anyOf": [ + { + "enum": [ + "allof", + "anyof", + "blank", + "btw", + "checked", + "empty", + "eq", + "ge", + "gt", + "gte", + "in", + "is", + "isWithin", + "isnot", + "le", + "like", + "lt", + "lte", + "nallof", + "nanyof", + "nbtw", + "neq", + "nlike", + "not", + "notblank", + "notchecked", + "notempty", + "notnull", + "null" + ], + "type": "string" + }, + { + "type": "null" + } + ] }, "comparison_sub_op": { "anyOf": [ @@ -15262,7 +15269,7 @@ "description": "Comparison Sub-Operator" }, "fk_column_id": { - "$ref": "#/components/schemas/Id", + "$ref": "#/components/schemas/StringOrNull", "description": "Foreign Key to Column" }, "fk_hook_id": { @@ -15518,38 +15525,45 @@ "properties": { "comparison_op": { "description": "Comparison Operator", - "enum": [ - "allof", - "anyof", - "blank", - "btw", - "checked", - "empty", - "eq", - "ge", - "gt", - "gte", - "in", - "is", - "isWithin", - "isnot", - "le", - "like", - "lt", - "lte", - "nallof", - "nanyof", - "nbtw", - "neq", - "nlike", - "not", - "notblank", - "notchecked", - "notempty", - "notnull", - "null" - ], - "type": "string" + "anyOf": [ + { + "enum": [ + "allof", + "anyof", + "blank", + "btw", + "checked", + "empty", + "eq", + "ge", + "gt", + "gte", + "in", + "is", + "isWithin", + "isnot", + "le", + "like", + "lt", + "lte", + "nallof", + "nanyof", + "nbtw", + "neq", + "nlike", + "not", + "notblank", + "notchecked", + "notempty", + "notnull", + "null" + ], + "type": "string" + }, + { + "type": "null" + } + ] }, "comparison_sub_op": { "anyOf": [ @@ -15583,7 +15597,7 @@ "description": "Comparison Sub-Operator" }, "fk_column_id": { - "$ref": "#/components/schemas/Id", + "$ref": "#/components/schemas/StringOrNull", "description": "Foreign Key to Column" }, "fk_parent_id": { diff --git a/packages/nocodb/src/services/public-metas.service.ts b/packages/nocodb/src/services/public-metas.service.ts index 1ce6605e73..0073502bba 100644 --- a/packages/nocodb/src/services/public-metas.service.ts +++ b/packages/nocodb/src/services/public-metas.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { ErrorMessages, RelationTypes, UITypes } from 'nocodb-sdk'; import { NcError } from '../helpers/catchError'; import { Base, Column, Model, Project, View } from '../models'; -import type { LinkToAnotherRecordColumn } from '../models'; +import type { LinkToAnotherRecordColumn, LookupColumn } from '../models'; import type { LinkToAnotherRecordType } from 'nocodb-sdk'; @Injectable() @@ -63,23 +63,88 @@ export class PublicMetasService { // load related table metas for (const col of view.model.columns) { - if (UITypes.LinkToAnotherRecord === col.uidt) { - const colOpt = await col.getColOptions(); - relatedMetas[colOpt.fk_related_model_id] = await Model.getWithInfo({ - id: colOpt.fk_related_model_id, - }); - if (colOpt.type === 'mm') { - relatedMetas[colOpt.fk_mm_model_id] = await Model.getWithInfo({ - id: colOpt.fk_mm_model_id, - }); - } - } + await this.extractRelatedMetas({ col, relatedMetas }); } view.relatedMetas = relatedMetas; return view; } + + private async extractRelatedMetas({ + col, + relatedMetas = {}, + }: { + col: Column; + relatedMetas: Record; + }) { + if (UITypes.LinkToAnotherRecord === col.uidt) { + await this.extractLTARRelatedMetas({ + ltarColOption: await col.getColOptions(), + relatedMetas, + }); + } else if (UITypes.Lookup === col.uidt) { + await this.extractLookupRelatedMetas({ + lookupColOption: await col.getColOptions(), + relatedMetas, + }); + } + } + + private async extractLTARRelatedMetas({ + ltarColOption, + relatedMetas = {}, + }: { + ltarColOption: LinkToAnotherRecordColumn; + relatedMetas: { [key: string]: Model }; + }) { + relatedMetas[ltarColOption.fk_related_model_id] = await Model.getWithInfo({ + id: ltarColOption.fk_related_model_id, + }); + if (ltarColOption.type === 'mm') { + relatedMetas[ltarColOption.fk_mm_model_id] = await Model.getWithInfo({ + id: ltarColOption.fk_mm_model_id, + }); + } + } + + private async extractLookupRelatedMetas({ + lookupColOption, + relatedMetas = {}, + }: { + lookupColOption: LookupColumn; + relatedMetas: { [key: string]: Model }; + }) { + const relationCol = await Column.get({ + colId: lookupColOption.fk_relation_column_id, + }); + const lookedUpCol = await Column.get({ + colId: lookupColOption.fk_lookup_column_id, + }); + + // extract meta for table which belongs the relation column + // if not already extracted + if (!relatedMetas[relationCol.fk_model_id]) { + relatedMetas[relationCol.fk_model_id] = await Model.getWithInfo({ + id: relationCol.fk_model_id, + }); + } + + // extract meta for table in which looked up column belongs + // if not already extracted + if (!relatedMetas[lookedUpCol.fk_model_id]) { + relatedMetas[lookedUpCol.fk_model_id] = await Model.getWithInfo({ + id: lookedUpCol.fk_model_id, + }); + } + + // extract metas related to the looked up column + await this.extractRelatedMetas({ + col: lookedUpCol, + relatedMetas, + }); + } + async publicSharedBaseGet(param: { sharedBaseUuid: string }): Promise { const project = await Project.getByUuid(param.sharedBaseUuid); diff --git a/packages/nocodb/src/utils/nc-config/NcConfig.ts b/packages/nocodb/src/utils/nc-config/NcConfig.ts index b8d3654551..cd8cb0e2fe 100644 --- a/packages/nocodb/src/utils/nc-config/NcConfig.ts +++ b/packages/nocodb/src/utils/nc-config/NcConfig.ts @@ -126,6 +126,8 @@ export class NcConfig { if (dashboardPath) { ncConfig.dashboardPath = dashboardPath; + } else { + ncConfig.dashboardPath = '/dashboard'; } try {