diff --git a/src/packages/model/CodesList.ts b/src/packages/model/CodesList.ts
index 9a2998c75..7a9b20779 100644
--- a/src/packages/model/CodesList.ts
+++ b/src/packages/model/CodesList.ts
@@ -13,6 +13,8 @@ export interface CodesList {
id?: string;
codes: Code[];
notation: string;
+ lastCodeUriSegment: string;
+ contributor: string;
}
export type CodesLists = {
diff --git a/src/packages/modules-codelists/components/codelist-detail/code-sliding-panel-menu.spec.tsx b/src/packages/modules-codelists/components/codelist-detail/code-sliding-panel-menu.spec.tsx
new file mode 100644
index 000000000..43e59458f
--- /dev/null
+++ b/src/packages/modules-codelists/components/codelist-detail/code-sliding-panel-menu.spec.tsx
@@ -0,0 +1,143 @@
+import { CodesList } from '@model/CodesList';
+import { render, screen, fireEvent } from '@testing-library/react';
+import { Mock, vi } from 'vitest';
+
+import { ADMIN, CODELIST_CONTRIBUTOR } from '../../../auth/roles';
+import { usePermission } from '../../../redux/hooks/usePermission';
+import { CodeSlidingPanelMenu } from './code-sliding-panel-menu';
+
+vi.mock('../../../redux/hooks/usePermission');
+
+describe('CodeSlidingPanelMenu', () => {
+ const mockHandleSubmit = vi.fn();
+ const mockHandleBack = vi.fn();
+ const codelist = { contributor: 'test-contributor' };
+
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it('renders the ReturnButton', () => {
+ (usePermission as Mock).mockReturnValue({ roles: [], stamp: '' });
+ render(
+ ,
+ );
+
+ screen.getByRole('button', { name: /back/i });
+ });
+
+ it('renders the UpdateButton when not in creation mode and has permission', () => {
+ (usePermission as Mock).mockReturnValue({
+ roles: [CODELIST_CONTRIBUTOR],
+ stamp: 'test-contributor',
+ });
+
+ render(
+ ,
+ );
+
+ screen.getByRole('button', { name: /update/i });
+ });
+
+ it('renders the SaveButton when in creation mode and has permission', () => {
+ (usePermission as Mock).mockReturnValue({
+ roles: [CODELIST_CONTRIBUTOR],
+ stamp: 'test-contributor',
+ });
+
+ render(
+ ,
+ );
+
+ screen.getByRole('button', { name: /save/i });
+ });
+
+ it('does not render UpdateButton or SaveButton when user lacks permissions', () => {
+ (usePermission as Mock).mockReturnValue({
+ roles: [],
+ stamp: 'other-contributor',
+ });
+
+ render(
+ ,
+ );
+
+ expect(screen.queryByRole('button', { name: /update/i })).toBeNull();
+
+ render(
+ ,
+ );
+
+ expect(screen.queryByRole('button', { name: /save/i })).toBeNull();
+ });
+
+ it('renders the UpdateButton and SaveButton for admin users', () => {
+ (usePermission as Mock).mockReturnValue({ roles: [ADMIN], stamp: '' });
+
+ render(
+ ,
+ );
+
+ screen.getByRole('button', { name: /update/i });
+
+ render(
+ ,
+ );
+
+ screen.getByRole('button', { name: /save/i });
+ });
+
+ it('triggers the appropriate actions on button clicks', () => {
+ (usePermission as Mock).mockReturnValue({ roles: [ADMIN], stamp: '' });
+
+ render(
+ ,
+ );
+
+ fireEvent.click(screen.getByRole('button', { name: /back/i }));
+ expect(mockHandleBack).toHaveBeenCalled();
+
+ fireEvent.click(screen.getByRole('button', { name: /update/i }));
+ expect(mockHandleSubmit).toHaveBeenCalled();
+ });
+});
diff --git a/src/packages/modules-codelists/components/codelist-detail/code-sliding-panel-menu.jsx b/src/packages/modules-codelists/components/codelist-detail/code-sliding-panel-menu.tsx
similarity index 65%
rename from src/packages/modules-codelists/components/codelist-detail/code-sliding-panel-menu.jsx
rename to src/packages/modules-codelists/components/codelist-detail/code-sliding-panel-menu.tsx
index 0ddccf23b..7ce8a67fd 100644
--- a/src/packages/modules-codelists/components/codelist-detail/code-sliding-panel-menu.jsx
+++ b/src/packages/modules-codelists/components/codelist-detail/code-sliding-panel-menu.tsx
@@ -1,3 +1,5 @@
+import { CodesList } from '@model/CodesList';
+
import { ActionToolbar } from '@components/action-toolbar';
import {
ReturnButton,
@@ -8,12 +10,18 @@ import {
import { ADMIN, CODELIST_CONTRIBUTOR } from '../../../auth/roles';
import { usePermission } from '../../../redux/hooks/usePermission';
+interface CodeSlidingPanelMenuTypes {
+ codelist: CodesList;
+ handleSubmit: () => void;
+ handleBack: () => void;
+ creation: boolean;
+}
export const CodeSlidingPanelMenu = ({
codelist,
handleSubmit,
handleBack,
creation,
-}) => {
+}: Readonly) => {
const permission = usePermission();
const hasRightsBasedOnStamp =
@@ -23,11 +31,11 @@ export const CodeSlidingPanelMenu = ({
return (
-
+
{(isAdmin || hasRightsBasedOnStamp) && (
<>
- {!creation && }
- {creation && }
+ {!creation && }
+ {creation && }
>
)}
diff --git a/src/packages/modules-codelists/components/codelist-detail/codes-panel-add-button.spec.tsx b/src/packages/modules-codelists/components/codelist-detail/codes-panel-add-button.spec.tsx
index faca3d6dd..2017ed249 100644
--- a/src/packages/modules-codelists/components/codelist-detail/codes-panel-add-button.spec.tsx
+++ b/src/packages/modules-codelists/components/codelist-detail/codes-panel-add-button.spec.tsx
@@ -1,3 +1,4 @@
+import { CodesList } from '@model/CodesList';
import { render, screen, fireEvent } from '@testing-library/react';
import { Mock, vi } from 'vitest';
@@ -23,7 +24,10 @@ describe('CodesPanelAddButton', () => {
});
render(
- ,
+ ,
);
expect(screen.queryByRole('button', { name: /add/i })).toBeNull();
@@ -37,7 +41,7 @@ describe('CodesPanelAddButton', () => {
render(
,
);
@@ -53,10 +57,12 @@ describe('CodesPanelAddButton', () => {
render(
,
);
@@ -72,10 +78,12 @@ describe('CodesPanelAddButton', () => {
render(
,
);
@@ -91,10 +99,12 @@ describe('CodesPanelAddButton', () => {
render(
,
);
diff --git a/src/packages/modules-codelists/components/codelist-detail/codes-panel-add-button.tsx b/src/packages/modules-codelists/components/codelist-detail/codes-panel-add-button.tsx
index 0c1501eec..cee336b65 100644
--- a/src/packages/modules-codelists/components/codelist-detail/codes-panel-add-button.tsx
+++ b/src/packages/modules-codelists/components/codelist-detail/codes-panel-add-button.tsx
@@ -1,10 +1,12 @@
+import { CodesList } from '@model/CodesList';
+
import { AddButton } from '@components/buttons/add';
import { ADMIN, CODELIST_CONTRIBUTOR } from '../../../auth/roles';
import { usePermission } from '../../../redux/hooks/usePermission';
interface CodesPanelAddButtonTypes {
- codelist: any;
+ codelist: CodesList;
onHandlePanel: () => void;
}
export const CodesPanelAddButton = ({
diff --git a/src/packages/modules-codelists/components/codelist-detail/codes-panel.scss b/src/packages/modules-codelists/components/codelist-detail/codes-panel.css
similarity index 100%
rename from src/packages/modules-codelists/components/codelist-detail/codes-panel.scss
rename to src/packages/modules-codelists/components/codelist-detail/codes-panel.css
diff --git a/src/packages/modules-codelists/components/codelist-detail/codes-panel.jsx b/src/packages/modules-codelists/components/codelist-detail/codes-panel.jsx
index 989168288..b2d0ec18d 100644
--- a/src/packages/modules-codelists/components/codelist-detail/codes-panel.jsx
+++ b/src/packages/modules-codelists/components/codelist-detail/codes-panel.jsx
@@ -16,7 +16,7 @@ import { validateCode } from '../../utils';
import { CollapsiblePanel } from '../collapsible-panel';
import { CodeSlidingPanelMenu } from './code-sliding-panel-menu';
import { CodesPanelAddButton } from './codes-panel-add-button';
-import './codes-panel.scss';
+import './codes-panel.css';
import { Table } from './codes/table';
const CodeSlidingPanel = ({