remove additional context layers for dashboard

This commit is contained in:
Nate Kelley 2025-03-12 17:12:27 -06:00
parent 76254339e9
commit ee6686448d
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
17 changed files with 96 additions and 175 deletions

View File

@ -6,19 +6,27 @@ import {
dashboardsUpdateDashboard, dashboardsUpdateDashboard,
dashboardsDeleteDashboard dashboardsDeleteDashboard
} from './requests'; } from './requests';
import type { import type { DashboardsListRequest } from '@/api/request_interfaces/dashboards/interfaces';
DashboardsListRequest,
DashboardCreateRequest,
DashboardUpdateRequest,
DashboardDeleteRequest
} from '@/api/request_interfaces/dashboards/interfaces';
import { dashboardQueryKeys } from '@/api/query_keys/dashboard'; import { dashboardQueryKeys } from '@/api/query_keys/dashboard';
import { BusterDashboard } from '@/api/asset_interfaces/dashboard'; import { BusterDashboard } from '@/api/asset_interfaces/dashboard';
import { useMemo } from 'react';
import { useMemoizedFn } from '@/hooks';
import { useBusterNotifications } from '@/context/BusterNotifications';
export const useGetDashboardsList = (
params: Omit<DashboardsListRequest, 'page_token' | 'page_size'>
) => {
const filters = useMemo(() => {
return {
...params,
page_token: 0,
page_size: 3000
};
}, [params]);
export const useGetDashboardsList = (params: DashboardsListRequest) => {
return useQuery({ return useQuery({
...dashboardQueryKeys.dashboardGetList(params), ...dashboardQueryKeys.dashboardGetList(filters),
queryFn: () => dashboardsGetList(params) queryFn: () => dashboardsGetList(filters)
}); });
}; };
@ -68,12 +76,44 @@ export const useUpdateDashboard = () => {
export const useDeleteDashboards = () => { export const useDeleteDashboards = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const { openConfirmModal } = useBusterNotifications();
const onDeleteDashboard = useMemoizedFn(
async ({
dashboardId,
ignoreConfirm
}: {
dashboardId: string | string[];
ignoreConfirm?: boolean;
}) => {
const method = () => {
const ids = typeof dashboardId === 'string' ? [dashboardId] : dashboardId;
dashboardsDeleteDashboard({ ids });
};
if (ignoreConfirm) {
return method();
}
return await openConfirmModal({
title: 'Delete Dashboard',
content: 'Are you sure you want to delete this dashboard?',
onOk: () => {
method();
},
useReject: true
});
}
);
return useMutation({ return useMutation({
mutationFn: dashboardsDeleteDashboard, mutationFn: onDeleteDashboard,
onMutate: (variables) => { onMutate: (variables) => {
const queryKey = dashboardQueryKeys.dashboardGetList({}).queryKey; const queryKey = dashboardQueryKeys.dashboardGetList({}).queryKey;
queryClient.setQueryData(queryKey, (v) => { queryClient.setQueryData(queryKey, (v) => {
return v?.filter((t) => !variables.ids.includes(t.id)) || []; const ids =
typeof variables.dashboardId === 'string'
? [variables.dashboardId]
: variables.dashboardId;
return v?.filter((t) => !ids.includes(t.id)) || [];
}); });
} }
}); });

View File

@ -8,7 +8,9 @@ import { DashboardsListRequest } from '../request_interfaces/dashboards/interfac
const dashboardGetList = (filters: Omit<DashboardsListRequest, 'page_token' | 'page_size'>) => const dashboardGetList = (filters: Omit<DashboardsListRequest, 'page_token' | 'page_size'>) =>
queryOptions<BusterDashboardListItem[]>({ queryOptions<BusterDashboardListItem[]>({
queryKey: ['dashboard', 'list', filters] as const, queryKey: ['dashboard', 'list', filters] as const,
staleTime: 10 * 1000 staleTime: 10 * 1000,
initialData: [],
initialDataUpdatedAt: 0
}); });
const dashboardGetDashboard = (dashboardId: string) => const dashboardGetDashboard = (dashboardId: string) =>

View File

@ -39,7 +39,7 @@ export interface DashboardUnsubscribeRequest {
*/ */
export interface DashboardCreateRequest { export interface DashboardCreateRequest {
/** The name of the dashboard */ /** The name of the dashboard */
name: string; name?: string;
/** Optional description of the dashboard */ /** Optional description of the dashboard */
description?: string | null; description?: string | null;
} }

View File

@ -1,8 +1,4 @@
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout'; import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
import {
useBusterDashboardContextSelector,
useBusterDashboardListByFilter
} from '@/context/Dashboards';
import { useMemoizedFn } from '@/hooks'; import { useMemoizedFn } from '@/hooks';
import React, { useMemo, useState } from 'react'; import React, { useMemo, useState } from 'react';
import { BusterRoutes, createBusterRoute } from '@/routes/busterRoutes'; import { BusterRoutes, createBusterRoute } from '@/routes/busterRoutes';
@ -11,6 +7,7 @@ import { Dropdown, type DropdownProps } from '@/components/ui/dropdown/Dropdown'
import { AppTooltip } from '@/components/ui/tooltip'; import { AppTooltip } from '@/components/ui/tooltip';
import { Plus } from '@/components/ui/icons'; import { Plus } from '@/components/ui/icons';
import type { BusterMetric, BusterDashboardListItem } from '@/api/asset_interfaces'; import type { BusterMetric, BusterDashboardListItem } from '@/api/asset_interfaces';
import { useCreateDashboard, useGetDashboardsList } from '@/api/buster_rest/dashboards';
export const SaveToDashboardDropdown: React.FC<{ export const SaveToDashboardDropdown: React.FC<{
children: React.ReactNode; children: React.ReactNode;
@ -18,10 +15,9 @@ export const SaveToDashboardDropdown: React.FC<{
onSaveToDashboard: (dashboardId: string[]) => Promise<void>; onSaveToDashboard: (dashboardId: string[]) => Promise<void>;
onRemoveFromDashboard: (dashboardId: string) => void; onRemoveFromDashboard: (dashboardId: string) => void;
}> = ({ children, onRemoveFromDashboard, onSaveToDashboard, selectedDashboards }) => { }> = ({ children, onRemoveFromDashboard, onSaveToDashboard, selectedDashboards }) => {
const onCreateNewDashboard = useBusterDashboardContextSelector((x) => x.onCreateNewDashboard); const { mutateAsync: createDashboard, isPending: isCreatingDashboard } = useCreateDashboard();
const isCreatingDashboard = useBusterDashboardContextSelector((x) => x.isCreatingDashboard);
const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage); const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
const { list: dashboardsList } = useBusterDashboardListByFilter({}); const { data: dashboardsList } = useGetDashboardsList({});
const [showDropdown, setShowDropdown] = useState(false); const [showDropdown, setShowDropdown] = useState(false);
@ -53,22 +49,13 @@ export const SaveToDashboardDropdown: React.FC<{
); );
const onClickNewDashboardButton = useMemoizedFn(async () => { const onClickNewDashboardButton = useMemoizedFn(async () => {
const res = await onCreateNewDashboard({ const res = await createDashboard({});
rerouteToDashboard: false
});
if (res?.id) { if (res?.dashboard?.id) {
await onSaveToDashboard([res.id]); await onSaveToDashboard([res.dashboard.id]);
// await saveMetricToDashboard({
// metricId,
// dashboardIds: [res.id]
// });
}
if (res?.id) {
onChangePage({ onChangePage({
route: BusterRoutes.APP_DASHBOARD_ID, route: BusterRoutes.APP_DASHBOARD_ID,
dashboardId: res.id dashboardId: res.dashboard.id
}); });
} }

View File

@ -5,7 +5,6 @@ import { useMemoizedFn } from '@/hooks';
import { createContext, useContextSelector } from 'use-context-selector'; import { createContext, useContextSelector } from 'use-context-selector';
import { queryKeys } from '@/api/query_keys'; import { queryKeys } from '@/api/query_keys';
import { useDashboardAssosciations } from './useDashboardAssosciations'; import { useDashboardAssosciations } from './useDashboardAssosciations';
import { useDashboardCreate } from './useDashboardCreate';
import { useDashboardUpdateConfig } from './useDashboardUpdateConfig'; import { useDashboardUpdateConfig } from './useDashboardUpdateConfig';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
@ -27,13 +26,8 @@ export const useBusterDashboards = () => {
updateDashboardMutation updateDashboardMutation
}); });
const dashboardCreate = useDashboardCreate({
onUpdateDashboard
});
return { return {
...dashboardAssosciations, ...dashboardAssosciations,
...dashboardCreate,
...dashboardUpdateConfig, ...dashboardUpdateConfig,
getDashboardMemoized getDashboardMemoized
}; };

View File

@ -1,25 +0,0 @@
import { BusterDashboard, VerificationStatus } from '@/api/asset_interfaces';
export const defaultBusterDashboard: BusterDashboard = {
id: '',
config: {
rows: []
},
created_at: '',
deleted_at: '',
description: '',
name: '',
updated_at: '',
created_by: '',
updated_by: '',
public_expiry_date: null,
publicly_accessible: false,
password_secret_id: null,
sharingKey: '',
public_enabled_by: '',
status: VerificationStatus.NOT_REQUESTED,
public_password: null,
version_number: 1,
file: '',
file_name: ''
};

View File

@ -1,66 +0,0 @@
import { useBusterNotifications } from '@/context/BusterNotifications';
import { BusterRoutes } from '@/routes/busterRoutes';
import { useMemoizedFn } from '@/hooks';
import { useQueryClient } from '@tanstack/react-query';
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
import { useCreateDashboard, useDeleteDashboards } from '@/api/buster_rest/dashboards';
export const useDashboardCreate = ({}: {}) => {
const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
const queryClient = useQueryClient();
const { mutateAsync: deleteDashboard, isPending: isDeletingDashboard } = useDeleteDashboards();
const { openConfirmModal } = useBusterNotifications();
const { mutateAsync: createDashboard, isPending: isCreatingDashboard } = useCreateDashboard();
const onCreateNewDashboard = useMemoizedFn(
async (newDashboard: {
name?: string;
description?: string | null;
rerouteToDashboard?: boolean;
}) => {
if (isCreatingDashboard) {
return;
}
const { rerouteToDashboard, ...rest } = newDashboard;
const res = await createDashboard({ ...rest, name: rest.name || '' });
if (rerouteToDashboard) {
onChangePage({
route: BusterRoutes.APP_DASHBOARD_ID,
dashboardId: res.dashboard.id
});
}
return res.dashboard;
}
);
const onDeleteDashboard = useMemoizedFn(
async (dashboardId: string | string[], ignoreConfirm?: boolean) => {
const method = () => {
const ids = typeof dashboardId === 'string' ? [dashboardId] : dashboardId;
deleteDashboard({ ids });
};
if (ignoreConfirm) {
return method();
}
return await openConfirmModal({
title: 'Delete Dashboard',
content: 'Are you sure you want to delete this dashboard?',
onOk: () => {
method();
},
useReject: true
});
}
);
return {
onCreateNewDashboard,
isCreatingDashboard,
onDeleteDashboard,
isDeletingDashboard
};
};

View File

@ -5,7 +5,6 @@ import {
} from '@/api/asset_interfaces'; } from '@/api/asset_interfaces';
import { useMemoizedFn } from '@/hooks'; import { useMemoizedFn } from '@/hooks';
import { create } from 'mutative'; import { create } from 'mutative';
import { useQueryClient } from '@tanstack/react-query';
import { useUpdateDashboard } from '@/api/buster_rest/dashboards'; import { useUpdateDashboard } from '@/api/buster_rest/dashboards';
import type { DashboardUpdateRequest } from '@/api/request_interfaces/dashboards/interfaces'; import type { DashboardUpdateRequest } from '@/api/request_interfaces/dashboards/interfaces';

View File

@ -1 +0,0 @@
export * from './useBusterDashboardListByFilter';

View File

@ -1,17 +0,0 @@
import { useGetDashboardsList } from '@/api/buster_rest/dashboards';
import { DashboardsListRequest } from '@/api/request_interfaces/dashboards/interfaces';
export const useBusterDashboardListByFilter = (
filters: Omit<DashboardsListRequest, 'page_token' | 'page_size'>
) => {
const { data: dashboardsList, isFetched: isFetchedDashboardsList } = useGetDashboardsList({
...filters,
page_token: 0,
page_size: 3000
});
return {
list: dashboardsList,
isFetchedDashboardsList
};
};

View File

@ -1,3 +1,2 @@
export * from './DashboardProvider'; export * from './DashboardProvider';
export * from './DashboardListProvider';
export * from './DashboardIndividualProvider'; export * from './DashboardIndividualProvider';

View File

@ -9,6 +9,8 @@ import { AppSegmented, SegmentedItem } from '@/components/ui/segmented';
import { useMemoizedFn } from '@/hooks'; import { useMemoizedFn } from '@/hooks';
import { Plus } from '@/components/ui/icons'; import { Plus } from '@/components/ui/icons';
import type { DashboardsListRequest } from '@/api/request_interfaces/dashboards'; import type { DashboardsListRequest } from '@/api/request_interfaces/dashboards';
import { useCreateDashboard } from '@/api/buster_rest/dashboards';
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
export const DashboardHeader: React.FC<{ export const DashboardHeader: React.FC<{
dashboardFilters: { dashboardFilters: {
@ -20,12 +22,8 @@ export const DashboardHeader: React.FC<{
only_my_dashboards?: boolean; only_my_dashboards?: boolean;
}) => void; }) => void;
}> = React.memo(({ dashboardFilters, onSetDashboardListFilters }) => { }> = React.memo(({ dashboardFilters, onSetDashboardListFilters }) => {
const onCreateNewDashboard = useBusterDashboardContextSelector( const { mutateAsync: createDashboard, isPending: isCreatingDashboard } = useCreateDashboard();
(state) => state.onCreateNewDashboard const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
);
const isCreatingDashboard = useBusterDashboardContextSelector(
(state) => state.isCreatingDashboard
);
const dashboardTitle = 'Dashboards'; const dashboardTitle = 'Dashboards';
const showFilters = true; const showFilters = true;
@ -42,7 +40,13 @@ export const DashboardHeader: React.FC<{
); );
const onClickNewDashboardButton = useMemoizedFn(async () => { const onClickNewDashboardButton = useMemoizedFn(async () => {
await onCreateNewDashboard({ rerouteToDashboard: true }); const res = await createDashboard({});
if (res?.dashboard?.id) {
onChangePage({
route: BusterRoutes.APP_DASHBOARD_ID,
dashboardId: res.dashboard.id
});
}
}); });
return ( return (

View File

@ -1,7 +1,6 @@
'use client'; 'use client';
import React, { useMemo, useState } from 'react'; import React, { useMemo, useState } from 'react';
import { useBusterDashboardContextSelector } from '@/context/Dashboards';
import { Avatar } from '@/components/ui/avatar'; import { Avatar } from '@/components/ui/avatar';
import { formatDate } from '@/lib'; import { formatDate } from '@/lib';
import { import {
@ -15,6 +14,8 @@ import { useMemoizedFn } from '@/hooks';
import { DashboardSelectedOptionPopup } from './DashboardSelectedPopup'; import { DashboardSelectedOptionPopup } from './DashboardSelectedPopup';
import type { BusterDashboardListItem } from '@/api/asset_interfaces'; 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 { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
const columns: BusterListColumn[] = [ const columns: BusterListColumn[] = [
{ {
@ -58,12 +59,8 @@ export const DashboardListContent: React.FC<{
dashboardsList: BusterDashboardListItem[]; dashboardsList: BusterDashboardListItem[];
className?: string; className?: string;
}> = React.memo(({ loading, dashboardsList, className = '' }) => { }> = React.memo(({ loading, dashboardsList, className = '' }) => {
const onCreateNewDashboard = useBusterDashboardContextSelector( const { mutateAsync: createDashboard, isPending: isCreatingDashboard } = useCreateDashboard();
(state) => state.onCreateNewDashboard const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
);
const isCreatingDashboard = useBusterDashboardContextSelector(
(state) => state.isCreatingDashboard
);
const [selectedDashboardIds, setSelectedDashboardIds] = useState<string[]>([]); const [selectedDashboardIds, setSelectedDashboardIds] = useState<string[]>([]);
const rows: BusterListRow[] = useMemo(() => { const rows: BusterListRow[] = useMemo(() => {
@ -80,7 +77,13 @@ export const DashboardListContent: React.FC<{
}, [dashboardsList]); }, [dashboardsList]);
const onClickEmptyState = useMemoizedFn(async () => { const onClickEmptyState = useMemoizedFn(async () => {
await onCreateNewDashboard({ rerouteToDashboard: true }); const res = await createDashboard({});
if (res?.dashboard?.id) {
onChangePage({
route: BusterRoutes.APP_DASHBOARD_ID,
dashboardId: res.dashboard.id
});
}
}); });
return ( return (

View File

@ -3,15 +3,16 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { DashboardHeader } from './DashboardHeader'; import { DashboardHeader } from './DashboardHeader';
import { DashboardListContent } from './DashboardListContent'; import { DashboardListContent } from './DashboardListContent';
import { useBusterDashboardListByFilter } from '@/context/Dashboards';
import { AppPageLayout } from '@/components/ui/layouts'; import { AppPageLayout } from '@/components/ui/layouts';
import { useGetDashboardsList } from '@/api/buster_rest/dashboards';
export const DashboardListController: React.FC = () => { export const DashboardListController: React.FC = () => {
const [dashboardListFilters, setDashboardListFilters] = useState<{ const [dashboardListFilters, setDashboardListFilters] = useState<{
shared_with_me?: boolean; shared_with_me?: boolean;
only_my_dashboards?: boolean; only_my_dashboards?: boolean;
}>({}); }>({});
const { list, isFetchedDashboardsList } = useBusterDashboardListByFilter(dashboardListFilters); const { data: dashboardsList, isFetched: isFetchedDashboardsList } =
useGetDashboardsList(dashboardListFilters);
return ( return (
<AppPageLayout <AppPageLayout
@ -21,7 +22,7 @@ export const DashboardListController: React.FC = () => {
onSetDashboardListFilters={setDashboardListFilters} onSetDashboardListFilters={setDashboardListFilters}
/> />
}> }>
<DashboardListContent loading={!isFetchedDashboardsList} dashboardsList={list || []} /> <DashboardListContent loading={!isFetchedDashboardsList} dashboardsList={dashboardsList} />
</AppPageLayout> </AppPageLayout>
); );
}; };

View File

@ -2,7 +2,6 @@ import React, { useState } from 'react';
import { BusterListSelectedOptionPopupContainer } from '@/components/ui/list'; import { BusterListSelectedOptionPopupContainer } from '@/components/ui/list';
import { Dropdown, DropdownItems } from '@/components/ui/dropdown'; import { Dropdown, DropdownItems } from '@/components/ui/dropdown';
import { Button } from '@/components/ui/buttons'; import { Button } from '@/components/ui/buttons';
import { useUserConfigContextSelector } from '@/context/Users';
import { useMemoizedFn } from '@/hooks'; import { useMemoizedFn } from '@/hooks';
import { useBusterNotifications } from '@/context/BusterNotifications'; import { useBusterNotifications } from '@/context/BusterNotifications';
import { SaveToCollectionsDropdown } from '@/components/features/dropdowns/SaveToCollectionsDropdown'; import { SaveToCollectionsDropdown } from '@/components/features/dropdowns/SaveToCollectionsDropdown';
@ -15,6 +14,7 @@ import {
useGetUserFavorites useGetUserFavorites
} from '@/api/buster_rest/users'; } from '@/api/buster_rest/users';
import { ShareAssetType } from '@/api/asset_interfaces/share'; import { ShareAssetType } from '@/api/asset_interfaces/share';
import { useDeleteDashboards } from '@/api/buster_rest/dashboards';
export const DashboardSelectedOptionPopup: React.FC<{ export const DashboardSelectedOptionPopup: React.FC<{
selectedRowKeys: string[]; selectedRowKeys: string[];
@ -100,7 +100,7 @@ const DeleteButton: React.FC<{
selectedRowKeys: string[]; selectedRowKeys: string[];
onSelectChange: (selectedRowKeys: string[]) => void; onSelectChange: (selectedRowKeys: string[]) => void;
}> = ({ selectedRowKeys, onSelectChange }) => { }> = ({ selectedRowKeys, onSelectChange }) => {
const onDeleteDashboard = useBusterDashboardContextSelector((state) => state.onDeleteDashboard); const { mutateAsync: deleteDashboard, isPending: isDeletingDashboard } = useDeleteDashboards();
const { openConfirmModal } = useBusterNotifications(); const { openConfirmModal } = useBusterNotifications();
const onDeleteClick = useMemoizedFn(async () => { const onDeleteClick = useMemoizedFn(async () => {
@ -108,7 +108,7 @@ const DeleteButton: React.FC<{
title: 'Delete dashboard', title: 'Delete dashboard',
content: 'Are you sure you want to delete these dashboards?', content: 'Are you sure you want to delete these dashboards?',
onOk: async () => { onOk: async () => {
await onDeleteDashboard(selectedRowKeys, true); await deleteDashboard({ dashboardId: selectedRowKeys });
onSelectChange([]); onSelectChange([]);
} }
}); });

View File

@ -13,6 +13,7 @@ import { Dots, Plus, Trash } from '@/components/ui/icons';
import { useBusterDashboardContextSelector } from '@/context/Dashboards'; import { useBusterDashboardContextSelector } from '@/context/Dashboards';
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout'; import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
import { BusterRoutes } from '@/routes'; import { BusterRoutes } from '@/routes';
import { useDeleteDashboards } from '@/api/buster_rest/dashboards';
export const DashboardContainerHeaderButtons: React.FC<FileContainerButtonsProps> = React.memo( export const DashboardContainerHeaderButtons: React.FC<FileContainerButtonsProps> = React.memo(
() => { () => {
@ -50,7 +51,7 @@ const AddContentToDashboardButton = React.memo(() => {
AddContentToDashboardButton.displayName = 'AddContentToDashboardButton'; AddContentToDashboardButton.displayName = 'AddContentToDashboardButton';
const ThreeDotMenu = React.memo(({ dashboardId }: { dashboardId: string }) => { const ThreeDotMenu = React.memo(({ dashboardId }: { dashboardId: string }) => {
const onDeleteDashboard = useBusterDashboardContextSelector((x) => x.onDeleteDashboard); const { mutateAsync: deleteDashboard, isPending: isDeletingDashboard } = useDeleteDashboards();
const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage); const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
const items: DropdownItems = useMemo(() => { const items: DropdownItems = useMemo(() => {
@ -60,12 +61,12 @@ const ThreeDotMenu = React.memo(({ dashboardId }: { dashboardId: string }) => {
value: 'delete', value: 'delete',
icon: <Trash />, icon: <Trash />,
onClick: async () => { onClick: async () => {
await onDeleteDashboard(dashboardId); await deleteDashboard({ dashboardId });
onChangePage({ route: BusterRoutes.APP_DASHBOARDS }); onChangePage({ route: BusterRoutes.APP_DASHBOARDS });
} }
} }
]; ];
}, [dashboardId, onDeleteDashboard, onChangePage]); }, [dashboardId, deleteDashboard, onChangePage]);
return ( return (
<Dropdown items={items}> <Dropdown items={items}>

View File

@ -4,7 +4,7 @@ import {
VerificationStatus VerificationStatus
} from '@/api/asset_interfaces'; } from '@/api/asset_interfaces';
import { ShareRole } from '@/api/asset_interfaces'; import { ShareRole } from '@/api/asset_interfaces';
import { createMockMetric } from '../../../mocks/metric'; import { createMockMetric } from './metric';
interface DashboardMockResponse { interface DashboardMockResponse {
dashboard: BusterDashboard; dashboard: BusterDashboard;