mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-05 15:48:03 +00:00
* fix the table column selection not persisting for all action in dropdown * added playwright test for the test * move the utils changes to the component itself * updated the code as the setter was not needed * modify state name and remove unnecessary conditions
This commit is contained in:
parent
5989df394d
commit
3e17b85f2e
@ -1262,6 +1262,10 @@ test.describe('Glossary tests', () => {
|
|||||||
const checkboxLabels = ['Reviewer', 'Synonyms'];
|
const checkboxLabels = ['Reviewer', 'Synonyms'];
|
||||||
await selectColumns(page, checkboxLabels);
|
await selectColumns(page, checkboxLabels);
|
||||||
await verifyColumnsVisibility(page, checkboxLabels, true);
|
await verifyColumnsVisibility(page, checkboxLabels, true);
|
||||||
|
|
||||||
|
await page.reload();
|
||||||
|
await page.waitForLoadState('networkidle');
|
||||||
|
await verifyColumnsVisibility(page, checkboxLabels, true);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1272,6 +1276,10 @@ test.describe('Glossary tests', () => {
|
|||||||
const checkboxLabels = ['Reviewer', 'Owners'];
|
const checkboxLabels = ['Reviewer', 'Owners'];
|
||||||
await deselectColumns(page, checkboxLabels);
|
await deselectColumns(page, checkboxLabels);
|
||||||
await verifyColumnsVisibility(page, checkboxLabels, false);
|
await verifyColumnsVisibility(page, checkboxLabels, false);
|
||||||
|
|
||||||
|
await page.reload();
|
||||||
|
await page.waitForLoadState('networkidle');
|
||||||
|
await verifyColumnsVisibility(page, checkboxLabels, false);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1287,6 +1295,10 @@ test.describe('Glossary tests', () => {
|
|||||||
'ACTIONS',
|
'ACTIONS',
|
||||||
];
|
];
|
||||||
await verifyAllColumns(page, tableColumns, true);
|
await verifyAllColumns(page, tableColumns, true);
|
||||||
|
|
||||||
|
await page.reload();
|
||||||
|
await page.waitForLoadState('networkidle');
|
||||||
|
await verifyAllColumns(page, tableColumns, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('Hide All columns selection', async () => {
|
await test.step('Hide All columns selection', async () => {
|
||||||
@ -1299,6 +1311,10 @@ test.describe('Glossary tests', () => {
|
|||||||
'STATUS',
|
'STATUS',
|
||||||
];
|
];
|
||||||
await verifyAllColumns(page, tableColumns, false);
|
await verifyAllColumns(page, tableColumns, false);
|
||||||
|
|
||||||
|
await page.reload();
|
||||||
|
await page.waitForLoadState('networkidle');
|
||||||
|
await verifyAllColumns(page, tableColumns, false);
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
await glossaryTerm1.delete(apiContext);
|
await glossaryTerm1.delete(apiContext);
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { render, screen } from '@testing-library/react';
|
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||||
import { DndProvider } from 'react-dnd';
|
import { DndProvider } from 'react-dnd';
|
||||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||||
import { getCustomizeColumnDetails } from '../../../utils/CustomizeColumnUtils';
|
import { getCustomizeColumnDetails } from '../../../utils/CustomizeColumnUtils';
|
||||||
@ -25,10 +25,50 @@ jest.mock('../../../utils/CustomizeColumnUtils', () => ({
|
|||||||
getReorderedColumns: jest.fn().mockImplementation((_, columns) => columns),
|
getReorderedColumns: jest.fn().mockImplementation((_, columns) => columns),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock('../../../utils/TableUtils', () => ({
|
||||||
|
getTableExpandableConfig: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
jest.mock('../SearchBarComponent/SearchBar.component', () =>
|
jest.mock('../SearchBarComponent/SearchBar.component', () =>
|
||||||
jest.fn().mockImplementation(() => <div>SearchBar</div>)
|
jest.fn().mockImplementation(() => <div>SearchBar</div>)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Mock DraggableMenuItem component
|
||||||
|
jest.mock('./DraggableMenu/DraggableMenuItem.component', () =>
|
||||||
|
jest.fn().mockImplementation(({ currentItem, selectedOptions, onSelect }) => (
|
||||||
|
<div key={currentItem.value}>
|
||||||
|
<input
|
||||||
|
checked={selectedOptions.includes(currentItem.value)}
|
||||||
|
data-testid={`column-checkbox-${currentItem.value}`}
|
||||||
|
type="checkbox"
|
||||||
|
onChange={(e) => onSelect(currentItem.value, e.target.checked)}
|
||||||
|
/>
|
||||||
|
<label>{currentItem.label}</label>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mock hooks
|
||||||
|
const mockSetPreference = jest.fn();
|
||||||
|
const mockUseCurrentUserPreferences = {
|
||||||
|
preferences: {
|
||||||
|
selectedEntityTableColumns: {},
|
||||||
|
},
|
||||||
|
setPreference: mockSetPreference,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockUseGenericContext = {
|
||||||
|
type: 'table',
|
||||||
|
};
|
||||||
|
|
||||||
|
jest.mock('../../../hooks/currentUserStore/useCurrentUserStore', () => ({
|
||||||
|
useCurrentUserPreferences: jest.fn(() => mockUseCurrentUserPreferences),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('../../Customization/GenericProvider/GenericProvider', () => ({
|
||||||
|
useGenericContext: jest.fn(() => mockUseGenericContext),
|
||||||
|
}));
|
||||||
|
|
||||||
const mockColumns = [
|
const mockColumns = [
|
||||||
{
|
{
|
||||||
title: 'Column 1',
|
title: 'Column 1',
|
||||||
@ -40,11 +80,16 @@ const mockColumns = [
|
|||||||
dataIndex: 'col2',
|
dataIndex: 'col2',
|
||||||
key: 'col2',
|
key: 'col2',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'Column 3',
|
||||||
|
dataIndex: 'col3',
|
||||||
|
key: 'col3',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const mockData = [
|
const mockData = [
|
||||||
{ col1: 'Value 1', col2: 'Value 2' },
|
{ col1: 'Value 1', col2: 'Value 2', col3: 'Value 3' },
|
||||||
{ col1: 'Value 3', col2: 'Value 4' },
|
{ col1: 'Value 4', col2: 'Value 5', col3: 'Value 6' },
|
||||||
];
|
];
|
||||||
|
|
||||||
describe('Table component', () => {
|
describe('Table component', () => {
|
||||||
@ -56,6 +101,11 @@ describe('Table component', () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
mockUseCurrentUserPreferences.preferences.selectedEntityTableColumns = {};
|
||||||
|
});
|
||||||
|
|
||||||
it('should display skeleton loader if loading is true', async () => {
|
it('should display skeleton loader if loading is true', async () => {
|
||||||
renderComponent({ loading: true });
|
renderComponent({ loading: true });
|
||||||
|
|
||||||
@ -105,4 +155,317 @@ describe('Table component', () => {
|
|||||||
|
|
||||||
expect(screen.getByTestId('table-filters')).toBeInTheDocument();
|
expect(screen.getByTestId('table-filters')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Column Selection Functionality', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
(getCustomizeColumnDetails as jest.Mock).mockReturnValue([
|
||||||
|
{ label: 'Column 1', value: 'col1' },
|
||||||
|
{ label: 'Column 2', value: 'col2' },
|
||||||
|
{ label: 'Column 3', value: 'col3' },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should initialize column selections from existing user preferences', () => {
|
||||||
|
mockUseCurrentUserPreferences.preferences.selectedEntityTableColumns = {
|
||||||
|
table: ['col1', 'col2'],
|
||||||
|
};
|
||||||
|
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2', 'col3'],
|
||||||
|
entityType: 'table',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Component should use existing preferences
|
||||||
|
expect(mockSetPreference).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use default columns when no existing preferences and customization is enabled', () => {
|
||||||
|
mockUseCurrentUserPreferences.preferences.selectedEntityTableColumns = {};
|
||||||
|
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2', 'col3'],
|
||||||
|
entityType: 'table',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Component should not automatically set preferences
|
||||||
|
expect(mockSetPreference).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should require both static and default columns for customization', () => {
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2'],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.getByTestId('column-dropdown')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not render column dropdown when only staticVisibleColumns is provided', () => {
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.queryByTestId('column-dropdown')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not render column dropdown when only defaultVisibleColumns is provided', () => {
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: undefined,
|
||||||
|
defaultVisibleColumns: ['col2'],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.queryByTestId('column-dropdown')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not render column dropdown when both static and default columns are empty', () => {
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: undefined,
|
||||||
|
defaultVisibleColumns: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.queryByTestId('column-dropdown')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not enable customization when no static or default columns are provided', () => {
|
||||||
|
renderComponent();
|
||||||
|
|
||||||
|
expect(screen.queryByTestId('column-dropdown')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should open column dropdown and show column options', async () => {
|
||||||
|
mockUseCurrentUserPreferences.preferences.selectedEntityTableColumns = {
|
||||||
|
table: ['col1', 'col2'],
|
||||||
|
};
|
||||||
|
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2'],
|
||||||
|
});
|
||||||
|
|
||||||
|
const columnDropdown = screen.getByTestId('column-dropdown');
|
||||||
|
fireEvent.click(columnDropdown);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByTestId('column-dropdown-title')).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('label.column')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle column selection when checkbox is clicked', async () => {
|
||||||
|
mockUseCurrentUserPreferences.preferences.selectedEntityTableColumns = {
|
||||||
|
table: ['col1', 'col2'],
|
||||||
|
};
|
||||||
|
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2'],
|
||||||
|
entityType: 'table',
|
||||||
|
});
|
||||||
|
|
||||||
|
const columnDropdown = screen.getByTestId('column-dropdown');
|
||||||
|
fireEvent.click(columnDropdown);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByTestId('column-checkbox-col2')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
const checkbox = screen.getByTestId('column-checkbox-col2');
|
||||||
|
fireEvent.click(checkbox);
|
||||||
|
|
||||||
|
// Verify that preferences are updated
|
||||||
|
expect(mockSetPreference).toHaveBeenCalledWith({
|
||||||
|
selectedEntityTableColumns: {
|
||||||
|
table: ['col1'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle column addition when unchecked checkbox is clicked', async () => {
|
||||||
|
mockUseCurrentUserPreferences.preferences.selectedEntityTableColumns = {
|
||||||
|
table: ['col1'],
|
||||||
|
};
|
||||||
|
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2', 'col3'],
|
||||||
|
entityType: 'table',
|
||||||
|
});
|
||||||
|
|
||||||
|
const columnDropdown = screen.getByTestId('column-dropdown');
|
||||||
|
fireEvent.click(columnDropdown);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByTestId('column-checkbox-col3')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
const checkbox = screen.getByTestId('column-checkbox-col3');
|
||||||
|
fireEvent.click(checkbox);
|
||||||
|
|
||||||
|
expect(mockSetPreference).toHaveBeenCalledWith({
|
||||||
|
selectedEntityTableColumns: {
|
||||||
|
table: ['col1', 'col3'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show "View All" button when not all columns are selected', async () => {
|
||||||
|
mockUseCurrentUserPreferences.preferences.selectedEntityTableColumns = {
|
||||||
|
table: ['col1'],
|
||||||
|
};
|
||||||
|
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2'],
|
||||||
|
});
|
||||||
|
|
||||||
|
const columnDropdown = screen.getByTestId('column-dropdown');
|
||||||
|
fireEvent.click(columnDropdown);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(
|
||||||
|
screen.getByTestId('column-dropdown-action-button')
|
||||||
|
).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('label.view-all')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show "Hide All" button when all columns are selected', async () => {
|
||||||
|
mockUseCurrentUserPreferences.preferences.selectedEntityTableColumns = {
|
||||||
|
table: ['col1', 'col2', 'col3'],
|
||||||
|
};
|
||||||
|
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2'],
|
||||||
|
});
|
||||||
|
|
||||||
|
const columnDropdown = screen.getByTestId('column-dropdown');
|
||||||
|
fireEvent.click(columnDropdown);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(
|
||||||
|
screen.getByTestId('column-dropdown-action-button')
|
||||||
|
).toBeInTheDocument();
|
||||||
|
expect(screen.getByText('label.hide-all')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select all columns when "View All" button is clicked', async () => {
|
||||||
|
mockUseCurrentUserPreferences.preferences.selectedEntityTableColumns = {
|
||||||
|
table: ['col1'],
|
||||||
|
};
|
||||||
|
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2'],
|
||||||
|
entityType: 'table',
|
||||||
|
});
|
||||||
|
|
||||||
|
const columnDropdown = screen.getByTestId('column-dropdown');
|
||||||
|
fireEvent.click(columnDropdown);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(
|
||||||
|
screen.getByTestId('column-dropdown-action-button')
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
const viewAllButton = screen.getByTestId('column-dropdown-action-button');
|
||||||
|
fireEvent.click(viewAllButton);
|
||||||
|
|
||||||
|
expect(mockSetPreference).toHaveBeenCalledWith({
|
||||||
|
selectedEntityTableColumns: {
|
||||||
|
table: ['col1', 'col2', 'col3'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should deselect all columns when "Hide All" button is clicked', async () => {
|
||||||
|
mockUseCurrentUserPreferences.preferences.selectedEntityTableColumns = {
|
||||||
|
table: ['col1', 'col2', 'col3'],
|
||||||
|
};
|
||||||
|
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2'],
|
||||||
|
entityType: 'table',
|
||||||
|
});
|
||||||
|
|
||||||
|
const columnDropdown = screen.getByTestId('column-dropdown');
|
||||||
|
fireEvent.click(columnDropdown);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(
|
||||||
|
screen.getByTestId('column-dropdown-action-button')
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
const hideAllButton = screen.getByTestId('column-dropdown-action-button');
|
||||||
|
fireEvent.click(hideAllButton);
|
||||||
|
|
||||||
|
expect(mockSetPreference).toHaveBeenCalledWith({
|
||||||
|
selectedEntityTableColumns: {
|
||||||
|
table: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should preserve existing preferences for other entity types', async () => {
|
||||||
|
mockUseCurrentUserPreferences.preferences.selectedEntityTableColumns = {
|
||||||
|
dashboard: ['dash1', 'dash2'],
|
||||||
|
table: ['col1'],
|
||||||
|
};
|
||||||
|
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2'],
|
||||||
|
entityType: 'table',
|
||||||
|
});
|
||||||
|
|
||||||
|
const columnDropdown = screen.getByTestId('column-dropdown');
|
||||||
|
fireEvent.click(columnDropdown);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(
|
||||||
|
screen.getByTestId('column-dropdown-action-button')
|
||||||
|
).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
const viewAllButton = screen.getByTestId('column-dropdown-action-button');
|
||||||
|
fireEvent.click(viewAllButton);
|
||||||
|
|
||||||
|
expect(mockSetPreference).toHaveBeenCalledWith({
|
||||||
|
selectedEntityTableColumns: {
|
||||||
|
dashboard: ['dash1', 'dash2'],
|
||||||
|
table: ['col1', 'col2', 'col3'],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render search bar when searchProps are provided', () => {
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: ['col1'],
|
||||||
|
defaultVisibleColumns: ['col2'],
|
||||||
|
searchProps: {
|
||||||
|
placeholder: 'Search columns',
|
||||||
|
value: 'test',
|
||||||
|
onSearch: jest.fn(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.getByText('SearchBar')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not render column dropdown in full view mode', () => {
|
||||||
|
renderComponent({
|
||||||
|
staticVisibleColumns: undefined,
|
||||||
|
defaultVisibleColumns: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(screen.queryByTestId('column-dropdown')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -37,16 +37,12 @@ import { DndProvider } from 'react-dnd';
|
|||||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { ReactComponent as ColumnIcon } from '../../../assets/svg/ic-column.svg';
|
import { ReactComponent as ColumnIcon } from '../../../assets/svg/ic-column.svg';
|
||||||
import { useApplicationStore } from '../../../hooks/useApplicationStore';
|
import { useCurrentUserPreferences } from '../../../hooks/currentUserStore/useCurrentUserStore';
|
||||||
import {
|
import {
|
||||||
getCustomizeColumnDetails,
|
getCustomizeColumnDetails,
|
||||||
getReorderedColumns,
|
getReorderedColumns,
|
||||||
} from '../../../utils/CustomizeColumnUtils';
|
} from '../../../utils/CustomizeColumnUtils';
|
||||||
import {
|
import { getTableExpandableConfig } from '../../../utils/TableUtils';
|
||||||
getTableColumnConfigSelections,
|
|
||||||
getTableExpandableConfig,
|
|
||||||
handleUpdateTableColumnSelections,
|
|
||||||
} from '../../../utils/TableUtils';
|
|
||||||
import { useGenericContext } from '../../Customization/GenericProvider/GenericProvider';
|
import { useGenericContext } from '../../Customization/GenericProvider/GenericProvider';
|
||||||
import Loader from '../Loader/Loader';
|
import Loader from '../Loader/Loader';
|
||||||
import NextPrevious from '../NextPrevious/NextPrevious';
|
import NextPrevious from '../NextPrevious/NextPrevious';
|
||||||
@ -73,7 +69,6 @@ const Table = <T extends Record<string, unknown>>(
|
|||||||
) => {
|
) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { type } = useGenericContext();
|
const { type } = useGenericContext();
|
||||||
const { currentUser } = useApplicationStore();
|
|
||||||
const [propsColumns, setPropsColumns] = useState<ColumnsType<T>>([]);
|
const [propsColumns, setPropsColumns] = useState<ColumnsType<T>>([]);
|
||||||
const [isDropdownVisible, setIsDropdownVisible] = useState<boolean>(false);
|
const [isDropdownVisible, setIsDropdownVisible] = useState<boolean>(false);
|
||||||
const [dropdownColumnList, setDropdownColumnList] = useState<
|
const [dropdownColumnList, setDropdownColumnList] = useState<
|
||||||
@ -86,6 +81,10 @@ const Table = <T extends Record<string, unknown>>(
|
|||||||
() => ({ columns: propsColumns as Column[], minWidth: 80 }),
|
() => ({ columns: propsColumns as Column[], minWidth: 80 }),
|
||||||
[propsColumns]
|
[propsColumns]
|
||||||
);
|
);
|
||||||
|
const {
|
||||||
|
preferences: { selectedEntityTableColumns },
|
||||||
|
setPreference,
|
||||||
|
} = useCurrentUserPreferences();
|
||||||
|
|
||||||
const isLoading = useMemo(
|
const isLoading = useMemo(
|
||||||
() => (loading as SpinProps)?.spinning ?? (loading as boolean) ?? false,
|
() => (loading as SpinProps)?.spinning ?? (loading as boolean) ?? false,
|
||||||
@ -94,9 +93,10 @@ const Table = <T extends Record<string, unknown>>(
|
|||||||
|
|
||||||
const entityKey = useMemo(() => entityType ?? type, [type, entityType]);
|
const entityKey = useMemo(() => entityType ?? type, [type, entityType]);
|
||||||
|
|
||||||
// Check if the table is in Full View mode, if so, the dropdown and Customize Column feature is not available
|
// Check if the table is customizable, if so, the dropdown and Customize Column feature is available
|
||||||
const isFullViewTable = useMemo(
|
const isCustomizeColumnEnable = useMemo(
|
||||||
() => isEmpty(rest.staticVisibleColumns) && isEmpty(defaultVisibleColumns),
|
() =>
|
||||||
|
!isEmpty(rest.staticVisibleColumns) && !isEmpty(defaultVisibleColumns),
|
||||||
[rest.staticVisibleColumns, defaultVisibleColumns]
|
[rest.staticVisibleColumns, defaultVisibleColumns]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -110,28 +110,47 @@ const Table = <T extends Record<string, unknown>>(
|
|||||||
|
|
||||||
const handleColumnItemSelect = useCallback(
|
const handleColumnItemSelect = useCallback(
|
||||||
(key: string, selected: boolean) => {
|
(key: string, selected: boolean) => {
|
||||||
const updatedSelections = handleUpdateTableColumnSelections(
|
const updatedSelections = selected
|
||||||
selected,
|
? [...columnDropdownSelections, key]
|
||||||
key,
|
: columnDropdownSelections.filter((item) => item !== key);
|
||||||
columnDropdownSelections,
|
|
||||||
currentUser?.fullyQualifiedName ?? '',
|
setPreference({
|
||||||
entityKey
|
selectedEntityTableColumns: {
|
||||||
);
|
...selectedEntityTableColumns,
|
||||||
|
[entityKey]: updatedSelections,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
setColumnDropdownSelections(updatedSelections);
|
setColumnDropdownSelections(updatedSelections);
|
||||||
},
|
},
|
||||||
[columnDropdownSelections, entityKey]
|
[columnDropdownSelections, selectedEntityTableColumns, entityKey]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleBulkColumnAction = useCallback(() => {
|
const handleBulkColumnAction = useCallback(() => {
|
||||||
if (dropdownColumnList.length === columnDropdownSelections.length) {
|
if (dropdownColumnList.length === columnDropdownSelections.length) {
|
||||||
setColumnDropdownSelections([]);
|
setColumnDropdownSelections([]);
|
||||||
|
setPreference({
|
||||||
|
selectedEntityTableColumns: {
|
||||||
|
...selectedEntityTableColumns,
|
||||||
|
[entityKey]: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
setColumnDropdownSelections(
|
const columns = dropdownColumnList.map((option) => option.value);
|
||||||
dropdownColumnList.map((option) => option.value)
|
setColumnDropdownSelections(columns);
|
||||||
);
|
setPreference({
|
||||||
|
selectedEntityTableColumns: {
|
||||||
|
...selectedEntityTableColumns,
|
||||||
|
[entityKey]: columns,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, [dropdownColumnList, columnDropdownSelections]);
|
}, [
|
||||||
|
dropdownColumnList,
|
||||||
|
columnDropdownSelections,
|
||||||
|
selectedEntityTableColumns,
|
||||||
|
entityKey,
|
||||||
|
]);
|
||||||
|
|
||||||
const menu = useMemo(
|
const menu = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
@ -203,15 +222,15 @@ const Table = <T extends Record<string, unknown>>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isFullViewTable) {
|
if (isCustomizeColumnEnable) {
|
||||||
setDropdownColumnList(
|
setDropdownColumnList(
|
||||||
getCustomizeColumnDetails<T>(rest.columns, rest.staticVisibleColumns)
|
getCustomizeColumnDetails<T>(rest.columns, rest.staticVisibleColumns)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [isFullViewTable, rest.columns, rest.staticVisibleColumns]);
|
}, [isCustomizeColumnEnable, rest.columns, rest.staticVisibleColumns]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isFullViewTable) {
|
if (!isCustomizeColumnEnable) {
|
||||||
setPropsColumns(rest.columns ?? []);
|
setPropsColumns(rest.columns ?? []);
|
||||||
} else {
|
} else {
|
||||||
const filteredColumns = (rest.columns ?? []).filter(
|
const filteredColumns = (rest.columns ?? []).filter(
|
||||||
@ -223,28 +242,31 @@ const Table = <T extends Record<string, unknown>>(
|
|||||||
setPropsColumns(getReorderedColumns(dropdownColumnList, filteredColumns));
|
setPropsColumns(getReorderedColumns(dropdownColumnList, filteredColumns));
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
isFullViewTable,
|
isCustomizeColumnEnable,
|
||||||
rest.columns,
|
rest.columns,
|
||||||
columnDropdownSelections,
|
columnDropdownSelections,
|
||||||
rest.staticVisibleColumns,
|
rest.staticVisibleColumns,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const selections = getTableColumnConfigSelections(
|
if (isCustomizeColumnEnable) {
|
||||||
currentUser?.fullyQualifiedName ?? '',
|
setColumnDropdownSelections(
|
||||||
entityKey,
|
selectedEntityTableColumns?.[entityKey] ?? defaultVisibleColumns ?? []
|
||||||
isFullViewTable,
|
);
|
||||||
defaultVisibleColumns
|
}
|
||||||
);
|
}, [
|
||||||
|
isCustomizeColumnEnable,
|
||||||
setColumnDropdownSelections(selections);
|
selectedEntityTableColumns,
|
||||||
}, [entityKey, defaultVisibleColumns, isFullViewTable]);
|
entityKey,
|
||||||
|
defaultVisibleColumns,
|
||||||
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row className={classNames('table-container', rest.containerClassName)}>
|
<Row className={classNames('table-container', rest.containerClassName)}>
|
||||||
<Col
|
<Col
|
||||||
className={classNames({
|
className={classNames({
|
||||||
'p-y-md': searchProps ?? rest.extraTableFilters ?? !isFullViewTable,
|
'p-y-md':
|
||||||
|
searchProps ?? rest.extraTableFilters ?? isCustomizeColumnEnable,
|
||||||
})}
|
})}
|
||||||
span={24}>
|
span={24}>
|
||||||
<Row className="p-x-md">
|
<Row className="p-x-md">
|
||||||
@ -260,7 +282,7 @@ const Table = <T extends Record<string, unknown>>(
|
|||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
) : null}
|
) : null}
|
||||||
{(rest.extraTableFilters || !isFullViewTable) && (
|
{(rest.extraTableFilters || isCustomizeColumnEnable) && (
|
||||||
<Col
|
<Col
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'd-flex justify-end items-center gap-5',
|
'd-flex justify-end items-center gap-5',
|
||||||
@ -268,7 +290,7 @@ const Table = <T extends Record<string, unknown>>(
|
|||||||
)}
|
)}
|
||||||
span={searchProps ? 12 : 24}>
|
span={searchProps ? 12 : 24}>
|
||||||
{rest.extraTableFilters}
|
{rest.extraTableFilters}
|
||||||
{!isFullViewTable && (
|
{isCustomizeColumnEnable && (
|
||||||
<DndProvider backend={HTML5Backend}>
|
<DndProvider backend={HTML5Backend}>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
className="custom-column-dropdown-menu text-primary"
|
className="custom-column-dropdown-menu text-primary"
|
||||||
|
@ -15,8 +15,9 @@ import { create } from 'zustand';
|
|||||||
import { createJSONStorage, persist } from 'zustand/middleware';
|
import { createJSONStorage, persist } from 'zustand/middleware';
|
||||||
import { useApplicationStore } from '../useApplicationStore';
|
import { useApplicationStore } from '../useApplicationStore';
|
||||||
|
|
||||||
interface UserPreferences {
|
export interface UserPreferences {
|
||||||
isSidebarCollapsed: boolean;
|
isSidebarCollapsed: boolean;
|
||||||
|
selectedEntityTableColumns: Record<string, string[]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Store {
|
interface Store {
|
||||||
@ -31,6 +32,7 @@ interface Store {
|
|||||||
|
|
||||||
const defaultPreferences: UserPreferences = {
|
const defaultPreferences: UserPreferences = {
|
||||||
isSidebarCollapsed: false,
|
isSidebarCollapsed: false,
|
||||||
|
selectedEntityTableColumns: {},
|
||||||
// Add default values for other preferences
|
// Add default values for other preferences
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -743,66 +743,6 @@ export const updateFieldDescription = <T extends TableFieldsInfoCommonEntities>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getTableColumnConfigSelections = (
|
|
||||||
userFqn: string,
|
|
||||||
entityType: string | undefined,
|
|
||||||
isFullViewTable: boolean,
|
|
||||||
defaultColumns: string[] | undefined
|
|
||||||
) => {
|
|
||||||
if (!userFqn) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const storageKey = `selectedColumns-${userFqn}`;
|
|
||||||
const selectedColumns = JSON.parse(localStorage.getItem(storageKey) ?? '{}');
|
|
||||||
|
|
||||||
if (entityType) {
|
|
||||||
if (selectedColumns[entityType]) {
|
|
||||||
return selectedColumns[entityType];
|
|
||||||
} else if (!isFullViewTable) {
|
|
||||||
localStorage.setItem(
|
|
||||||
storageKey,
|
|
||||||
JSON.stringify({
|
|
||||||
...selectedColumns,
|
|
||||||
[entityType]: defaultColumns,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return defaultColumns;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const handleUpdateTableColumnSelections = (
|
|
||||||
selected: boolean,
|
|
||||||
key: string,
|
|
||||||
columnDropdownSelections: string[],
|
|
||||||
userFqn: string,
|
|
||||||
entityType: string | undefined
|
|
||||||
) => {
|
|
||||||
const updatedSelections = selected
|
|
||||||
? [...columnDropdownSelections, key]
|
|
||||||
: columnDropdownSelections.filter((item) => item !== key);
|
|
||||||
|
|
||||||
// Updating localStorage
|
|
||||||
const selectedColumns = JSON.parse(
|
|
||||||
localStorage.getItem(`selectedColumns-${userFqn}`) ?? '{}'
|
|
||||||
);
|
|
||||||
if (entityType) {
|
|
||||||
localStorage.setItem(
|
|
||||||
`selectedColumns-${userFqn}`,
|
|
||||||
JSON.stringify({
|
|
||||||
...selectedColumns,
|
|
||||||
[entityType]: updatedSelections,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return updatedSelections;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getTableDetailPageBaseTabs = ({
|
export const getTableDetailPageBaseTabs = ({
|
||||||
queryCount,
|
queryCount,
|
||||||
isTourOpen,
|
isTourOpen,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user