buster/web/src/controllers/MetricListContainer/MetricItemsSelectedPopup.tsx

193 lines
6.0 KiB
TypeScript

import React, { useState } from 'react';
import { BusterListSelectedOptionPopupContainer } from '@/components/ui/list';
import { ShareAssetType, VerificationStatus } from '@/api/asset_interfaces';
import { useUserConfigContextSelector } from '@/context/Users';
import { useMemoizedFn } from '@/hooks';
import { SaveToCollectionsDropdown } from '@/components/features/dropdowns/SaveToCollectionsDropdown';
import { useBusterNotifications } from '@/context/BusterNotifications';
import { Button } from '@/components/ui/buttons';
import { ASSET_ICONS } from '@/components/features/config/assetIcons';
import { Dropdown } from '@/components/ui/dropdown';
import { StatusBadgeButton } from '@/components/features/metrics/StatusBadgeIndicator';
import { Dots, Trash } from '@/components/ui/icons';
import {
useDeleteMetric,
useRemoveMetricFromCollection,
useSaveMetricToCollections,
useUpdateMetric
} from '@/api/buster_rest/metrics';
import { useThreeDotFavoritesOptions } from '@/components/features/dropdowns/useThreeDotFavoritesOptions';
export const MetricSelectedOptionPopup: React.FC<{
selectedRowKeys: string[];
onSelectChange: (selectedRowKeys: string[]) => void;
hasSelected: boolean;
}> = React.memo(({ selectedRowKeys, onSelectChange, hasSelected }) => {
return (
<BusterListSelectedOptionPopupContainer
selectedRowKeys={selectedRowKeys}
onSelectChange={onSelectChange}
buttons={[
<CollectionsButton
key="collections"
selectedRowKeys={selectedRowKeys}
onSelectChange={onSelectChange}
/>,
<DashboardButton
key="dashboard"
selectedRowKeys={selectedRowKeys}
onSelectChange={onSelectChange}
/>,
<StatusButton
key="status"
selectedRowKeys={selectedRowKeys}
onSelectChange={onSelectChange}
/>,
<DeleteButton
key="delete"
selectedRowKeys={selectedRowKeys}
onSelectChange={onSelectChange}
/>,
<ThreeDotButton
key="three-dot"
selectedRowKeys={selectedRowKeys}
onSelectChange={onSelectChange}
/>
]}
show={hasSelected}
/>
);
});
MetricSelectedOptionPopup.displayName = 'MetricSelectedOptionPopup';
const CollectionsButton: React.FC<{
selectedRowKeys: string[];
onSelectChange: (selectedRowKeys: string[]) => void;
}> = ({ selectedRowKeys, onSelectChange }) => {
const { openInfoMessage } = useBusterNotifications();
const { mutateAsync: saveMetricToCollection } = useSaveMetricToCollections();
const { mutateAsync: removeMetricFromCollection } = useRemoveMetricFromCollection();
const [selectedCollections, setSelectedCollections] = useState<
Parameters<typeof SaveToCollectionsDropdown>[0]['selectedCollections']
>([]);
const onSaveToCollection = useMemoizedFn(async (collectionIds: string[]) => {
setSelectedCollections(collectionIds);
await saveMetricToCollection({
metricIds: selectedRowKeys,
collectionIds
});
openInfoMessage('Metrics saved to collections');
});
const onRemoveFromCollection = useMemoizedFn(async (collectionId: string) => {
setSelectedCollections((prev) => prev.filter((id) => id !== collectionId));
await removeMetricFromCollection({
metricIds: selectedRowKeys,
collectionIds: [collectionId]
});
openInfoMessage('Metrics removed from collections');
});
return (
<SaveToCollectionsDropdown
onSaveToCollection={onSaveToCollection}
onRemoveFromCollection={onRemoveFromCollection}
selectedCollections={selectedCollections}>
<Button prefix={<ASSET_ICONS.collections />}>Collections</Button>
</SaveToCollectionsDropdown>
);
};
const DashboardButton: React.FC<{
selectedRowKeys: string[];
onSelectChange: (selectedRowKeys: string[]) => void;
}> = ({ selectedRowKeys, onSelectChange }) => {
return (
<Dropdown items={[{ label: 'Dashboard', value: 'dashboard' }]}>
<Button prefix={<ASSET_ICONS.dashboards />} type="button">
Dashboard
</Button>
</Dropdown>
);
};
const StatusButton: React.FC<{
selectedRowKeys: string[];
onSelectChange: (selectedRowKeys: string[]) => void;
}> = ({ selectedRowKeys, onSelectChange }) => {
const { mutateAsync: updateMetric } = useUpdateMetric({
updateVersion: false,
saveToServer: true,
updateOnSave: true
});
const isAdmin = useUserConfigContextSelector((state) => state.isAdmin);
const onVerify = useMemoizedFn(async (d: { id: string; status: VerificationStatus }[]) => {
await Promise.all(
d.map(({ id, status }) => {
return updateMetric({
id,
status
});
})
);
onSelectChange([]);
});
return (
<StatusBadgeButton
status={VerificationStatus.NOT_REQUESTED}
id={selectedRowKeys}
onVerify={onVerify}
isAdmin={isAdmin}
/>
);
};
const DeleteButton: React.FC<{
selectedRowKeys: string[];
onSelectChange: (selectedRowKeys: string[]) => void;
}> = ({ selectedRowKeys, onSelectChange }) => {
const { mutateAsync: deleteMetric } = useDeleteMetric();
const { openConfirmModal } = useBusterNotifications();
const onDeleteClick = async () => {
openConfirmModal({
title: 'Delete metric',
content: 'Are you sure you want to delete these metrics?',
onOk: async () => {
await deleteMetric({ ids: selectedRowKeys });
onSelectChange([]);
}
});
};
return (
<Button prefix={<Trash />} onClick={onDeleteClick}>
Delete
</Button>
);
};
const ThreeDotButton: React.FC<{
selectedRowKeys: string[];
onSelectChange: (selectedRowKeys: string[]) => void;
}> = React.memo(({ selectedRowKeys, onSelectChange }) => {
const dropdownOptions = useThreeDotFavoritesOptions({
itemIds: selectedRowKeys,
assetType: ShareAssetType.METRIC,
onFinish: () => onSelectChange([])
});
return (
<Dropdown items={dropdownOptions}>
<Button prefix={<Dots />} />
</Dropdown>
);
});
ThreeDotButton.displayName = 'ThreeDotButton';