mirror of https://github.com/buster-so/buster.git
favorites on list endpoint
This commit is contained in:
parent
2ef2ad1499
commit
7fd5d346ff
|
@ -110,7 +110,7 @@ export const DropdownBase = <T,>({
|
||||||
<span className="dropdown-trigger">{children}</span>
|
<span className="dropdown-trigger">{children}</span>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent
|
<DropdownMenuContent
|
||||||
className={cn('max-w-72 min-w-44', className)}
|
className={cn('max-w-72 min-w-48', className)}
|
||||||
align={align}
|
align={align}
|
||||||
side={side}
|
side={side}
|
||||||
sideOffset={sideOffset}>
|
sideOffset={sideOffset}>
|
||||||
|
|
|
@ -14,18 +14,20 @@ const TooltipContent = React.forwardRef<
|
||||||
React.ElementRef<typeof TooltipPrimitive.Content>,
|
React.ElementRef<typeof TooltipPrimitive.Content>,
|
||||||
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
|
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
|
||||||
>(({ className, sideOffset = 4, ...props }, ref) => (
|
>(({ className, sideOffset = 4, ...props }, ref) => (
|
||||||
<TooltipPrimitive.Content
|
<TooltipPrimitive.Portal>
|
||||||
ref={ref}
|
<TooltipPrimitive.Content
|
||||||
sideOffset={sideOffset}
|
ref={ref}
|
||||||
className={cn(
|
sideOffset={sideOffset}
|
||||||
'bg-popover text-popover-foreground',
|
className={cn(
|
||||||
'rounded border py-1.5 pr-0.5 pl-1.5',
|
'bg-popover text-popover-foreground',
|
||||||
'text-sm shadow',
|
'rounded border py-1.5 pr-0.5 pl-1.5',
|
||||||
'animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden',
|
'text-sm shadow',
|
||||||
className
|
'animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden',
|
||||||
)}
|
className
|
||||||
{...props}
|
)}
|
||||||
/>
|
{...props}
|
||||||
|
/>
|
||||||
|
</TooltipPrimitive.Portal>
|
||||||
));
|
));
|
||||||
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,10 @@ import {
|
||||||
} from '@/components/ui/list';
|
} from '@/components/ui/list';
|
||||||
import { useMemoizedFn } from '@/hooks';
|
import { useMemoizedFn } from '@/hooks';
|
||||||
import { NewCollectionModal } from '@/components/features/modal/NewCollectionModal';
|
import { NewCollectionModal } from '@/components/features/modal/NewCollectionModal';
|
||||||
import { BusterCollectionListItem } from '@/api/asset_interfaces';
|
import { BusterCollectionListItem, ShareAssetType } from '@/api/asset_interfaces';
|
||||||
import { CollectionListSelectedPopup } from './CollectionListSelectedPopup';
|
import { CollectionListSelectedPopup } from './CollectionListSelectedPopup';
|
||||||
|
import { Text } from '@/components/ui/typography';
|
||||||
|
import { FavoriteStar } from '@/components/features/list';
|
||||||
|
|
||||||
export const CollectionsListContent: React.FC<{
|
export const CollectionsListContent: React.FC<{
|
||||||
openNewCollectionModal: boolean;
|
openNewCollectionModal: boolean;
|
||||||
|
@ -54,17 +56,28 @@ export const CollectionsListContent: React.FC<{
|
||||||
CollectionsListContent.displayName = 'CollectionsListContent';
|
CollectionsListContent.displayName = 'CollectionsListContent';
|
||||||
|
|
||||||
const columns: BusterListColumn[] = [
|
const columns: BusterListColumn[] = [
|
||||||
{ dataIndex: 'title', title: 'Title' },
|
|
||||||
{
|
{
|
||||||
dataIndex: 'createdAt',
|
dataIndex: 'name',
|
||||||
title: 'Created at',
|
title: 'Title',
|
||||||
width: 145,
|
render: (v, { id, ...rest }: BusterCollectionListItem) => {
|
||||||
render: (v) => formatDate({ date: v, format: 'lll' })
|
return (
|
||||||
|
<div className="mr-2 flex items-center space-x-1.5">
|
||||||
|
<Text truncate>{v}</Text>
|
||||||
|
<FavoriteStar
|
||||||
|
id={id}
|
||||||
|
type={ShareAssetType.COLLECTION}
|
||||||
|
iconStyle="tertiary"
|
||||||
|
title={v}
|
||||||
|
className="opacity-0 group-hover:opacity-100"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dataIndex: 'lastEdited',
|
dataIndex: 'last_edited',
|
||||||
title: 'Last edited',
|
title: 'Last edited',
|
||||||
width: 145,
|
width: 150,
|
||||||
render: (v) => formatDate({ date: v, format: 'lll' })
|
render: (v) => formatDate({ date: v, format: 'lll' })
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -98,13 +111,7 @@ const CollectionList: React.FC<{
|
||||||
route: BusterRoutes.APP_COLLECTIONS_ID,
|
route: BusterRoutes.APP_COLLECTIONS_ID,
|
||||||
collectionId: collection.id
|
collectionId: collection.id
|
||||||
}),
|
}),
|
||||||
data: {
|
data: collection
|
||||||
title: collection.name,
|
|
||||||
lastEdited: collection.last_edited,
|
|
||||||
createdAt: collection.created_at,
|
|
||||||
owner: collection.owner,
|
|
||||||
sharing: collection.sharing
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}, [collectionsList]);
|
}, [collectionsList]);
|
||||||
|
|
|
@ -16,14 +16,28 @@ import type { BusterDashboardListItem } from '@/api/asset_interfaces';
|
||||||
import { getShareStatus } from '@/components/features/metrics/StatusBadgeIndicator/helpers';
|
import { getShareStatus } from '@/components/features/metrics/StatusBadgeIndicator/helpers';
|
||||||
import { useCreateDashboard } from '@/api/buster_rest/dashboards';
|
import { useCreateDashboard } from '@/api/buster_rest/dashboards';
|
||||||
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
|
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
|
||||||
|
import { FavoriteStar } from '@/components/features/list';
|
||||||
|
import { ShareAssetType } from '@/api/asset_interfaces';
|
||||||
|
import { Text } from '@/components/ui/typography';
|
||||||
|
|
||||||
const columns: BusterListColumn[] = [
|
const columns: BusterListColumn[] = [
|
||||||
{
|
{
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
title: 'Title',
|
title: 'Title',
|
||||||
render: (data) => {
|
render: (data, { id }) => {
|
||||||
if (data) return data;
|
const name = data || 'New Dashboard';
|
||||||
return 'New Dashboard';
|
return (
|
||||||
|
<div className="mr-2 flex items-center space-x-1.5">
|
||||||
|
<Text truncate>{name}</Text>
|
||||||
|
<FavoriteStar
|
||||||
|
id={id}
|
||||||
|
type={ShareAssetType.DASHBOARD}
|
||||||
|
iconStyle="tertiary"
|
||||||
|
title={name}
|
||||||
|
className="opacity-0 group-hover:opacity-100"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -158,20 +158,18 @@ const TitleCell = React.memo<{ title: string; status: VerificationStatus; metric
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full items-center space-x-2">
|
<div className="mr-2 flex w-full items-center space-x-2">
|
||||||
<div className="flex items-center justify-center">
|
<div className="flex items-center justify-center">
|
||||||
<StatusBadgeIndicator status={status} />
|
<StatusBadgeIndicator status={status} />
|
||||||
</div>
|
</div>
|
||||||
<Text truncate>{title}</Text>
|
<Text truncate>{title}</Text>
|
||||||
<div className="mr-2 flex items-center" onClick={onFavoriteDivClick}>
|
<FavoriteStar
|
||||||
<FavoriteStar
|
id={metricId}
|
||||||
id={metricId}
|
type={ShareAssetType.METRIC}
|
||||||
type={ShareAssetType.METRIC}
|
iconStyle="tertiary"
|
||||||
iconStyle="tertiary"
|
title={title}
|
||||||
title={title}
|
className="opacity-0 group-hover:opacity-100"
|
||||||
className="opacity-0 group-hover:opacity-100"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import { ShareMenuContent } from '@/components/features/ShareMenu/ShareMenuConte
|
||||||
import { DASHBOARD_TITLE_INPUT_ID } from '@/controllers/DashboardController/DashboardViewDashboardController/DashboardEditTitle';
|
import { DASHBOARD_TITLE_INPUT_ID } from '@/controllers/DashboardController/DashboardViewDashboardController/DashboardEditTitle';
|
||||||
import { canEdit, canFilter, getIsEffectiveOwner } from '@/lib/share';
|
import { canEdit, canFilter, getIsEffectiveOwner } from '@/lib/share';
|
||||||
import { getShareAssetConfig } from '@/components/features/ShareMenu/helpers';
|
import { getShareAssetConfig } from '@/components/features/ShareMenu/helpers';
|
||||||
|
import { useDashboardContentStore } from '@/context/Dashboards';
|
||||||
|
|
||||||
export const DashboardThreeDotMenu = React.memo(({ dashboardId }: { dashboardId: string }) => {
|
export const DashboardThreeDotMenu = React.memo(({ dashboardId }: { dashboardId: string }) => {
|
||||||
const versionHistoryItems = useVersionHistorySelectMenu({ dashboardId });
|
const versionHistoryItems = useVersionHistorySelectMenu({ dashboardId });
|
||||||
|
@ -245,13 +246,16 @@ export const useShareMenuSelectMenu = ({ dashboardId }: { dashboardId: string })
|
||||||
};
|
};
|
||||||
|
|
||||||
const useAddContentToDashboardSelectMenu = () => {
|
const useAddContentToDashboardSelectMenu = () => {
|
||||||
|
const onOpenAddContentModal = useDashboardContentStore((x) => x.onOpenAddContentModal);
|
||||||
|
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
label: 'Add content',
|
label: 'Add content',
|
||||||
value: 'add-content',
|
value: 'add-content',
|
||||||
icon: <Plus />
|
icon: <Plus />,
|
||||||
|
onClick: onOpenAddContentModal
|
||||||
}),
|
}),
|
||||||
[]
|
[onOpenAddContentModal]
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue