dnazarenkoo 8363dadd8d
fix: resolve the list view issues (#3020)
* feat: add dynamic table based on query

* feat: add the list view for the traces explorer

* fix: fix the options menu

* feat: update the list view columns config for the traces explorer

* feat: fix columns for the list view for the traces explorer page

* feat: update customization columns for the list view from the traces explorer

* feat: add error msg for the list view, fix creating data for the table

* fix: resolve the list view issues

* fix: update the date column for the list view

* fix: remove additional filter title for the list view

* fix: add initial orderBy filter for the list view

---------

Co-authored-by: Yevhen Shevchenko <y.shevchenko@seedium.io>
Co-authored-by: Nazarenko19 <danil.nazarenko2000@gmail.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
2023-07-05 16:20:20 +05:30

179 lines
4.7 KiB
TypeScript

import { RadioChangeEvent } from 'antd';
import { getAggregateKeys } from 'api/queryBuilder/getAttributeKeys';
import { QueryBuilderKeys } from 'constants/queryBuilder';
import { useNotifications } from 'hooks/useNotifications';
import useUrlQueryData from 'hooks/useUrlQueryData';
import { useCallback, useEffect, useMemo } from 'react';
import { useQuery } from 'react-query';
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
import { DataSource } from 'types/common/queryBuilder';
import { defaultOptionsQuery, URL_OPTIONS } from './constants';
import { InitialOptions, OptionsMenuConfig, OptionsQuery } from './types';
import { getInitialColumns, getOptionsFromKeys } from './utils';
interface UseOptionsMenuProps {
dataSource: DataSource;
aggregateOperator: string;
initialOptions?: InitialOptions;
}
interface UseOptionsMenu {
isLoading: boolean;
options: OptionsQuery;
config: OptionsMenuConfig;
}
const useOptionsMenu = ({
dataSource,
aggregateOperator,
initialOptions = {},
}: UseOptionsMenuProps): UseOptionsMenu => {
const { notifications } = useNotifications();
const {
query: optionsQuery,
queryData: optionsQueryData,
redirectWithQuery: redirectWithOptionsData,
} = useUrlQueryData<OptionsQuery>(URL_OPTIONS);
const { data, isFetched, isLoading } = useQuery(
[QueryBuilderKeys.GET_ATTRIBUTE_KEY],
async () =>
getAggregateKeys({
searchText: '',
dataSource,
aggregateOperator,
aggregateAttribute: '',
}),
);
const attributeKeys = useMemo(() => data?.payload?.attributeKeys || [], [
data?.payload?.attributeKeys,
]);
const initialOptionsQuery: OptionsQuery = useMemo(
() => ({
...defaultOptionsQuery,
...initialOptions,
selectColumns: initialOptions?.selectColumns
? getInitialColumns(initialOptions?.selectColumns || [], attributeKeys)
: defaultOptionsQuery.selectColumns,
}),
[initialOptions, attributeKeys],
);
const selectedColumnKeys = useMemo(
() => optionsQueryData?.selectColumns?.map(({ id }) => id) || [],
[optionsQueryData],
);
const addColumnOptions = useMemo(
() => getOptionsFromKeys(attributeKeys, selectedColumnKeys),
[attributeKeys, selectedColumnKeys],
);
const handleSelectedColumnsChange = useCallback(
(value: string[]) => {
const newSelectedColumnKeys = [
...new Set([...selectedColumnKeys, ...value]),
];
const newSelectedColumns = newSelectedColumnKeys.reduce((acc, key) => {
const column = attributeKeys.find(({ id }) => id === key);
if (!column) return acc;
return [...acc, column];
}, [] as BaseAutocompleteData[]);
redirectWithOptionsData({
...defaultOptionsQuery,
selectColumns: newSelectedColumns,
});
},
[attributeKeys, selectedColumnKeys, redirectWithOptionsData],
);
const handleRemoveSelectedColumn = useCallback(
(columnKey: string) => {
const newSelectedColumns = optionsQueryData?.selectColumns?.filter(
({ id }) => id !== columnKey,
);
if (!newSelectedColumns.length) {
notifications.error({
message: 'There must be at least one selected column',
});
} else {
redirectWithOptionsData({
...defaultOptionsQuery,
selectColumns: newSelectedColumns,
});
}
},
[optionsQueryData, notifications, redirectWithOptionsData],
);
const handleFormatChange = useCallback(
(event: RadioChangeEvent) => {
redirectWithOptionsData({
...defaultOptionsQuery,
format: event.target.value,
});
},
[redirectWithOptionsData],
);
const handleMaxLinesChange = useCallback(
(value: string | number | null) => {
redirectWithOptionsData({
...defaultOptionsQuery,
maxLines: value as number,
});
},
[redirectWithOptionsData],
);
const optionsMenuConfig: Required<OptionsMenuConfig> = useMemo(
() => ({
addColumn: {
value: optionsQueryData?.selectColumns || defaultOptionsQuery.selectColumns,
options: addColumnOptions || [],
onChange: handleSelectedColumnsChange,
onRemove: handleRemoveSelectedColumn,
},
format: {
value: optionsQueryData?.format || defaultOptionsQuery.format,
onChange: handleFormatChange,
},
maxLines: {
value: optionsQueryData?.maxLines || defaultOptionsQuery.maxLines,
onChange: handleMaxLinesChange,
},
}),
[
addColumnOptions,
optionsQueryData?.maxLines,
optionsQueryData?.format,
optionsQueryData?.selectColumns,
handleSelectedColumnsChange,
handleRemoveSelectedColumn,
handleFormatChange,
handleMaxLinesChange,
],
);
useEffect(() => {
if (optionsQuery || !isFetched) return;
redirectWithOptionsData(initialOptionsQuery);
}, [isFetched, optionsQuery, initialOptionsQuery, redirectWithOptionsData]);
return {
isLoading,
options: optionsQueryData,
config: optionsMenuConfig,
};
};
export default useOptionsMenu;