feat: add column sorting in table header

pull/237/head
kat 2026-09-17 12:52:09 +01:00
parent 1d67af1558
commit ee585d31eb
1 changed files with 50 additions and 10 deletions

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useMemo } from 'react';
import { useIntl } from 'react-intl';
import { isEmpty } from 'lodash';
import { useDispatch } from 'react-redux';
@ -12,7 +12,9 @@ import {
Typography,
Checkbox,
Loader,
Flex,
} from '@strapi/design-system';
import { CaretDown, CaretUp } from '@strapi/icons';
import ConfigDiff from '../ConfigDiff';
import FirstExport from '../FirstExport';
@ -27,9 +29,20 @@ const ConfigList = ({ diff, isLoading }) => {
const [cName, setCname] = useState('');
const [rows, setRows] = useState([]);
const [checkedItems, setCheckedItems] = useState([]);
const [sortBy, setSortBy] = useState('configName');
const [sortOrder, setSortOrder] = useState('asc');
const dispatch = useDispatch();
const { formatMessage } = useIntl();
const handleSort = (field) => {
if (sortBy === field) {
setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');
} else {
setSortBy(field);
setSortOrder('asc');
}
};
const getConfigState = (configName) => {
if (
diff.fileConfig[configName]
@ -87,6 +100,19 @@ const ConfigList = ({ diff, isLoading }) => {
dispatch(setConfigPartialDiffInState(newPartialDiff));
}, [checkedItems]);
const sortedRows = useMemo(() => {
const rowsWithIndex = rows.map((row, originalIndex) => ({ ...row, originalIndex }));
return rowsWithIndex.sort((a, b) => {
const aValue = (a[sortBy] || '').toLowerCase();
const bValue = (b[sortBy] || '').toLowerCase();
if (aValue < bValue) return sortOrder === 'asc' ? -1 : 1;
if (aValue > bValue) return sortOrder === 'asc' ? 1 : -1;
return 0;
});
}, [rows, sortBy, sortOrder]);
if (isLoading) {
return (
<div style={{ textAlign: 'center', marginTop: 40 }}>
@ -106,6 +132,11 @@ const ConfigList = ({ diff, isLoading }) => {
const allChecked = checkedItems && checkedItems.every(Boolean);
const isIndeterminate = checkedItems.some(Boolean) && !allChecked;
const renderSortIcon = (field) => {
if (sortBy !== field) return null;
return sortOrder === 'asc' ? <CaretUp /> : <CaretDown />;
};
return (
<div>
<Table colCount={4} rowCount={rows.length + 1}>
@ -118,19 +149,28 @@ const ConfigList = ({ diff, isLoading }) => {
onCheckedChange={(value) => setCheckedItems(checkedItems.map(() => value))}
/>
</Th>
<Th>
<Th onClick={() => handleSort('configName')} style={{ cursor: 'pointer' }}>
<Flex gap={1}>
<Typography variant="sigma">{formatMessage({ id: 'config-sync.ConfigList.ConfigName' })}</Typography>
{renderSortIcon('configName')}
</Flex>
</Th>
<Th>
<Th onClick={() => handleSort('configType')} style={{ cursor: 'pointer' }}>
<Flex gap={1}>
<Typography variant="sigma">{formatMessage({ id: 'config-sync.ConfigList.ConfigType' })}</Typography>
{renderSortIcon('configType')}
</Flex>
</Th>
<Th>
<Th onClick={() => handleSort('state')} style={{ cursor: 'pointer' }}>
<Flex gap={1}>
<Typography variant="sigma">{formatMessage({ id: 'config-sync.ConfigList.State' })}</Typography>
{renderSortIcon('state')}
</Flex>
</Th>
</Tr>
</Thead>
<Tbody>
{rows.map((row, index) => (
{sortedRows.map((row) => (
<ConfigDiff
key={row.configName}
oldValue={originalConfig}
@ -139,9 +179,9 @@ const ConfigList = ({ diff, isLoading }) => {
trigger={(
<ConfigListRow
row={row}
checked={checkedItems[index]}
checked={checkedItems[row.originalIndex]}
updateValue={() => {
checkedItems[index] = !checkedItems[index];
checkedItems[row.originalIndex] = !checkedItems[row.originalIndex];
setCheckedItems([...checkedItems]);
}}
/>