mirror of https://github.com/buster-so/buster.git
add and remove from collection works 📖
This commit is contained in:
parent
77d9203383
commit
4e5ac6f752
|
@ -106,7 +106,7 @@ export const updateCollectionShare = async ({
|
|||
|
||||
export const addAssetToCollection = async ({
|
||||
id,
|
||||
...params
|
||||
assets
|
||||
}: {
|
||||
id: string;
|
||||
assets: {
|
||||
|
@ -114,13 +114,14 @@ export const addAssetToCollection = async ({
|
|||
id: string;
|
||||
}[];
|
||||
}) => {
|
||||
return mainApi.post<null>(`/collections/${id}/assets`, params).then((res) => res.data);
|
||||
return mainApi.post<null>(`/collections/${id}/assets`, { assets }).then((res) => res.data);
|
||||
};
|
||||
|
||||
export const removeAssetFromCollection = async (
|
||||
params: Parameters<typeof addAssetToCollection>[0]
|
||||
) => {
|
||||
export const removeAssetFromCollection = async ({
|
||||
id,
|
||||
assets
|
||||
}: Parameters<typeof addAssetToCollection>[0]) => {
|
||||
return mainApi
|
||||
.delete<null>(`/collections/${params.id}/assets`, { data: params })
|
||||
.delete<null>(`/collections/${id}/assets`, { data: { assets } })
|
||||
.then((res) => res.data);
|
||||
};
|
||||
|
|
|
@ -1,19 +1,15 @@
|
|||
import { useGetMetricsList } from '@/api/buster_rest/metrics';
|
||||
import { useDebounce, useMemoizedFn } from '@/hooks';
|
||||
import React, { useLayoutEffect, useMemo, useState } from 'react';
|
||||
import { InputSelectModal, InputSelectModalProps } from '@/components/ui/modal/InputSelectModal';
|
||||
import { formatDate } from '@/lib';
|
||||
import { Button } from '@/components/ui/buttons';
|
||||
import { useGetDashboardsList } from '@/api/buster_rest/dashboards';
|
||||
import {
|
||||
useAddAndRemoveAssetsFromCollection,
|
||||
useGetCollection
|
||||
} from '@/api/buster_rest/collections';
|
||||
import { Text } from '@/components/ui/typography';
|
||||
import { ASSET_ICONS } from '../config/assetIcons';
|
||||
import pluralize from 'pluralize';
|
||||
import { useSearch } from '@/api/buster_rest/search';
|
||||
import { ShareAssetType } from '@/api/asset_interfaces/share';
|
||||
|
||||
export const AddToCollectionModal: React.FC<{
|
||||
open: boolean;
|
||||
|
@ -103,6 +99,61 @@ export const AddToCollectionModal: React.FC<{
|
|||
return originalIds.length !== newIds.length || originalIds.some((id) => !newIds.includes(id));
|
||||
}, [originalIds, selectedAssets]);
|
||||
|
||||
const removedAssetCount = useMemo(() => {
|
||||
return originalIds.filter((id) => !selectedAssets.includes(id)).length;
|
||||
}, [originalIds, selectedAssets]);
|
||||
|
||||
const addedAssetCount = useMemo(() => {
|
||||
return selectedAssets.filter((id) => !originalIds.includes(id)).length;
|
||||
}, [originalIds, selectedAssets]);
|
||||
|
||||
const primaryButtonText = useMemo(() => {
|
||||
if (!isFetchedCollection) {
|
||||
return 'Loading assets...';
|
||||
}
|
||||
|
||||
const hasRemovedItems = removedAssetCount > 0;
|
||||
const hasAddedItems = addedAssetCount > 0;
|
||||
|
||||
if (hasRemovedItems && hasAddedItems) {
|
||||
return `Update collection`;
|
||||
}
|
||||
|
||||
if (hasRemovedItems) {
|
||||
return `Remove assets`;
|
||||
}
|
||||
|
||||
if (hasAddedItems) {
|
||||
return `Add assets`;
|
||||
}
|
||||
|
||||
return `Update collection`;
|
||||
}, [isFetchedCollection, removedAssetCount, addedAssetCount]);
|
||||
|
||||
const primaryButtonTooltipText = useMemo(() => {
|
||||
if (!isFetchedCollection) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const hasRemovedItems = removedAssetCount > 0;
|
||||
const hasAddedItems = addedAssetCount > 0;
|
||||
const returnText: string[] = [];
|
||||
|
||||
if (!hasRemovedItems && !hasAddedItems) {
|
||||
return 'No changes to update';
|
||||
}
|
||||
|
||||
if (hasRemovedItems) {
|
||||
returnText.push(`Removing ${removedAssetCount}`);
|
||||
}
|
||||
|
||||
if (hasAddedItems) {
|
||||
returnText.push(`Adding ${addedAssetCount}`);
|
||||
}
|
||||
|
||||
return returnText.join(', ');
|
||||
}, [isFetchedCollection, addedAssetCount, removedAssetCount]);
|
||||
|
||||
const emptyState = useMemo(() => {
|
||||
if (rows.length === 0) {
|
||||
return 'No assets found';
|
||||
|
@ -123,18 +174,19 @@ export const AddToCollectionModal: React.FC<{
|
|||
onClick: onClose
|
||||
},
|
||||
primaryButton: {
|
||||
text:
|
||||
selectedAssets.length === 0
|
||||
? 'Update collection'
|
||||
: `Add ${selectedAssets.length} ${pluralize('asset', selectedAssets.length)} to collection`,
|
||||
text: primaryButtonText,
|
||||
onClick: handleAddAndRemoveMetrics,
|
||||
disabled: !isSelectedChanged,
|
||||
tooltip: isSelectedChanged
|
||||
? `Adding ${selectedAssets.length} assets`
|
||||
: 'No changes to update'
|
||||
tooltip: primaryButtonTooltipText
|
||||
}
|
||||
};
|
||||
}, [selectedAssets.length, isSelectedChanged, handleAddAndRemoveMetrics]);
|
||||
}, [
|
||||
selectedAssets.length,
|
||||
isSelectedChanged,
|
||||
handleAddAndRemoveMetrics,
|
||||
primaryButtonText,
|
||||
primaryButtonTooltipText
|
||||
]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (isFetchedCollection) {
|
||||
|
|
|
@ -189,7 +189,6 @@ export const AddToDashboardModal: React.FC<{
|
|||
emptyState={emptyState}
|
||||
searchText={searchTerm}
|
||||
handleSearchChange={setSearchTerm}
|
||||
className="data-[state=closed]:slide-out-to-top-[5%]! data-[state=open]:slide-in-from-top-[5%]! top-28 translate-y-0"
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ import { useDebounceSearch } from '@/hooks';
|
|||
import { VisuallyHidden } from '@radix-ui/react-visually-hidden';
|
||||
import { DialogDescription, DialogTitle } from '@radix-ui/react-dialog';
|
||||
import { Text } from '../typography';
|
||||
import { cn } from '@/lib/classMerge';
|
||||
|
||||
export interface InputSelectModalProps extends Omit<BorderedModalProps, 'children'> {
|
||||
inputPlaceholder?: string;
|
||||
|
@ -25,6 +26,7 @@ export const InputSelectModal = React.memo(
|
|||
columns,
|
||||
rows,
|
||||
emptyState,
|
||||
className,
|
||||
onSelectChange,
|
||||
selectedRowKeys,
|
||||
searchText,
|
||||
|
@ -51,7 +53,13 @@ export const InputSelectModal = React.memo(
|
|||
}, [searchText, handleSearchChange, inputPlaceholder, rows.length]);
|
||||
|
||||
return (
|
||||
<BorderedModal header={memoizedHeader} {...props}>
|
||||
<BorderedModal
|
||||
header={memoizedHeader}
|
||||
className={cn(
|
||||
'data-[state=closed]:slide-out-to-top-[5%]! data-[state=open]:slide-in-from-top-[5%]! top-28 translate-y-0',
|
||||
className
|
||||
)}
|
||||
{...props}>
|
||||
<div
|
||||
className="max-h-[65vh]"
|
||||
style={{
|
||||
|
|
Loading…
Reference in New Issue