Browse Source

feat(nocodb): prevent column deletion if it is being used in kanban

pull/3563/head
Wing-Kam Wong 2 years ago
parent
commit
4836fbc166
  1. 19
      packages/nocodb/src/lib/meta/api/columnApis.ts
  2. 15
      packages/nocodb/src/lib/models/KanbanView.ts

19
packages/nocodb/src/lib/meta/api/columnApis.ts

@ -34,6 +34,7 @@ import mapDefaultPrimaryValue from '../helpers/mapDefaultPrimaryValue';
import NcConnectionMgrv2 from '../../utils/common/NcConnectionMgrv2'; import NcConnectionMgrv2 from '../../utils/common/NcConnectionMgrv2';
import { metaApiMetrics } from '../helpers/apiMetrics'; import { metaApiMetrics } from '../helpers/apiMetrics';
import FormulaColumn from '../../models/FormulaColumn'; import FormulaColumn from '../../models/FormulaColumn';
import KanbanView from '../../models/KanbanView';
import { MetaTable } from '../../utils/globals'; import { MetaTable } from '../../utils/globals';
const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 10); const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 10);
@ -541,7 +542,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
// handle single quote for default value // handle single quote for default value
if (driverType === 'mysql' || driverType === 'mysql2') { if (driverType === 'mysql' || driverType === 'mysql2') {
colBody.cdf = colBody.cdf.replace(/'/g, "\'"); colBody.cdf = colBody.cdf.replace(/'/g, "'");
} else { } else {
colBody.cdf = colBody.cdf.replace(/'/g, "''"); colBody.cdf = colBody.cdf.replace(/'/g, "''");
} }
@ -837,7 +838,7 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
// handle single quote for default value // handle single quote for default value
if (driverType === 'mysql' || driverType === 'mysql2') { if (driverType === 'mysql' || driverType === 'mysql2') {
colBody.cdf = colBody.cdf.replace(/'/g, "\'"); colBody.cdf = colBody.cdf.replace(/'/g, "'");
} else { } else {
colBody.cdf = colBody.cdf.replace(/'/g, "''"); colBody.cdf = colBody.cdf.replace(/'/g, "''");
} }
@ -1509,9 +1510,21 @@ export async function columnDelete(req: Request, res: Response<TableType>) {
} }
Tele.emit('evt', { evt_type: 'raltion:deleted' }); Tele.emit('evt', { evt_type: 'raltion:deleted' });
break; break;
case UITypes.ForeignKey: case UITypes.ForeignKey: {
NcError.notImplemented(); NcError.notImplemented();
break; break;
}
// @ts-expect-error
case UITypes.SingleSelect: {
if (column.uidt === UITypes.SingleSelect) {
if (await KanbanView.IsColumnBeingUsedAsGroupingField(column.id)) {
NcError.badRequest(
`The column '${column.column_name}' is being used in Kanban View. Please delete Kanban View first.`
);
}
}
/* falls through to default */
}
default: { default: {
const tableUpdateBody = { const tableUpdateBody = {
...table, ...table,

15
packages/nocodb/src/lib/models/KanbanView.ts

@ -42,6 +42,21 @@ export default class KanbanView implements KanbanType {
return view && new KanbanView(view); return view && new KanbanView(view);
} }
public static async IsColumnBeingUsedAsGroupingField(
columnId: string,
ncMeta = Noco.ncMeta
) {
return (
(
await ncMeta.metaList2(null, null, MetaTable.KANBAN_VIEW, {
condition: {
grp_column_id: columnId,
},
})
).length > 0
);
}
static async insert(view: Partial<KanbanView>, ncMeta = Noco.ncMeta) { static async insert(view: Partial<KanbanView>, ncMeta = Noco.ncMeta) {
const insertObj = { const insertObj = {
project_id: view.project_id, project_id: view.project_id,

Loading…
Cancel
Save