mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 21:45:59 +08:00
feat: preserve the sorting searching and pagination in dashboard page (#4319)
* feat: preserved the sorting searching and pagination * fix: filter in dashboard data
This commit is contained in:
parent
a47a90b0f3
commit
5fe7948be9
@ -43,7 +43,7 @@ function DynamicColumnTable({
|
|||||||
: undefined,
|
: undefined,
|
||||||
);
|
);
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [columns]);
|
}, [columns, dynamicColumns]);
|
||||||
|
|
||||||
const onToggleHandler = (index: number) => (
|
const onToggleHandler = (index: number) => (
|
||||||
checked: boolean,
|
checked: boolean,
|
||||||
|
@ -24,10 +24,14 @@ import { Dashboard } from 'types/api/dashboard/getAll';
|
|||||||
import AppReducer from 'types/reducer/app';
|
import AppReducer from 'types/reducer/app';
|
||||||
|
|
||||||
import DateComponent from '../../components/ResizeTable/TableComponent/DateComponent';
|
import DateComponent from '../../components/ResizeTable/TableComponent/DateComponent';
|
||||||
|
import useSortableTable from '../../hooks/ResizeTable/useSortableTable';
|
||||||
|
import useUrlQuery from '../../hooks/useUrlQuery';
|
||||||
|
import { GettableAlert } from '../../types/api/alerts/get';
|
||||||
import ImportJSON from './ImportJSON';
|
import ImportJSON from './ImportJSON';
|
||||||
import { ButtonContainer, NewDashboardButton, TableContainer } from './styles';
|
import { ButtonContainer, NewDashboardButton, TableContainer } from './styles';
|
||||||
import DeleteButton from './TableComponents/DeleteButton';
|
import DeleteButton from './TableComponents/DeleteButton';
|
||||||
import Name from './TableComponents/Name';
|
import Name from './TableComponents/Name';
|
||||||
|
import { filterDashboard } from './utils';
|
||||||
|
|
||||||
const { Search } = Input;
|
const { Search } = Input;
|
||||||
|
|
||||||
@ -55,8 +59,26 @@ function DashboardsList(): JSX.Element {
|
|||||||
const [uploadedGrafana, setUploadedGrafana] = useState<boolean>(false);
|
const [uploadedGrafana, setUploadedGrafana] = useState<boolean>(false);
|
||||||
const [isFilteringDashboards, setIsFilteringDashboards] = useState(false);
|
const [isFilteringDashboards, setIsFilteringDashboards] = useState(false);
|
||||||
|
|
||||||
|
const params = useUrlQuery();
|
||||||
|
const orderColumnParam = params.get('columnKey');
|
||||||
|
const orderQueryParam = params.get('order');
|
||||||
|
const paginationParam = params.get('page');
|
||||||
|
const searchParams = params.get('search');
|
||||||
|
const [searchString, setSearchString] = useState<string>(searchParams || '');
|
||||||
|
|
||||||
const [dashboards, setDashboards] = useState<Dashboard[]>();
|
const [dashboards, setDashboards] = useState<Dashboard[]>();
|
||||||
|
|
||||||
|
const sortingOrder: 'ascend' | 'descend' | null =
|
||||||
|
orderQueryParam === 'ascend' || orderQueryParam === 'descend'
|
||||||
|
? orderQueryParam
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const { sortedInfo, handleChange } = useSortableTable<GettableAlert>(
|
||||||
|
sortingOrder,
|
||||||
|
orderColumnParam || '',
|
||||||
|
searchString,
|
||||||
|
);
|
||||||
|
|
||||||
const sortDashboardsByCreatedAt = (dashboards: Dashboard[]): void => {
|
const sortDashboardsByCreatedAt = (dashboards: Dashboard[]): void => {
|
||||||
const sortedDashboards = dashboards.sort(
|
const sortedDashboards = dashboards.sort(
|
||||||
(a, b) =>
|
(a, b) =>
|
||||||
@ -67,7 +89,12 @@ function DashboardsList(): JSX.Element {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
sortDashboardsByCreatedAt(dashboardListResponse);
|
sortDashboardsByCreatedAt(dashboardListResponse);
|
||||||
}, [dashboardListResponse]);
|
const filteredDashboards = filterDashboard(
|
||||||
|
searchString,
|
||||||
|
dashboardListResponse,
|
||||||
|
);
|
||||||
|
setDashboards(filteredDashboards || []);
|
||||||
|
}, [dashboardListResponse, searchString]);
|
||||||
|
|
||||||
const [newDashboardState, setNewDashboardState] = useState({
|
const [newDashboardState, setNewDashboardState] = useState({
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -89,6 +116,10 @@ function DashboardsList(): JSX.Element {
|
|||||||
return prev - next;
|
return prev - next;
|
||||||
},
|
},
|
||||||
render: DateComponent,
|
render: DateComponent,
|
||||||
|
sortOrder:
|
||||||
|
sortedInfo.columnKey === DynamicColumnsKey.CreatedAt
|
||||||
|
? sortedInfo.order
|
||||||
|
: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Created By',
|
title: 'Created By',
|
||||||
@ -108,6 +139,10 @@ function DashboardsList(): JSX.Element {
|
|||||||
return prev - next;
|
return prev - next;
|
||||||
},
|
},
|
||||||
render: DateComponent,
|
render: DateComponent,
|
||||||
|
sortOrder:
|
||||||
|
sortedInfo.columnKey === DynamicColumnsKey.UpdatedAt
|
||||||
|
? sortedInfo.order
|
||||||
|
: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Last Updated By',
|
title: 'Last Updated By',
|
||||||
@ -249,28 +284,13 @@ function DashboardsList(): JSX.Element {
|
|||||||
return menuItems;
|
return menuItems;
|
||||||
}, [createNewDashboard, isDashboardListLoading, onNewDashboardHandler, t]);
|
}, [createNewDashboard, isDashboardListLoading, onNewDashboardHandler, t]);
|
||||||
|
|
||||||
const searchArrayOfObjects = (searchValue: string): any[] => {
|
|
||||||
// Convert the searchValue to lowercase for case-insensitive search
|
|
||||||
const searchValueLowerCase = searchValue.toLowerCase();
|
|
||||||
|
|
||||||
// Use the filter method to find matching objects
|
|
||||||
return dashboardListResponse.filter((item: any) => {
|
|
||||||
// Convert each property value to lowercase for case-insensitive search
|
|
||||||
const itemValues = Object.values(item?.data).map((value: any) =>
|
|
||||||
value.toString().toLowerCase(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check if any property value contains the searchValue
|
|
||||||
return itemValues.some((value) => value.includes(searchValueLowerCase));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSearch = useDebouncedFn((event: unknown): void => {
|
const handleSearch = useDebouncedFn((event: unknown): void => {
|
||||||
setIsFilteringDashboards(true);
|
setIsFilteringDashboards(true);
|
||||||
const searchText = (event as React.BaseSyntheticEvent)?.target?.value || '';
|
const searchText = (event as React.BaseSyntheticEvent)?.target?.value || '';
|
||||||
const filteredDashboards = searchArrayOfObjects(searchText);
|
const filteredDashboards = filterDashboard(searchText, dashboardListResponse);
|
||||||
setDashboards(filteredDashboards);
|
setDashboards(filteredDashboards);
|
||||||
setIsFilteringDashboards(false);
|
setIsFilteringDashboards(false);
|
||||||
|
setSearchString(searchText);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
const GetHeader = useMemo(
|
const GetHeader = useMemo(
|
||||||
@ -283,6 +303,7 @@ function DashboardsList(): JSX.Element {
|
|||||||
onChange={handleSearch}
|
onChange={handleSearch}
|
||||||
loading={isFilteringDashboards}
|
loading={isFilteringDashboards}
|
||||||
style={{ marginBottom: 16, marginTop: 16 }}
|
style={{ marginBottom: 16, marginTop: 16 }}
|
||||||
|
defaultValue={searchString}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
@ -328,6 +349,7 @@ function DashboardsList(): JSX.Element {
|
|||||||
newDashboardState.loading,
|
newDashboardState.loading,
|
||||||
newDashboardState.error,
|
newDashboardState.error,
|
||||||
getText,
|
getText,
|
||||||
|
searchString,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -349,12 +371,14 @@ function DashboardsList(): JSX.Element {
|
|||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
defaultPageSize: 10,
|
defaultPageSize: 10,
|
||||||
total: data?.length || 0,
|
total: data?.length || 0,
|
||||||
|
defaultCurrent: Number(paginationParam) || 1,
|
||||||
}}
|
}}
|
||||||
showHeader
|
showHeader
|
||||||
bordered
|
bordered
|
||||||
sticky
|
sticky
|
||||||
loading={isDashboardListLoading}
|
loading={isDashboardListLoading}
|
||||||
dataSource={data}
|
dataSource={data}
|
||||||
|
onChange={handleChange}
|
||||||
showSorterTooltip
|
showSorterTooltip
|
||||||
/>
|
/>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
20
frontend/src/container/ListOfDashboard/utils.ts
Normal file
20
frontend/src/container/ListOfDashboard/utils.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Dashboard } from 'types/api/dashboard/getAll';
|
||||||
|
|
||||||
|
export const filterDashboard = (
|
||||||
|
searchValue: string,
|
||||||
|
dashboardList: Dashboard[],
|
||||||
|
): any[] => {
|
||||||
|
// Convert the searchValue to lowercase for case-insensitive search
|
||||||
|
const searchValueLowerCase = searchValue.toLowerCase();
|
||||||
|
|
||||||
|
// Use the filter method to find matching objects
|
||||||
|
return dashboardList.filter((item: Dashboard) => {
|
||||||
|
// Convert each property value to lowercase for case-insensitive search
|
||||||
|
const itemValues = Object.values(item?.data).map((value) =>
|
||||||
|
value.toString().toLowerCase(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check if any property value contains the searchValue
|
||||||
|
return itemValues.some((value) => value.includes(searchValueLowerCase));
|
||||||
|
});
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user