Browse Source

fix: limit rollup functions per UIType

pull/7202/head
mertmit 12 months ago
parent
commit
a4d5af07bd
  1. 40
      packages/nc-gui/components/smartsheet/column/RollupOptions.vue
  2. 42
      packages/nocodb-sdk/src/lib/helperFunctions.ts
  3. 14
      packages/nocodb/src/helpers/columnHelpers.ts

40
packages/nc-gui/components/smartsheet/column/RollupOptions.vue

@ -1,7 +1,7 @@
<script setup lang="ts">
import { onMounted } from '@vue/runtime-core'
import type { ColumnType, LinkToAnotherRecordType, TableType, UITypes } from 'nocodb-sdk'
import { isLinksOrLTAR, isNumericCol, isSystemColumn, isVirtualCol } from 'nocodb-sdk'
import { getAvailableRollupForUiType, isLinksOrLTAR, isNumericCol, isSystemColumn, isVirtualCol } from 'nocodb-sdk'
import type { Ref } from '#imports'
import {
MetaInj,
@ -102,31 +102,27 @@ const cellIcon = (column: ColumnType) =>
const aggFunctionsList: Ref<Record<string, string>[]> = ref([])
const allFunctions = [
{ text: t('datatype.Count'), value: 'count' },
{ text: t('general.min'), value: 'min' },
{ text: t('general.max'), value: 'max' },
{ text: t('general.avg'), value: 'avg' },
{ text: t('general.sum'), value: 'sum' },
{ text: t('general.countDistinct'), value: 'countDistinct' },
{ text: t('general.sumDistinct'), value: 'sumDistinct' },
{ text: t('general.avgDistinct'), value: 'avgDistinct' },
]
watch(
() => vModel.value.fk_rollup_column_id,
() => {
const childFieldColumn = columns.value?.find((column: ColumnType) => column.id === vModel.value.fk_rollup_column_id)
const showNumericFunctions = isNumericCol(childFieldColumn)
const nonNumericFunctions = [
// functions for non-numeric types,
// e.g. count / min / max / countDistinct date field
{ text: t('datatype.Count'), value: 'count' },
{ text: t('general.min'), value: 'min' },
{ text: t('general.max'), value: 'max' },
{ text: t('general.countDistinct'), value: 'countDistinct' },
]
const numericFunctions = showNumericFunctions
? [
{ text: t('general.avg'), value: 'avg' },
{ text: t('general.sum'), value: 'sum' },
{ text: t('general.sumDistinct'), value: 'sumDistinct' },
{ text: t('general.avgDistinct'), value: 'avgDistinct' },
]
: []
aggFunctionsList.value = [...nonNumericFunctions, ...numericFunctions]
if (!showNumericFunctions && ['avg', 'sum', 'sumDistinct', 'avgDistinct'].includes(vModel.value.rollup_function)) {
aggFunctionsList.value = allFunctions.filter((func) =>
getAvailableRollupForUiType(childFieldColumn?.uidt as UITypes).includes(func.value),
)
if (!aggFunctionsList.value.includes(vModel.value.rollup_function)) {
// when the previous roll up function was numeric type and the current child field is non-numeric
// reset rollup function with a non-numeric type
vModel.value.rollup_function = aggFunctionsList.value[0].value

42
packages/nocodb-sdk/src/lib/helperFunctions.ts

@ -1,4 +1,4 @@
import UITypes from './UITypes';
import UITypes, { isNumericCol } from './UITypes';
import { RolesObj, RolesType } from './globals';
// import {RelationTypes} from "./globals";
@ -45,6 +45,45 @@ const stringifyRolesObj = (roles?: RolesObj | null): string => {
return rolesArr.join(',');
};
const getAvailableRollupForUiType = (type: string) => {
if (isNumericCol(type as UITypes)) {
return [
'sum',
'count',
'min',
'max',
'avg',
'countDistinct',
'sumDistinct',
'avgDistinct',
];
} else if ([UITypes.Date, UITypes.DateTime].includes(type as UITypes)) {
return ['count', 'min', 'max', 'countDistinct'];
} else if (
[
UITypes.SingleLineText,
UITypes.LongText,
UITypes.User,
UITypes.Email,
UITypes.PhoneNumber,
UITypes.URL,
].includes(type as UITypes)
) {
return ['count'];
} else {
return [
'sum',
'count',
'min',
'max',
'avg',
'countDistinct',
'sumDistinct',
'avgDistinct',
];
}
};
export {
filterOutSystemColumns,
getSystemColumnsIds,
@ -52,4 +91,5 @@ export {
isSystemColumn,
extractRolesObj,
stringifyRolesObj,
getAvailableRollupForUiType,
};

14
packages/nocodb/src/helpers/columnHelpers.ts

@ -1,5 +1,5 @@
import { customAlphabet } from 'nanoid';
import { UITypes } from 'nocodb-sdk';
import { getAvailableRollupForUiType, UITypes } from 'nocodb-sdk';
import { pluralize, singularize } from 'inflection';
import type { RollupColumn } from '~/models';
import type {
@ -135,6 +135,18 @@ export async function validateRollupPayload(payload: ColumnReqType | Column) {
)
)
throw new Error('Rollup column not found in related table');
if (
!getAvailableRollupForUiType(relatedColumn.uidt).includes(
(payload as RollupColumnReqType).rollup_function,
)
) {
throw new Error(
`Rollup function (${
(payload as RollupColumnReqType).rollup_function
}) not available for type (${relatedColumn.uidt})`,
);
}
}
export async function validateLookupPayload(

Loading…
Cancel
Save