diff --git a/packages/module/src/ColumnManagementModal/ColumnManagementModal.test.tsx b/packages/module/src/ColumnManagementModal/ColumnManagementModal.test.tsx
index 7ec26827..a23ec2dc 100644
--- a/packages/module/src/ColumnManagementModal/ColumnManagementModal.test.tsx
+++ b/packages/module/src/ColumnManagementModal/ColumnManagementModal.test.tsx
@@ -1,9 +1,9 @@
-import '@testing-library/jest-dom'
-import { render, screen, fireEvent } from '@testing-library/react';
+import '@testing-library/jest-dom';
+import { render, screen, fireEvent, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import ColumnManagementModal, { ColumnManagementModalColumn } from './ColumnManagementModal';
-const DEFAULT_COLUMNS : ColumnManagementModalColumn[] = [
+const DEFAULT_COLUMNS: ColumnManagementModalColumn[] = [
{
title: 'ID',
key: 'id',
@@ -31,23 +31,35 @@ const DEFAULT_COLUMNS : ColumnManagementModalColumn[] = [
}
];
+interface ExtendedColumn extends ColumnManagementModalColumn {
+ dataKey: string;
+}
+
+const EXTENDED_COLUMNS: ExtendedColumn[] = DEFAULT_COLUMNS.map((col) => ({
+ ...col,
+ dataKey: `row.${col.key}`
+}));
+
const onClose = jest.fn();
const setColumns = jest.fn();
// Simple mock to track when DragDropSort is used
jest.mock('@patternfly/react-drag-drop', () => ({
DragDropSort: ({ children }) =>
{children}
,
- Droppable: ({ wrapper }) => wrapper,
+ Droppable: ({ wrapper }) => wrapper
}));
-const renderColumnManagementModal = (props = {}) => render( setColumns(newColumns)}
- isOpen
- onClose={onClose}
- data-testid="column-mgmt-modal"
- {...props}
-/>);
+const renderColumnManagementModal = (props = {}) =>
+ render(
+ setColumns(newColumns)}
+ isOpen
+ onClose={onClose}
+ data-testid="column-mgmt-modal"
+ {...props}
+ />
+ );
beforeEach(() => {
jest.clearAllMocks();
@@ -56,17 +68,21 @@ beforeEach(() => {
const getCheckboxesState = () => {
// Get only the column checkboxes (exclude the BulkSelect checkbox)
- const checkboxes = screen.getByTestId('column-mgmt-modal').querySelectorAll('input[type="checkbox"][data-testid^="column-check-"]');
- return (Array.from(checkboxes) as HTMLInputElement[]).map(c => c.checked);
-}
+ const checkboxes = screen
+ .getByTestId('column-mgmt-modal')
+ .querySelectorAll('input[type="checkbox"][data-testid^="column-check-"]');
+ return (Array.from(checkboxes) as HTMLInputElement[]).map((c) => c.checked);
+};
describe('ColumnManagementModal component', () => {
it('should have disabled and checked checkboxes for columns that should always be shown', () => {
- expect(getCheckboxesState()).toEqual(DEFAULT_COLUMNS.map(c => c.isShownByDefault));
+ expect(getCheckboxesState()).toEqual(DEFAULT_COLUMNS.map((c) => c.isShownByDefault));
});
it('should have checkbox checked if column is shown by default', () => {
- const idCheckbox = screen.getByTestId('column-mgmt-modal').querySelector('input[type="checkbox"][data-testid="column-check-id"]');
+ const idCheckbox = screen
+ .getByTestId('column-mgmt-modal')
+ .querySelector('input[type="checkbox"][data-testid="column-check-id"]');
expect(idCheckbox).toHaveAttribute('disabled');
expect(idCheckbox).toHaveAttribute('checked');
@@ -81,18 +97,20 @@ describe('ColumnManagementModal component', () => {
fireEvent.click(screen.getByText('Reset to default'));
- expect(getCheckboxesState()).toEqual(DEFAULT_COLUMNS.map(c => c.isShownByDefault));
+ expect(getCheckboxesState()).toEqual(DEFAULT_COLUMNS.map((c) => c.isShownByDefault));
});
it('should call onReset callback when reset to default is clicked', () => {
const onResetMock = jest.fn();
- render();
+ render(
+
+ );
const resetButtons = screen.getAllByText('Reset to default');
// Click the last one rendered (the new modal)
@@ -103,13 +121,15 @@ describe('ColumnManagementModal component', () => {
it('should display custom reset button label', () => {
const customLabel = 'Restaurer par défaut';
- render();
+ render(
+
+ );
expect(screen.getByText(customLabel)).toBeInTheDocument();
});
@@ -124,7 +144,7 @@ describe('ColumnManagementModal component', () => {
const selectAllButton = screen.getByText('Select all (4)');
await userEvent.click(selectAllButton);
- expect(getCheckboxesState()).toEqual(DEFAULT_COLUMNS.map(_ => true));
+ expect(getCheckboxesState()).toEqual(DEFAULT_COLUMNS.map((_) => true));
});
it('should change columns on save', () => {
@@ -132,7 +152,7 @@ describe('ColumnManagementModal component', () => {
fireEvent.click(screen.getByText('Save'));
const expectedColumns = DEFAULT_COLUMNS;
- const impactColumn = expectedColumns.find(c => c.title === 'Impact');
+ const impactColumn = expectedColumns.find((c) => c.title === 'Impact');
if (impactColumn === undefined) {
throw new Error('Expected to find "Impact" column in "DEFAULT_COLUMNS"');
@@ -153,6 +173,35 @@ describe('ColumnManagementModal component', () => {
expect(setColumns).not.toHaveBeenCalled();
});
+ it('should preserve extended column fields when saving', () => {
+ const applyColumnsMock = jest.fn();
+ render(
+
+ appliedColumns={EXTENDED_COLUMNS}
+ applyColumns={applyColumnsMock}
+ isOpen
+ onClose={onClose}
+ data-testid="extended-column-modal"
+ />
+ );
+
+ const modal = screen.getByTestId('extended-column-modal');
+ fireEvent.click(within(modal).getByTestId('column-check-impact'));
+ fireEvent.click(within(modal).getByRole('button', { name: 'Save' }));
+
+ expect(applyColumnsMock).toHaveBeenCalledTimes(1);
+ const saved = applyColumnsMock.mock.calls[0][0] as ExtendedColumn[];
+
+ // Test that we have same number of columns
+ expect(saved).toHaveLength(EXTENDED_COLUMNS.length);
+
+ // Test that extension keys were preserved
+ saved.forEach((col) => {
+ const source = EXTENDED_COLUMNS.find((aec) => aec.key === col.key);
+ expect(source?.dataKey).toBe(col.dataKey);
+ });
+ });
+
describe('enableDragDrop prop', () => {
it('should default enableDragDrop to false', () => {
// Default behavior should not enable drag and drop
@@ -175,16 +224,18 @@ describe('ColumnManagementModal component', () => {
DEFAULT_COLUMNS[3], // Score (last -> first)
DEFAULT_COLUMNS[0], // ID
DEFAULT_COLUMNS[2], // Impact
- DEFAULT_COLUMNS[1], // Publish date
+ DEFAULT_COLUMNS[1] // Publish date
];
const applyColumnsMock = jest.fn();
- render();
+ render(
+
+ );
// Click reset to default - get all buttons and click the last one
const resetButtons = screen.getAllByText('Reset to default');
@@ -197,7 +248,7 @@ describe('ColumnManagementModal component', () => {
// Verify that the saved columns match the original reordered columns order
// (after reset, it should restore the order from appliedColumns which is reorderedColumns)
expect(applyColumnsMock).toHaveBeenCalledWith(
- reorderedColumns.map(col => ({
+ reorderedColumns.map((col) => ({
...col,
isShown: col.isShownByDefault
}))
diff --git a/packages/module/src/ColumnManagementModal/ColumnManagementModal.tsx b/packages/module/src/ColumnManagementModal/ColumnManagementModal.tsx
index 006cb6c3..fa6a1606 100644
--- a/packages/module/src/ColumnManagementModal/ColumnManagementModal.tsx
+++ b/packages/module/src/ColumnManagementModal/ColumnManagementModal.tsx
@@ -1,11 +1,5 @@
-import type { FunctionComponent } from 'react';
import { useState, useEffect } from 'react';
-import {
- Button,
- Content,
- ContentVariants,
- ButtonVariant,
-} from '@patternfly/react-core';
+import { Button, Content, ContentVariants, ButtonVariant } from '@patternfly/react-core';
import { ModalProps, Modal, ModalVariant } from '@patternfly/react-core/deprecated';
import ListManager, { ListManagerItem } from '../ListManager/ListManager';
@@ -23,15 +17,16 @@ export interface ColumnManagementModalColumn {
}
/** extends ModalProps */
-export interface ColumnManagementModalProps extends Omit {
+export interface ColumnManagementModalProps
+ extends Omit {
/** Flag to show the modal */
isOpen?: boolean;
/** Invoked when modal visibility is changed */
onClose?: (event: KeyboardEvent | React.MouseEvent) => void;
/** Current column state */
- appliedColumns: ColumnManagementModalColumn[];
+ appliedColumns: T[];
/** Invoked with new column state after save button is clicked */
- applyColumns: (newColumns: ColumnManagementModalColumn[]) => void;
+ applyColumns: (newColumns: T[]) => void;
/* Modal description text */
description?: string;
/* Modal title text */
@@ -46,30 +41,32 @@ export interface ColumnManagementModalProps extends Omit = (
- { title = 'Manage columns',
- description = 'Selected categories will be displayed in the table.',
- isOpen = false,
- onClose = () => undefined,
- appliedColumns,
- applyColumns,
- ouiaId = 'ColumnManagementModal',
- enableDragDrop = false,
- onReset,
- resetToDefaultLabel = 'Reset to default',
- ...props }: ColumnManagementModalProps) => {
-
- const [ currentColumns, setCurrentColumns ] = useState(() =>
- appliedColumns.map(column => ({ ...column, isShown: column.isShown ?? column.isShownByDefault }))
+const ColumnManagementModal = ({
+ title = 'Manage columns',
+ description = 'Selected categories will be displayed in the table.',
+ isOpen = false,
+ onClose = () => undefined,
+ appliedColumns,
+ applyColumns,
+ ouiaId = 'ColumnManagementModal',
+ enableDragDrop = false,
+ onReset,
+ resetToDefaultLabel = 'Reset to default',
+ ...props
+}: ColumnManagementModalProps) => {
+ const [ currentColumns, setCurrentColumns ] = useState(() =>
+ appliedColumns.map((column) => ({ ...column, isShown: column.isShown ?? column.isShownByDefault }))
);
// Sync with appliedColumns when they change
useEffect(() => {
- setCurrentColumns(appliedColumns.map(column => ({ ...column, isShown: column.isShown ?? column.isShownByDefault })));
+ setCurrentColumns(
+ appliedColumns.map((column) => ({ ...column, isShown: column.isShown ?? column.isShownByDefault }))
+ );
}, [ appliedColumns ]);
// Convert ColumnManagementModalColumn to ListManagerItem
- const listManagerItems: ListManagerItem[] = currentColumns.map(column => ({
+ const listManagerItems: ListManagerItem[] = currentColumns.map((column) => ({
key: column.key,
title: column.title,
isSelected: column.isShown,
@@ -79,16 +76,14 @@ const ColumnManagementModal: FunctionComponent = (
const resetToDefault = () => {
// Reset both visibility and order to match the original appliedColumns
- setCurrentColumns(appliedColumns.map(column => ({ ...column, isShown: column.isShownByDefault ?? false })));
+ setCurrentColumns(appliedColumns.map((column) => ({ ...column, isShown: column.isShownByDefault ?? false })));
onReset?.();
};
const updateColumns = (items: ListManagerItem[]) => {
- const newColumns = currentColumns.map(column => {
- const matchingItem = items.find(item => item.key === column.key);
- return matchingItem
- ? { ...column, isShown: matchingItem.isSelected ?? column.isShownByDefault }
- : column;
+ const newColumns = currentColumns.map((column) => {
+ const matchingItem = items.find((item) => item.key === column.key);
+ return matchingItem ? { ...column, isShown: matchingItem.isSelected ?? column.isShownByDefault } : column;
});
setCurrentColumns(newColumns);
};
@@ -103,8 +98,8 @@ const ColumnManagementModal: FunctionComponent = (
const handleOrderChange = (items: ListManagerItem[]) => {
// Update the order of currentColumns based on the new order from ListManager
- const newColumns = items.map(item => {
- const originalColumn = currentColumns.find(col => col.key === item.key);
+ const newColumns = items.map((item) => {
+ const originalColumn = currentColumns.find((col) => col.key === item.key);
if (!originalColumn) {
throw new Error(`Column with key ${item.key} not found`);
}
@@ -114,13 +109,13 @@ const ColumnManagementModal: FunctionComponent = (
};
const handleSave = (items: ListManagerItem[]) => {
- const updatedColumns = items.map(item => ({
- key: item.key,
- title: item.title,
- isShown: item.isSelected,
- isShownByDefault: item.isShownByDefault,
- isUntoggleable: item.isUntoggleable
- }));
+ const updatedColumns = items.map((item) => {
+ const originalColumn = currentColumns.find((col) => col.key === item.key);
+ if (!originalColumn) {
+ throw new Error(`Column with key ${item.key} not found`);
+ }
+ return { ...originalColumn, isShown: item.isSelected };
+ });
applyColumns(updatedColumns);
onClose({} as KeyboardEvent);
};
@@ -158,6 +153,6 @@ const ColumnManagementModal: FunctionComponent = (
/>
);
-}
+};
export default ColumnManagementModal;