diff --git a/packages/nc-gui-v2/components/smartsheet/Gallery.vue b/packages/nc-gui-v2/components/smartsheet/Gallery.vue index 2f56d14cb4..ca9c54955c 100644 --- a/packages/nc-gui-v2/components/smartsheet/Gallery.vue +++ b/packages/nc-gui-v2/components/smartsheet/Gallery.vue @@ -203,10 +203,10 @@ openNewRecordFormHook?.on(async () => { display: block; font-size: 0; height: 3px; - opacity: .3; + opacity: 0.3; outline: none; padding: 0; - transition: all .5s; + transition: all 0.5s; width: 100%; } .ant-carousel.gallery-carousel :deep(.slick-dots li.slick-active div > div) { diff --git a/packages/nc-gui-v2/components/virtual-cell/ManyToMany.vue b/packages/nc-gui-v2/components/virtual-cell/ManyToMany.vue index cbc9bdd0ae..47febc5caa 100644 --- a/packages/nc-gui-v2/components/virtual-cell/ManyToMany.vue +++ b/packages/nc-gui-v2/components/virtual-cell/ManyToMany.vue @@ -94,14 +94,14 @@ const unlinkRef = async (rec: Record) => { -
+
diff --git a/packages/nc-gui-v2/components/virtual-cell/components/ListChildItems.vue b/packages/nc-gui-v2/components/virtual-cell/components/ListChildItems.vue index 70e32a2b48..8339270602 100644 --- a/packages/nc-gui-v2/components/virtual-cell/components/ListChildItems.vue +++ b/packages/nc-gui-v2/components/virtual-cell/components/ListChildItems.vue @@ -101,6 +101,7 @@ const expandedFormRow = ref() class="!my-4 hover:(!bg-gray-200/50 shadow-md)" @click=" () => { + if (readonly) return expandedFormRow = row expandedFormDlg = true } diff --git a/packages/nc-gui-v2/composables/useLTARStore.ts b/packages/nc-gui-v2/composables/useLTARStore.ts index 81f92b0a4d..60adb6e0b5 100644 --- a/packages/nc-gui-v2/composables/useLTARStore.ts +++ b/packages/nc-gui-v2/composables/useLTARStore.ts @@ -150,19 +150,35 @@ const [useProvideLTARStore, useLTARStore] = useInjectionState( try { if (colOptions.type === 'bt') return - childrenList.value = await $api.dbTableRow.nestedList( - NOCO, - (project?.value?.id || sharedView?.value?.view?.project_id) as string, - meta.value.id, - rowId.value, - colOptions.type as 'mm' | 'hm', - encodeURIComponent(column?.value?.title), - { - limit: String(childrenListPagination.size), - offset: String(childrenListPagination.size * (childrenListPagination.page - 1)), - where: childrenListPagination.query && `(${relatedTablePrimaryValueProp.value},like,${childrenListPagination.query})`, - } as any, - ) + if (isPublic) { + childrenList.value = await $api.public.dataNestedList( + sharedView.value?.uuid as string, + rowId.value, + colOptions.type as 'mm' | 'hm', + encodeURIComponent(column?.value?.id), + { + limit: String(childrenListPagination.size), + offset: String(childrenListPagination.size * (childrenListPagination.page - 1)), + where: + childrenListPagination.query && `(${relatedTablePrimaryValueProp.value},like,${childrenListPagination.query})`, + } as any, + ) + } else { + childrenList.value = await $api.dbTableRow.nestedList( + NOCO, + (project?.value?.id || sharedView?.value?.view?.project_id) as string, + meta.value.id, + rowId.value, + colOptions.type as 'mm' | 'hm', + encodeURIComponent(column?.value?.title), + { + limit: String(childrenListPagination.size), + offset: String(childrenListPagination.size * (childrenListPagination.page - 1)), + where: + childrenListPagination.query && `(${relatedTablePrimaryValueProp.value},like,${childrenListPagination.query})`, + } as any, + ) + } } catch (e: any) { message.error(`Failed to load children list: ${await extractSdkResponseErrorMsg(e)}`) } diff --git a/packages/nocodb/src/lib/meta/api/dataApis/dataAliasNestedApis.ts b/packages/nocodb/src/lib/meta/api/dataApis/dataAliasNestedApis.ts index 4ce58ac2ac..f1ddbd0a50 100644 --- a/packages/nocodb/src/lib/meta/api/dataApis/dataAliasNestedApis.ts +++ b/packages/nocodb/src/lib/meta/api/dataApis/dataAliasNestedApis.ts @@ -4,7 +4,7 @@ import Base from '../../../models/Base'; import NcConnectionMgrv2 from '../../../utils/common/NcConnectionMgrv2'; import { PagedResponseImpl } from '../../helpers/PagedResponse'; import ncMetaAclMw from '../../helpers/ncMetaAclMw'; -import { getViewAndModelFromRequestByAliasOrId } from './helpers'; +import { getColumnByIdOrName, getViewAndModelFromRequestByAliasOrId } from './helpers' import { NcError } from '../../helpers/catchError'; import apiMetrics from '../../helpers/apiMetrics'; @@ -240,19 +240,6 @@ async function relationDataAdd(req, res) { res.json({ msg: 'success' }); } -async function getColumnByIdOrName(columnNameOrId: string, model: Model) { - const column = (await model.getColumns()).find( - (c) => - c.title === columnNameOrId || - c.id === columnNameOrId || - c.column_name === columnNameOrId - ); - - if (!column) - NcError.notFound(`Column with id/name '${columnNameOrId}' is not found`); - - return column; -} const router = Router({ mergeParams: true }); diff --git a/packages/nocodb/src/lib/meta/api/dataApis/helpers.ts b/packages/nocodb/src/lib/meta/api/dataApis/helpers.ts index 059d3473bd..e75855bf32 100644 --- a/packages/nocodb/src/lib/meta/api/dataApis/helpers.ts +++ b/packages/nocodb/src/lib/meta/api/dataApis/helpers.ts @@ -229,3 +229,18 @@ export async function serializeCellValue({ return value; } } + + +export async function getColumnByIdOrName(columnNameOrId: string, model: Model) { + const column = (await model.getColumns()).find( + (c) => + c.title === columnNameOrId || + c.id === columnNameOrId || + c.column_name === columnNameOrId + ); + + if (!column) + NcError.notFound(`Column with id/name '${columnNameOrId}' is not found`); + + return column; +} diff --git a/packages/nocodb/src/lib/meta/api/publicApis/publicDataApis.ts b/packages/nocodb/src/lib/meta/api/publicApis/publicDataApis.ts index 2bc14e6ad3..345bc5e3b8 100644 --- a/packages/nocodb/src/lib/meta/api/publicApis/publicDataApis.ts +++ b/packages/nocodb/src/lib/meta/api/publicApis/publicDataApis.ts @@ -17,6 +17,7 @@ import { mimeIcons } from '../../../utils/mimeTypes'; import slash from 'slash'; import { sanitizeUrlPath } from '../attachmentApis'; import getAst from '../../../db/sql-data-mapper/lib/sql/helpers/getAst'; +import { getColumnByIdOrName } from '../dataApis/helpers'; export async function dataList(req: Request, res: Response) { try { @@ -219,7 +220,10 @@ export async function publicMmList(req: Request, res: Response) { NcError.forbidden(ErrorMessages.INVALID_SHARED_VIEW_PASSWORD); } - const column = await Column.get({ colId: req.params.colId }); + const column = await getColumnByIdOrName( + req.params.colId, + await view.getModel() + ); if (column.fk_model_id !== view.fk_model_id) NcError.badRequest("Column doesn't belongs to the model"); @@ -275,7 +279,10 @@ export async function publicHmList(req: Request, res: Response) { NcError.forbidden(ErrorMessages.INVALID_SHARED_VIEW_PASSWORD); } - const column = await Column.get({ colId: req.params.colId }); + const column = await getColumnByIdOrName( + req.params.colId, + await view.getModel() + ); if (column.fk_model_id !== view.fk_model_id) NcError.badRequest("Column doesn't belongs to the model"); @@ -317,11 +324,7 @@ export async function publicHmList(req: Request, res: Response) { id: req.params.rowId, }); - res.json( - new PagedResponseImpl(data, { - totalRows: count, - } as any) - ); + res.json(new PagedResponseImpl(data, { ...req.query, count })); } const router = Router({ mergeParams: true }); diff --git a/packages/nocodb/src/lib/meta/helpers/PagedResponse.ts b/packages/nocodb/src/lib/meta/helpers/PagedResponse.ts index ca8ced949c..777b4b4eb3 100644 --- a/packages/nocodb/src/lib/meta/helpers/PagedResponse.ts +++ b/packages/nocodb/src/lib/meta/helpers/PagedResponse.ts @@ -5,21 +5,31 @@ const config: any = { limitMin: Math.max(+process.env.DB_QUERY_LIMIT_MIN || 1, 1), limitMax: Math.max(+process.env.DB_QUERY_LIMIT_MAX || 1000, 1), }; + export class PagedResponseImpl { constructor( list: T[], - args: { limit?: number; offset?: number; count?: number, l?: number, o?: number } = {} + args: { + limit?: number; + offset?: number; + count?: number | string; + l?: number; + o?: number; + } = {} ) { const limit = Math.max( - Math.min( - args.limit || args.l || config.limitDefault, - config.limitMax - ), + Math.min(args.limit || args.l || config.limitDefault, config.limitMax), config.limitMin ); + const offset = Math.max(+(args.offset || args.o) || 0, 0); - const count = args.count ?? null; + + let count = args.count ?? null; + + if (count !== null) count = +count; + this.list = list; + if (count !== null) { this.pageInfo = { totalRows: +count }; this.pageInfo.page = offset ? offset / limit + 1 : 1; diff --git a/packages/nocodb/src/lib/models/Column.ts b/packages/nocodb/src/lib/models/Column.ts index 3d3bb8f8b9..82cc863b23 100644 --- a/packages/nocodb/src/lib/models/Column.ts +++ b/packages/nocodb/src/lib/models/Column.ts @@ -232,20 +232,33 @@ export default class Column implements ColumnType { } case UITypes.MultiSelect: { if (!column.colOptions?.options) { - const selectColors = [ '#cfdffe', '#d0f1fd', '#c2f5e8', '#ffdaf6', '#ffdce5', '#fee2d5', '#ffeab6', '#d1f7c4', '#ede2fe', '#eeeeee', ]; - for (const [i, option] of column.dtxp?.split(',').entries() || [].entries()) { + const selectColors = [ + '#cfdffe', + '#d0f1fd', + '#c2f5e8', + '#ffdaf6', + '#ffdce5', + '#fee2d5', + '#ffeab6', + '#d1f7c4', + '#ede2fe', + '#eeeeee', + ]; + for (const [i, option] of column.dtxp?.split(',').entries() || + [].entries()) { await SelectOption.insert( { fk_column_id: colId, title: option.replace(/^'/, '').replace(/'$/, ''), order: i + 1, - color: selectColors[i % selectColors.length] + color: selectColors[i % selectColors.length], }, ncMeta ); } } else { - for (const [i, option] of column.colOptions.options.entries() || [].entries()) { + for (const [i, option] of column.colOptions.options.entries() || + [].entries()) { // Trim end of enum/set if (column.dt === 'enum' || column.dt === 'set') { option.title = option.title.trimEnd(); @@ -254,7 +267,7 @@ export default class Column implements ColumnType { { ...option, fk_column_id: colId, - order: i + 1 + order: i + 1, }, ncMeta ); @@ -264,20 +277,33 @@ export default class Column implements ColumnType { } case UITypes.SingleSelect: { if (!column.colOptions?.options) { - const selectColors = [ '#cfdffe', '#d0f1fd', '#c2f5e8', '#ffdaf6', '#ffdce5', '#fee2d5', '#ffeab6', '#d1f7c4', '#ede2fe', '#eeeeee', ]; - for (const [i, option] of column.dtxp?.split(',').entries() || [].entries()) { + const selectColors = [ + '#cfdffe', + '#d0f1fd', + '#c2f5e8', + '#ffdaf6', + '#ffdce5', + '#fee2d5', + '#ffeab6', + '#d1f7c4', + '#ede2fe', + '#eeeeee', + ]; + for (const [i, option] of column.dtxp?.split(',').entries() || + [].entries()) { await SelectOption.insert( { fk_column_id: colId, title: option.replace(/^'/, '').replace(/'$/, ''), order: i + 1, - color: selectColors[i % selectColors.length] + color: selectColors[i % selectColors.length], }, ncMeta ); } } else { - for (const [i, option] of column.colOptions.options.entries() || [].entries()) { + for (const [i, option] of column.colOptions.options.entries() || + [].entries()) { // Trim end of enum/set if (column.dt === 'enum' || column.dt === 'set') { option.title = option.title.trimEnd(); @@ -286,7 +312,7 @@ export default class Column implements ColumnType { { ...option, fk_column_id: colId, - order: i + 1 + order: i + 1, }, ncMeta ); @@ -507,12 +533,14 @@ export default class Column implements ColumnType { MetaTable.COLUMNS, colId ); - try { - colData.meta = JSON.parse(colData.meta); - } catch { - colData.meta = {}; + if (colData) { + try { + colData.meta = JSON.parse(colData.meta); + } catch { + colData.meta = {}; + } + await NocoCache.set(`${CacheScope.COLUMN}:${colId}`, colData); } - await NocoCache.set(`${CacheScope.COLUMN}:${colId}`, colData); } if (colData) { const column = new Column(colData);