diff --git a/web/src/components/features/metrics/StatusBadgeIndicator/StatusDropdownContent.tsx b/web/src/components/features/metrics/StatusBadgeIndicator/StatusDropdownContent.tsx index b501f184f..5e43ddd7e 100644 --- a/web/src/components/features/metrics/StatusBadgeIndicator/StatusDropdownContent.tsx +++ b/web/src/components/features/metrics/StatusBadgeIndicator/StatusDropdownContent.tsx @@ -3,7 +3,7 @@ import React, { useMemo } from 'react'; import { getTooltipText } from './helpers'; import { useMemoizedFn } from '@/hooks'; import { StatusBadgeIndicator } from './StatusBadgeIndicator'; -import { Dropdown, DropdownItem } from '@/components/ui/dropdown'; +import { Dropdown, DropdownItem, DropdownProps } from '@/components/ui/dropdown'; const statuses = [ VerificationStatus.NOT_REQUESTED, @@ -26,6 +26,32 @@ export const StatusDropdownContent: React.FC<{ onChangeStatus: (status: VerificationStatus) => void; onOpenChange: (open: boolean) => void; }> = React.memo(({ isAdmin, status, onChangeStatus, children, onOpenChange }) => { + const dropdownProps = useStatusDropdownContent({ + isAdmin, + selectedStatus: status, + onChangeStatus + }); + + return ( + + {children} + + ); +}); +StatusDropdownContent.displayName = 'StatusDropdownContent'; + +export const useStatusDropdownContent = ({ + isAdmin, + selectedStatus, + onChangeStatus +}: { + isAdmin: boolean; + selectedStatus: VerificationStatus; + onChangeStatus: (status: VerificationStatus) => void; +}): Pick< + DropdownProps, + 'showIndex' | 'items' | 'emptyStateText' | 'menuHeader' | 'selectType' +> => { const items = useMemo(() => { return statuses.map>((status) => { const requiresAdmin = requiresAdminItems.includes(status); @@ -34,6 +60,7 @@ export const StatusDropdownContent: React.FC<{ value: status, icon: , disabled: requiresAdmin && !isAdmin, + selected: status === selectedStatus, onClick: () => { if (!requiresAdmin || isAdmin) { onChangeStatus(status); @@ -43,21 +70,14 @@ export const StatusDropdownContent: React.FC<{ }); }, [isAdmin, status, onChangeStatus]); - const onSelect = useMemoizedFn((item: VerificationStatus) => { - onChangeStatus(item); - }); - - return ( - - {children} - + return useMemo( + () => ({ + emptyStateText: 'Nothing to see here...', + menuHeader: 'Verification status...', + items, + selectType: 'single', + showIndex: true + }), + [items] ); -}); -StatusDropdownContent.displayName = 'StatusDropdownContent'; +}; diff --git a/web/src/components/ui/dropdown/DropdownBase.tsx b/web/src/components/ui/dropdown/DropdownBase.tsx index 2aa44dcef..7373e8592 100644 --- a/web/src/components/ui/dropdown/DropdownBase.tsx +++ b/web/src/components/ui/dropdown/DropdownBase.tsx @@ -91,7 +91,7 @@ const DropdownMenuItem = React.forwardRef< ref={ref} className={cn( 'relative flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-base outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0', - 'focus:bg-item-hover focus:text-foreground', + 'focus:bg-item-select focus:text-foreground', 'dropdown-item mx-1 [&.dropdown-item:first-child]:mt-1! [&.dropdown-item:has(+.dropdown-separator)]:mb-1 [&.dropdown-item:has(~.dropdown-separator)]:mt-1 [&.dropdown-item:last-child]:mb-1!', inset && 'pl-8', truncate && 'overflow-hidden', @@ -132,7 +132,7 @@ const DropdownMenuCheckboxItemSingle = React.forwardRef< ) => ( { if (closeOnSelect) { @@ -143,9 +143,9 @@ const DropdownMenuCheckboxItemSingle = React.forwardRef< }} {...props}> {children} - + -
+
diff --git a/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricThreeDotMenu.tsx b/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricThreeDotMenu.tsx index c1f930836..bd2b2cf36 100644 --- a/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricThreeDotMenu.tsx +++ b/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/MetricContainerHeaderButtons/MetricThreeDotMenu.tsx @@ -4,7 +4,8 @@ import { useRemoveMetricFromCollection, useRemoveMetricFromDashboard, useSaveMetricToCollection, - useSaveMetricToDashboard + useSaveMetricToDashboard, + useUpdateMetric } from '@/api/buster_rest/metrics'; import { DropdownContent, DropdownItem, DropdownItems } from '@/components/ui/dropdown'; import { @@ -33,6 +34,9 @@ import { StatusNotRequestedIcon } from '@/assets'; import { useSaveToDashboardDropdownContent } from '@/components/features/dropdowns/SaveToDashboardDropdown'; import { useMemoizedFn } from '@/hooks'; import { useSaveToCollectionsDropdownContent } from '@/components/features/dropdowns/SaveToCollectionsDropdown'; +import { VerificationStatus } from '@/api/asset_interfaces/share'; +import { useStatusDropdownContent } from '@/components/features/metrics/StatusBadgeIndicator/StatusDropdownContent'; +import { StatusBadgeIndicator } from '@/components/features/metrics/StatusBadgeIndicator'; export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string }) => { const { mutateAsync: deleteMetric, isPending: isDeletingMetric } = useDeleteMetric(); @@ -40,8 +44,9 @@ export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string } const onSetSelectedFile = useChatLayoutContextSelector((x) => x.onSetSelectedFile); const dashboardSelectMenu = useDashboardSelectMenu({ metricId }); - const versionHistoryItems = useVersionHistoryItems({ metricId }); + const versionHistoryItems = useVersionHistorySelectMenu({ metricId }); const collectionSelectMenu = useCollectionSelectMenu({ metricId }); + const statusSelectMenu = useStatusSelectMenu({ metricId }); const items: DropdownItems = useMemo( () => [ @@ -54,15 +59,7 @@ export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string } console.log('share metric'); } }, - { - label: 'Request verification', - value: 'request-verification', - icon: , - items: [], - onClick: () => { - console.log('share metric'); - } - }, + statusSelectMenu, { type: 'divider' }, dashboardSelectMenu, collectionSelectMenu, @@ -193,10 +190,7 @@ const useDashboardSelectMenu = ({ metricId }: { metricId: string }) => { label: 'Add to dashboard', value: 'add-to-dashboard', icon: , - items: [{dashboardSubMenu}], - onClick: () => { - console.log('add to dashboard'); - } + items: [{dashboardSubMenu}] }), [dashboardSubMenu] ); @@ -204,7 +198,7 @@ const useDashboardSelectMenu = ({ metricId }: { metricId: string }) => { return dashboardDropdownItem; }; -const useVersionHistoryItems = ({ metricId }: { metricId: string }) => { +const useVersionHistorySelectMenu = ({ metricId }: { metricId: string }) => { const { data } = useGetMetric(metricId, (x) => ({ versions: x.versions, version_number: x.version_number @@ -276,13 +270,41 @@ const useCollectionSelectMenu = ({ metricId }: { metricId: string }) => { {collectionSubMenu} {modal} - ], - onClick: () => { - console.log('add to collection'); - } + ] }), [collectionSubMenu] ); return collectionDropdownItem; }; + +const useStatusSelectMenu = ({ metricId }: { metricId: string }) => { + const { data: metric } = useGetMetric(metricId, (x) => x); + const { mutateAsync: updateMetric } = useUpdateMetric(); + + const onChangeStatus = useMemoizedFn(async (status: VerificationStatus) => { + await updateMetric({ id: metricId, status }); + }); + + const dropdownProps = useStatusDropdownContent({ + isAdmin: true, + selectedStatus: metric?.status || VerificationStatus.NOT_REQUESTED, + onChangeStatus + }); + + const statusSubMenu = useMemo(() => { + return ; + }, [dropdownProps]); + + const statusDropdownItem: DropdownItem = useMemo( + () => ({ + label: 'Status', + value: 'status', + icon: , + items: [{statusSubMenu}] + }), + [statusSubMenu] + ); + + return statusDropdownItem; +};