Skip to content

Commit ac601b3

Browse files
authored
Disable option creation for restricted namespaces in dropdown and enum (#6334)
* add hook to get namespace info * disable option for restricted namespaces * add fragment * remove workaround * disable enum option creation * update fragment * move e2e test * add test id * update test to use branch + add test for disabled button * hide buttons * update import * update test * revert move e2e test * fix import * revert config
1 parent f78aa1b commit ac601b3

File tree

5 files changed

+55
-13
lines changed

5 files changed

+55
-13
lines changed

changelog/+dropdown.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Disable option creation for restricted namespaces in dropdown and enum
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { namespacesAtom } from "@/entities/schema/stores/schema.atom";
2+
import { Namespace } from "@/entities/schema/types";
3+
import { useAtomValue } from "jotai";
4+
5+
export const useNamespace = (namespace: string | null | undefined): Namespace | undefined => {
6+
const namespaces = useAtomValue(namespacesAtom);
7+
8+
return namespaces.find((n) => {
9+
return n.name === namespace;
10+
});
11+
};

frontend/app/src/shared/components/inputs/dropdown.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { DROPDOWN_ADD_MUTATION, DROPDOWN_REMOVE_MUTATION } from "@/entities/schema/api/dropdown";
22
import { AttributeSchema, ModelSchema } from "@/entities/schema/types";
3+
import { useNamespace } from "@/entities/schema/ui/hooks/useNamespace";
34
import { useMutation } from "@/shared/api/graphql/useQuery";
45
import { Button } from "@/shared/components/buttons/button-primitive";
56
import SlideOver, { SlideOverTitle } from "@/shared/components/display/slide-over";
@@ -143,17 +144,21 @@ export const DropdownAddAction: React.FC<DropdownAddActionProps> = ({
143144
field,
144145
addOption,
145146
}) => {
147+
const namespace = useNamespace(schema.namespace);
146148
const [open, setOpen] = useState(false);
147149
const [addDropdownItem] = useMutation(DROPDOWN_ADD_MUTATION);
148150

149151
return (
150152
<div className="p-2 pt-0">
151-
<Button
152-
className="w-full bg-custom-blue-700/10 border border-custom-blue-700/20 text-custom-blue-700 enabled:hover:bg-custom-blue-700/20"
153-
onClick={() => setOpen(!open)}
154-
>
155-
+ Add option
156-
</Button>
153+
{namespace?.user_editable && (
154+
<Button
155+
className="w-full bg-custom-blue-700/10 border border-custom-blue-700/20 text-custom-blue-700 enabled:hover:bg-custom-blue-700/20"
156+
onClick={() => setOpen(!open)}
157+
data-testid="add-option-button"
158+
>
159+
+ Add option
160+
</Button>
161+
)}
157162

158163
<SlideOver
159164
title={

frontend/app/src/shared/components/inputs/enum.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ENUM_ADD_MUTATION, ENUM_REMOVE_MUTATION } from "@/entities/schema/api/enum";
22
import { AttributeSchema, ModelSchema } from "@/entities/schema/types";
3+
import { useNamespace } from "@/entities/schema/ui/hooks/useNamespace";
34
import { useMutation } from "@/shared/api/graphql/useQuery";
45
import { Button, ButtonProps } from "@/shared/components/buttons/button-primitive";
56
import SlideOver, { SlideOverTitle } from "@/shared/components/display/slide-over";
@@ -83,19 +84,22 @@ interface EnumAddActionProps {
8384
}
8485

8586
export const EnumAddAction: React.FC<EnumAddActionProps> = ({ schema, field, addOption }) => {
87+
const namespace = useNamespace(schema?.namespace);
8688
const [open, setOpen] = useState(false);
8789
const [addEnum] = useMutation(ENUM_ADD_MUTATION);
8890

8991
if (!schema || !field) return null;
9092

9193
return (
9294
<div className="p-2 pt-0">
93-
<Button
94-
className="w-full bg-custom-blue-700/10 border border-custom-blue-700/20 text-custom-blue-700 enabled:hover:bg-custom-blue-700/20"
95-
onClick={() => setOpen(!open)}
96-
>
97-
+ Add option
98-
</Button>
95+
{namespace?.user_editable && (
96+
<Button
97+
className="w-full bg-custom-blue-700/10 border border-custom-blue-700/20 text-custom-blue-700 enabled:hover:bg-custom-blue-700/20"
98+
onClick={() => setOpen(!open)}
99+
>
100+
+ Add option
101+
</Button>
102+
)}
99103

100104
<SlideOver
101105
title={

frontend/app/tests/e2e/objects/object-dropdown-creation.spec.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { expect, test } from "@playwright/test";
22
import { ACCOUNT_STATE_PATH } from "../../constants";
3+
import { generateRandomBranchName } from "../../utils";
4+
import { createBranchAPI, deleteBranchAPI } from "../utils/graphql";
35

46
test.describe("object dropdown creation", () => {
57
test.use({ storageState: ACCOUNT_STATE_PATH.ADMIN });
@@ -12,8 +14,18 @@ test.describe("object dropdown creation", () => {
1214
});
1315
});
1416

17+
const BRANCH_NAME = generateRandomBranchName();
18+
19+
test.beforeAll(async ({ request }) => {
20+
await createBranchAPI(request, BRANCH_NAME);
21+
});
22+
23+
test.afterAll(async ({ request }) => {
24+
await deleteBranchAPI(request, BRANCH_NAME);
25+
});
26+
1527
test("should open the creation form and open the tag option creation form", async ({ page }) => {
16-
await page.goto("/objects/InfraDevice");
28+
await page.goto(`/objects/InfraDevice?branch=${BRANCH_NAME}`);
1729

1830
// Open creation form
1931
await page.getByTestId("create-object-button").click();
@@ -39,4 +51,13 @@ test.describe("object dropdown creation", () => {
3951
// Closes the form
4052
await page.getByRole("button", { name: "Cancel" }).click();
4153
});
54+
55+
test("should not be able to create a new option for dropdown", async ({ page }) => {
56+
await page.goto(`/objects/CoreWebhook?branch=${BRANCH_NAME}`);
57+
await page.getByTestId("create-object-button").click();
58+
await page.getByRole("combobox", { name: "Select an object type" }).click();
59+
await page.getByRole("option", { name: "Custom Webhook Core" }).click();
60+
await page.getByRole("combobox", { name: "Branch Scope" }).click();
61+
expect(await page.getByTestId("add-option-button")).toBeHidden();
62+
});
4263
});

0 commit comments

Comments
 (0)