diff --git a/packages/server/src/api/routes/tests/rowAction.spec.ts b/packages/server/src/api/routes/tests/rowAction.spec.ts index 6fbdce3afa..d4169562d3 100644 --- a/packages/server/src/api/routes/tests/rowAction.spec.ts +++ b/packages/server/src/api/routes/tests/rowAction.spec.ts @@ -176,6 +176,33 @@ describe("/rowsActions", () => { }, }) }) + + it("can not create multiple row actions with the same name (for the same table)", async () => { + const action = await createRowAction(tableId, { + name: "Row action name ", + }) + + await createRowAction( + tableId, + { name: action.name }, + { + status: 409, + body: { + message: "A row action with the same name already exists.", + }, + } + ) + await createRowAction( + tableId, + { name: "row action name" }, + { + status: 409, + body: { + message: "A row action with the same name already exists.", + }, + } + ) + }) }) describe("find", () => { diff --git a/packages/server/src/sdk/app/rowActions.ts b/packages/server/src/sdk/app/rowActions.ts index f47d4348ea..a247e62ec6 100644 --- a/packages/server/src/sdk/app/rowActions.ts +++ b/packages/server/src/sdk/app/rowActions.ts @@ -7,6 +7,16 @@ import { VirtualDocumentType, } from "@budibase/types" +function ensureUnique(doc: TableRowActions, newName: string) { + if ( + Object.values(doc.actions).find( + a => a.name.toLowerCase() === newName.toLowerCase() + ) + ) { + throw new HTTPError("A row action with the same name already exists.", 409) + } +} + export async function create(tableId: string, rowAction: { name: string }) { const action = { name: rowAction.name.trim() } @@ -23,6 +33,8 @@ export async function create(tableId: string, rowAction: { name: string }) { doc = { _id: rowActionsId, actions: {} } } + ensureUnique(doc, action.name) + const newId = `${VirtualDocumentType.ROW_ACTION}${SEPARATOR}${utils.newid()}` doc.actions[newId] = action await db.put(doc)