From 2c4af95ee3014e12de9ea6352ca73dab5dbe95bf Mon Sep 17 00:00:00 2001 From: Gregor Vostrak Date: Tue, 10 Feb 2026 13:19:30 +0100 Subject: [PATCH] Add Tag Edit Modal and UI --- e2e/tags.spec.ts | 32 ++++++++ .../js/Components/Common/Tag/TagEditModal.vue | 75 +++++++++++++++++++ .../Common/Tag/TagMoreOptionsDropdown.vue | 14 +++- .../js/Components/Common/Tag/TagTableRow.vue | 10 ++- resources/js/packages/api/src/index.ts | 1 + resources/js/utils/permissions.ts | 4 + resources/js/utils/useTags.ts | 28 ++++++- 7 files changed, 158 insertions(+), 6 deletions(-) create mode 100644 resources/js/Components/Common/Tag/TagEditModal.vue diff --git a/e2e/tags.spec.ts b/e2e/tags.spec.ts index c2f65b93..26995641 100644 --- a/e2e/tags.spec.ts +++ b/e2e/tags.spec.ts @@ -88,3 +88,35 @@ test('test that multiple tags can be created via API and displayed in the table' await expect(page.getByTestId('tag_table')).toContainText(tagName1); await expect(page.getByTestId('tag_table')).toContainText(tagName2); }); + +// ============================================= +// Employee Permission Tests +// ============================================= + +test.describe('Employee Tags Restrictions', () => { + test('employee can view tags but cannot create', async ({ ctx, employee }) => { + const tagName = 'EmpViewTag ' + Math.floor(Math.random() * 10000); + await createTagViaApi(ctx, { name: tagName }); + + await employee.page.goto(PLAYWRIGHT_BASE_URL + '/tags'); + await expect(employee.page.getByTestId('tags_view')).toBeVisible({ timeout: 10000 }); + + // Employee can see the tag (tags are visible to all members with tags:view) + await expect(employee.page.getByText(tagName)).toBeVisible({ timeout: 10000 }); + + // Employee cannot see Create Tag button + await expect(employee.page.getByRole('button', { name: 'Create Tag' })).not.toBeVisible(); + }); + + test('employee cannot see edit/delete actions on tags', async ({ ctx, employee }) => { + const tagName = 'EmpActionsTag ' + Math.floor(Math.random() * 10000); + await createTagViaApi(ctx, { name: tagName }); + + await employee.page.goto(PLAYWRIGHT_BASE_URL + '/tags'); + await expect(employee.page.getByText(tagName)).toBeVisible({ timeout: 10000 }); + + // Actions button should not be visible for employee + const actionsButton = employee.page.locator(`[aria-label='Actions for Tag ${tagName}']`); + await expect(actionsButton).not.toBeVisible(); + }); +}); diff --git a/resources/js/Components/Common/Tag/TagEditModal.vue b/resources/js/Components/Common/Tag/TagEditModal.vue new file mode 100644 index 00000000..bd4d0083 --- /dev/null +++ b/resources/js/Components/Common/Tag/TagEditModal.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/resources/js/Components/Common/Tag/TagMoreOptionsDropdown.vue b/resources/js/Components/Common/Tag/TagMoreOptionsDropdown.vue index e67ae32a..7e1182bb 100644 --- a/resources/js/Components/Common/Tag/TagMoreOptionsDropdown.vue +++ b/resources/js/Components/Common/Tag/TagMoreOptionsDropdown.vue @@ -1,5 +1,6 @@