diff --git a/packages/nc-gui/components/dashboard/TreeView/ViewsList.vue b/packages/nc-gui/components/dashboard/TreeView/ViewsList.vue index f5d595e617..01f7b300fa 100644 --- a/packages/nc-gui/components/dashboard/TreeView/ViewsList.vue +++ b/packages/nc-gui/components/dashboard/TreeView/ViewsList.vue @@ -158,7 +158,8 @@ async function onSortEnd(evt: SortableEvent, undo = false) { if (!currentItem || !currentItem.id) return - const previousItem = (previousEl ? views.value.find((v) => v.id === previousEl.id) : {}) as ViewType + // set default order value as 0 if item not found + const previousItem = (previousEl ? views.value.find((v) => v.id === previousEl.id) ?? { order: 0 } : { order: 0 }) as ViewType const nextItem = (nextEl ? views.value.find((v) => v.id === nextEl.id) : {}) as ViewType let nextOrder: number diff --git a/packages/nc-gui/components/smartsheet/Kanban.vue b/packages/nc-gui/components/smartsheet/Kanban.vue index fef118c83b..b983deeb4f 100644 --- a/packages/nc-gui/components/smartsheet/Kanban.vue +++ b/packages/nc-gui/components/smartsheet/Kanban.vue @@ -367,7 +367,7 @@ watch( // horizontally scroll to the end of the kanban container // when a new option is added within kanban view nextTick(() => { - if (shouldScrollToRight.value) { + if (shouldScrollToRight.value && kanbanContainerRef.value) { kanbanContainerRef.value.scrollTo({ left: kanbanContainerRef.value.scrollWidth, behavior: 'smooth', diff --git a/packages/nc-gui/components/smartsheet/column/SelectOptions.vue b/packages/nc-gui/components/smartsheet/column/SelectOptions.vue index 5f59c6be83..111f0751d0 100644 --- a/packages/nc-gui/components/smartsheet/column/SelectOptions.vue +++ b/packages/nc-gui/components/smartsheet/column/SelectOptions.vue @@ -176,6 +176,8 @@ const addNewOption = () => { // } const syncOptions = () => { + // set initial colOptions if not set + vModel.value.colOptions = vModel.value.colOptions || {} vModel.value.colOptions.options = options.value .filter((op) => op.status !== 'remove') .sort((a, b) => { diff --git a/packages/nc-gui/components/smartsheet/expanded-form/index.vue b/packages/nc-gui/components/smartsheet/expanded-form/index.vue index 9edadf1492..972680dfd6 100644 --- a/packages/nc-gui/components/smartsheet/expanded-form/index.vue +++ b/packages/nc-gui/components/smartsheet/expanded-form/index.vue @@ -116,7 +116,8 @@ const fields = computedInject(FieldsInj, (_fields) => { }) const hiddenFields = computed(() => { - return (meta.value.columns ?? []).filter((col) => !fields.value?.includes(col)).filter((col) => !isSystemColumn(col)) + // todo: figure out when meta.value is undefined + return (meta.value?.columns ?? []).filter((col) => !fields.value?.includes(col)).filter((col) => !isSystemColumn(col)) }) const showHiddenFields = ref(false) diff --git a/packages/nc-gui/components/smartsheet/grid/useColumnDrag.ts b/packages/nc-gui/components/smartsheet/grid/useColumnDrag.ts index 44d9120fee..3765a7904e 100644 --- a/packages/nc-gui/components/smartsheet/grid/useColumnDrag.ts +++ b/packages/nc-gui/components/smartsheet/grid/useColumnDrag.ts @@ -25,7 +25,11 @@ export const useColumnDrag = ({ const reorderColumn = async (colId: string, toColId: string) => { const toBeReorderedViewCol = gridViewCols.value[colId] - const toViewCol = gridViewCols.value[toColId]! + const toViewCol = gridViewCols.value[toColId] + + // if toBeReorderedViewCol/toViewCol is null, return + if (!toBeReorderedViewCol || !toViewCol) return + const toColIndex = fields.value.findIndex((f) => f.id === toColId) const nextToColField = toColIndex < fields.value.length - 1 ? fields.value[toColIndex + 1] : null diff --git a/packages/nc-gui/components/smartsheet/header/CellIcon.ts b/packages/nc-gui/components/smartsheet/header/CellIcon.ts index 251c7d7c99..69e13f80fe 100644 --- a/packages/nc-gui/components/smartsheet/header/CellIcon.ts +++ b/packages/nc-gui/components/smartsheet/header/CellIcon.ts @@ -115,9 +115,11 @@ export default defineComponent({ const { sqlUis } = storeToRefs(useBase()) - const sqlUi = ref(column.value?.source_id ? sqlUis.value[column.value?.source_id] : Object.values(sqlUis.value)[0]) + const sqlUi = computed(() => + column.value?.source_id ? sqlUis.value[column.value?.source_id] : Object.values(sqlUis.value)[0], + ) - const abstractType = computed(() => column.value && sqlUi.value.getAbstractType(column.value)) + const abstractType = computed(() => column.value && sqlUi.value?.getAbstractType(column.value)) return () => { if (!column.value && !columnMeta.value) return null diff --git a/packages/nc-gui/components/virtual-cell/HasMany.vue b/packages/nc-gui/components/virtual-cell/HasMany.vue index e08bd65ba1..2cbdb17a6d 100644 --- a/packages/nc-gui/components/virtual-cell/HasMany.vue +++ b/packages/nc-gui/components/virtual-cell/HasMany.vue @@ -65,8 +65,6 @@ const cells = computed(() => const value = curr[relatedTableDisplayValueProp.value] - if (!value) return acc - return [...acc, { value, item: curr }] }, []), ) diff --git a/packages/nc-gui/components/virtual-cell/ManyToMany.vue b/packages/nc-gui/components/virtual-cell/ManyToMany.vue index 32f640bb15..2534b0fb07 100644 --- a/packages/nc-gui/components/virtual-cell/ManyToMany.vue +++ b/packages/nc-gui/components/virtual-cell/ManyToMany.vue @@ -66,8 +66,6 @@ const cells = computed(() => const value = curr[relatedTableDisplayValueProp.value] - if (!value) return acc - return [...acc, { value, item: curr }] }, []), ) diff --git a/packages/nc-gui/composables/useViewGroupBy.ts b/packages/nc-gui/composables/useViewGroupBy.ts index ff099c8166..4919757bd2 100644 --- a/packages/nc-gui/composables/useViewGroupBy.ts +++ b/packages/nc-gui/composables/useViewGroupBy.ts @@ -20,7 +20,7 @@ export const useViewGroupBy = (view: Ref, where?: Computed const tempGroupBy: { column: ColumnType; sort: string; order?: number }[] = [] Object.values(gridViewCols.value).forEach((col) => { if (col.group_by) { - const column = meta?.value.columns?.find((f) => f.id === col.fk_column_id) + const column = meta?.value?.columns?.find((f) => f.id === col.fk_column_id) if (column) { tempGroupBy.push({ column, diff --git a/packages/nc-gui/lang/en.json b/packages/nc-gui/lang/en.json index b001e929a2..b9350165d5 100644 --- a/packages/nc-gui/lang/en.json +++ b/packages/nc-gui/lang/en.json @@ -972,6 +972,7 @@ "hintStart": "Hint: Use {placeholder1} to reference fields, e.g: {placeholder2}. For more, please check out", "hintEnd": "Formulas.", "noSuggestedFormulaFound": "No suggested formula found", + "typeIsExpected": "{calleeName} requires a {type} at position {position}", "numericTypeIsExpected": "Numeric type is expected", "stringTypeIsExpected": "String type is expected", "operationNotAvailable": "{operation} operation not available", diff --git a/packages/nocodb-sdk/src/lib/formulaHelpers.ts b/packages/nocodb-sdk/src/lib/formulaHelpers.ts index 7f9f6b0bf7..d4158a8508 100644 --- a/packages/nocodb-sdk/src/lib/formulaHelpers.ts +++ b/packages/nocodb-sdk/src/lib/formulaHelpers.ts @@ -722,10 +722,12 @@ export const formulas: Record = { throw new FormulaError( FormulaErrorType.INVALID_ARG, { - key: 'msg.formula.numericTypeIsExpected', + key: 'msg.formula.typeIsExpected', + type: 'Numeric', calleeName: parsedTree.callee?.name?.toUpperCase(), + position: 2, }, - 'Numeric type is expected' + 'The REPEAT function requires a numeric as the parameter at position 2' ); } }, @@ -1771,26 +1773,32 @@ export async function validateFormulaAndExtractTreeWithType({ `Field ${name} with ${argPt.dataType} type is found but ${expectedArgType} type is expected` ); } else { - let key = '', - message = 'Invalid argument type'; + let key = ''; + const position = i + 1; + let type = ''; + if (expectedArgType === FormulaDataTypes.NUMERIC) { - key = 'msg.formula.numericTypeIsExpected'; - message = 'Numeric type is expected'; + key = 'msg.formula.typeIsExpected'; + type = 'numeric'; } else if (expectedArgType === FormulaDataTypes.BOOLEAN) { - key = 'msg.formula.booleanTypeIsExpected'; - message = 'Boolean type is expected'; + key = 'msg.formula.typeIsExpected'; + type = 'boolean'; } else if (expectedArgType === FormulaDataTypes.DATE) { - key = 'msg.formula.dateTypeIsExpected'; - message = 'Date type is expected'; + key = 'msg.formula.typeIsExpected'; + type = 'date'; } throw new FormulaError( FormulaErrorType.INVALID_ARG, { + type, key, + position, calleeName, }, - message + `${calleeName?.toUpperCase()} requires a ${ + type || expectedArgType + } at position ${position}` ); } }