Browse Source

fix: various small issues

Signed-off-by: mertmit <mertmit99@gmail.com>
pull/7750/head
mertmit 9 months ago
parent
commit
a701defc66
  1. 47
      packages/nc-gui/app.vue
  2. 78
      packages/nocodb-sdk/src/lib/formulaHelpers.ts
  3. 6
      packages/nocodb/src/db/BaseModelSqlv2.ts
  4. 2
      packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts
  5. 14
      packages/nocodb/src/services/data-table.service.ts
  6. 13
      packages/nocodb/src/services/datas.service.ts

47
packages/nc-gui/app.vue

@ -1,4 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { message } from 'ant-design-vue'
import { extractSdkResponseErrorMsg } from './utils'
import { applyNonSelectable, computed, isEeUI, isMac, useCommandPalette, useRouter, useTheme } from '#imports' import { applyNonSelectable, computed, isEeUI, isMac, useCommandPalette, useRouter, useTheme } from '#imports'
import type { CommandPaletteType } from '~/lib' import type { CommandPaletteType } from '~/lib'
@ -96,14 +98,50 @@ onMounted(() => {
refreshCommandPalette() refreshCommandPalette()
}) })
}) })
let errorCount = 0
const handleError = async (error, clearError) => {
console.error('UI ERROR', error.value)
// if error is api error, show toast message with error message
if (error.value?.response) {
message.warn(await extractSdkResponseErrorMsg(error.value))
} else {
// else show generic error message
message.warn('Something went wrong. Please reload the page if page is not functioning properly.')
}
clearError()
// if error count is more than 3 within 3 second, navigate to home
// since it's likely endless loop of errors due to some UI issue in certain page
errorCount++
if (errorCount > 3) {
router.push('/')
}
// reset error count after 1 second
setTimeout(() => {
errorCount = 0
}, 3000)
}
</script> </script>
<template> <template>
<a-config-provider> <a-config-provider>
<NuxtLayout :name="disableBaseLayout ? false : 'base'"> <NuxtLayout :name="disableBaseLayout ? false : 'base'">
<NuxtErrorBoundary>
<NuxtPage :key="key" :transition="false" /> <NuxtPage :key="key" :transition="false" />
<!-- on error, clear error and show toast message -->
<template #error="{ error, clearError }">
{{ handleError(error, clearError) }}
</template>
</NuxtErrorBoundary>
</NuxtLayout> </NuxtLayout>
</a-config-provider> </a-config-provider>
<NuxtErrorBoundary>
<div>
<!-- Command Menu --> <!-- Command Menu -->
<CmdK <CmdK
ref="commandPalette" ref="commandPalette"
@ -117,6 +155,13 @@ onMounted(() => {
/> />
<!-- Recent Views. Cycles through recently visited Views --> <!-- Recent Views. Cycles through recently visited Views -->
<CmdL v-model:open="cmdL" :set-active-cmd-view="setActiveCmdView" /> <CmdL v-model:open="cmdL" :set-active-cmd-view="setActiveCmdView" />
<!-- Documentation. Integrated NocoDB Docs directlt inside the Product --> <!-- Documentation. Integrated NocoDB Docs directly inside the Product -->
<CmdJ /> <CmdJ />
</div>
<!-- on error, clear error and show toast message -->
<template #error="{ error, clearError }">
{{ handleError(error, clearError) }}
</template>
</NuxtErrorBoundary>
</template> </template>

78
packages/nocodb-sdk/src/lib/formulaHelpers.ts

@ -323,6 +323,7 @@ export const formulas: Record<string, FormulaMeta> = {
validation: { validation: {
args: { args: {
rqd: 3, rqd: 3,
type: FormulaDataTypes.DATE,
}, },
custom: (_argTypes: FormulaDataTypes[], parsedTree: any) => { custom: (_argTypes: FormulaDataTypes[], parsedTree: any) => {
if (parsedTree.arguments[0].type === JSEPNode.LITERAL) { if (parsedTree.arguments[0].type === JSEPNode.LITERAL) {
@ -378,7 +379,6 @@ export const formulas: Record<string, FormulaMeta> = {
validation: { validation: {
args: { args: {
rqd: 1, rqd: 1,
type: FormulaDataTypes.DATE,
}, },
}, },
syntax: 'DATESTR(date | datetime)', syntax: 'DATESTR(date | datetime)',
@ -390,7 +390,6 @@ export const formulas: Record<string, FormulaMeta> = {
validation: { validation: {
args: { args: {
rqd: 1, rqd: 1,
type: FormulaDataTypes.DATE,
}, },
}, },
syntax: 'DAY(date | datetime)', syntax: 'DAY(date | datetime)',
@ -402,7 +401,6 @@ export const formulas: Record<string, FormulaMeta> = {
validation: { validation: {
args: { args: {
rqd: 1, rqd: 1,
type: FormulaDataTypes.DATE,
}, },
}, },
syntax: 'MONTH(date | datetime)', syntax: 'MONTH(date | datetime)',
@ -414,7 +412,6 @@ export const formulas: Record<string, FormulaMeta> = {
validation: { validation: {
args: { args: {
rqd: 1, rqd: 1,
type: FormulaDataTypes.DATE,
}, },
}, },
syntax: 'DAY(time | datetime)', syntax: 'DAY(time | datetime)',
@ -430,6 +427,7 @@ export const formulas: Record<string, FormulaMeta> = {
args: { args: {
min: 2, min: 2,
max: 3, max: 3,
type: FormulaDataTypes.DATE,
}, },
custom: (_argTypes: FormulaDataTypes[], parsedTree: any) => { custom: (_argTypes: FormulaDataTypes[], parsedTree: any) => {
if (parsedTree.arguments[0].type === JSEPNode.LITERAL) { if (parsedTree.arguments[0].type === JSEPNode.LITERAL) {
@ -820,6 +818,7 @@ export const formulas: Record<string, FormulaMeta> = {
validation: { validation: {
args: { args: {
rqd: 0, rqd: 0,
type: FormulaDataTypes.DATE,
}, },
}, },
description: 'Retrieve the current time and day.', description: 'Retrieve the current time and day.',
@ -887,29 +886,8 @@ export const formulas: Record<string, FormulaMeta> = {
validation: { validation: {
args: { args: {
rqd: 2, rqd: 2,
type: FormulaDataTypes.STRING,
}, },
custom(argTypes: FormulaDataTypes[], parsedTree) {
if (argTypes[0] !== FormulaDataTypes.STRING) {
throw new FormulaError(
FormulaErrorType.INVALID_ARG,
{
key: 'msg.formula.stringTypeIsExpected',
calleeName: parsedTree.callee?.name?.toUpperCase(),
},
'String type is expected'
);
}
if (argTypes[1] !== FormulaDataTypes.NUMERIC) {
throw new FormulaError(
FormulaErrorType.INVALID_ARG,
{
key: 'msg.formula.numericTypeIsExpected',
calleeName: parsedTree.callee?.name?.toUpperCase(),
},
'Numeric type is expected'
);
}
}
}, },
description: 'Retrieve the last n characters from the input string.', description: 'Retrieve the last n characters from the input string.',
syntax: 'RIGHT(str, n)', syntax: 'RIGHT(str, n)',
@ -923,29 +901,8 @@ export const formulas: Record<string, FormulaMeta> = {
validation: { validation: {
args: { args: {
rqd: 2, rqd: 2,
type: FormulaDataTypes.STRING,
}, },
custom(argTypes: FormulaDataTypes[], parsedTree) {
if (argTypes[0] !== FormulaDataTypes.STRING) {
throw new FormulaError(
FormulaErrorType.INVALID_ARG,
{
key: 'msg.formula.stringTypeIsExpected',
calleeName: parsedTree.callee?.name?.toUpperCase(),
},
'String type is expected'
);
}
if (argTypes[1] !== FormulaDataTypes.NUMERIC) {
throw new FormulaError(
FormulaErrorType.INVALID_ARG,
{
key: 'msg.formula.numericTypeIsExpected',
calleeName: parsedTree.callee?.name?.toUpperCase(),
},
'Numeric type is expected'
);
}
}
}, },
description: 'Retrieve the first n characters from the input string.', description: 'Retrieve the first n characters from the input string.',
syntax: 'LEFT(str, n)', syntax: 'LEFT(str, n)',
@ -990,30 +947,6 @@ export const formulas: Record<string, FormulaMeta> = {
FormulaDataTypes.NUMERIC, FormulaDataTypes.NUMERIC,
], ],
}, },
custom(argTypes: FormulaDataTypes[], parsedTree) {
if (argTypes[0] !== FormulaDataTypes.STRING) {
throw new FormulaError(
FormulaErrorType.INVALID_ARG,
{
key: 'msg.formula.stringTypeIsExpected',
calleeName: parsedTree.callee?.name?.toUpperCase(),
},
'String type is expected'
);
}
for(const i of [1,2]) {
if (argTypes[i] !== FormulaDataTypes.NUMERIC) {
throw new FormulaError(
FormulaErrorType.INVALID_ARG,
{
key: 'msg.formula.numericTypeIsExpected',
calleeName: parsedTree.callee?.name?.toUpperCase(),
},
'Numeric type is expected'
);
}
}
}
}, },
description: 'Extracts a substring; an alias for SUBSTR.', description: 'Extracts a substring; an alias for SUBSTR.',
syntax: 'MID(str, position, [count])', syntax: 'MID(str, position, [count])',
@ -1131,6 +1064,7 @@ export const formulas: Record<string, FormulaMeta> = {
args: { args: {
min: 1, min: 1,
max: 2, max: 2,
type: FormulaDataTypes.NUMERIC,
}, },
custom(_argTypes: FormulaDataTypes[], parsedTree: any) { custom(_argTypes: FormulaDataTypes[], parsedTree: any) {
if (parsedTree.arguments[0].type === JSEPNode.LITERAL) { if (parsedTree.arguments[0].type === JSEPNode.LITERAL) {

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

@ -2105,7 +2105,8 @@ class BaseModelSqlv2 {
obj.conditionGraph = args.conditionGraph || {}; obj.conditionGraph = args.conditionGraph || {};
obj.limit = Math.max( obj.limit = Math.max(
Math.min( Math.min(
args.limit || args.l || BaseModelSqlv2.config.limitDefault, Math.max(+(args.limit || args.l), 0) ||
BaseModelSqlv2.config.limitDefault,
BaseModelSqlv2.config.limitMax, BaseModelSqlv2.config.limitMax,
), ),
BaseModelSqlv2.config.limitMin, BaseModelSqlv2.config.limitMin,
@ -6371,7 +6372,8 @@ export function getListArgs(
obj.conditionGraph = args.conditionGraph || {}; obj.conditionGraph = args.conditionGraph || {};
obj.limit = Math.max( obj.limit = Math.max(
Math.min( Math.min(
args?.limit || args?.l || BaseModelSqlv2.config.limitDefault, Math.max(+(args?.limit || args?.l), 0) ||
BaseModelSqlv2.config.limitDefault,
BaseModelSqlv2.config.limitMax, BaseModelSqlv2.config.limitMax,
), ),
BaseModelSqlv2.config.limitMin, BaseModelSqlv2.config.limitMin,

2
packages/nocodb/src/db/formulav2/formulaQueryBuilderv2.ts

@ -16,7 +16,7 @@ import type { BaseModelSqlv2 } from '~/db/BaseModelSqlv2';
import type Column from '~/models/Column'; import type Column from '~/models/Column';
import Model from '~/models/Model'; import Model from '~/models/Model';
import NocoCache from '~/cache/NocoCache'; import NocoCache from '~/cache/NocoCache';
import { CacheGetType, CacheScope } from '~/utils/globals'; import { CacheScope } from '~/utils/globals';
import { convertDateFormatForConcat } from '~/helpers/formulaFnHelper'; import { convertDateFormatForConcat } from '~/helpers/formulaFnHelper';
import FormulaColumn from '~/models/FormulaColumn'; import FormulaColumn from '~/models/FormulaColumn';
import { Base, BaseUser } from '~/models'; import { Base, BaseUser } from '~/models';

14
packages/nocodb/src/services/data-table.service.ts

@ -21,15 +21,13 @@ export class DataTableService {
viewId?: string; viewId?: string;
ignorePagination?: boolean; ignorePagination?: boolean;
}) { }) {
const { model, view } = await this.getModelAndView(param); const { modelId, viewId, baseId, ...rest } = param;
const { model, view } = await this.getModelAndView({
return await this.datasService.getDataList({ modelId,
model, viewId,
view, baseId,
query: param.query,
throwErrorIfInvalidParams: true,
ignorePagination: param.ignorePagination,
}); });
return await this.datasService.dataList({ ...rest, model, view });
} }
async dataRead(param: { async dataRead(param: {

13
packages/nocodb/src/services/datas.service.ts

@ -20,13 +20,22 @@ export class DatasService {
constructor() {} constructor() {}
async dataList( async dataList(
param: PathParams & { param: (PathParams | { view?: View; model: Model }) & {
query: any; query: any;
disableOptimization?: boolean; disableOptimization?: boolean;
ignorePagination?: boolean; ignorePagination?: boolean;
throwErrorIfInvalidParams?: boolean;
}, },
) { ) {
const { model, view } = await getViewAndModelByAliasOrId(param); let { model, view } = param as { view?: View; model?: Model };
if (!model) {
const modelAndView = await getViewAndModelByAliasOrId(
param as PathParams,
);
model = modelAndView.model;
view = modelAndView.view;
}
return await this.getDataList({ return await this.getDataList({
model, model,

Loading…
Cancel
Save