mirror of https://github.com/buster-so/buster.git
add additional routes to new handlers
This commit is contained in:
parent
0ee588a6c5
commit
4d4ab66e2c
|
@ -40,7 +40,7 @@ export interface BusterDashboard
|
|||
deleted_at: string | null;
|
||||
description: string | null;
|
||||
id: string;
|
||||
title: string;
|
||||
name: string;
|
||||
updated_at: string | null;
|
||||
updated_by: string;
|
||||
status: VerificationStatus;
|
||||
|
|
|
@ -38,7 +38,7 @@ export interface BusterUserFavorite {
|
|||
id: string;
|
||||
asset_type: ShareAssetType;
|
||||
index?: number;
|
||||
title: string;
|
||||
name: string;
|
||||
//collections - TODO: type this better
|
||||
collection_name?: string;
|
||||
collection_id?: string;
|
||||
|
|
|
@ -87,8 +87,8 @@ export type DashboardUpdate = BusterSocketRequestBase<
|
|||
{
|
||||
/** The unique identifier of the dashboard */
|
||||
id: string;
|
||||
/** New title for the dashboard */
|
||||
title?: string;
|
||||
/** New name for the dashboard */
|
||||
name?: string;
|
||||
/** New description for the dashboard */
|
||||
description?: string | null;
|
||||
/** Updated dashboard configuration */
|
||||
|
|
|
@ -31,7 +31,7 @@ export type UsersFavoritePost = BusterSocketRequestBase<
|
|||
id: string;
|
||||
asset_type: ShareAssetType;
|
||||
index?: number;
|
||||
title: string; //sooo... this is a bit of hack...
|
||||
name: string;
|
||||
}
|
||||
>;
|
||||
|
||||
|
|
|
@ -14,7 +14,10 @@ import { CircleSpinnerLoaderContainer } from '@/components/loaders';
|
|||
import { BusterCollection } from '@/api/asset_interfaces';
|
||||
import { useBusterSearchContextSelector } from '@/context/Search';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { useBusterDashboardContextSelector } from '@/context/Dashboards';
|
||||
import {
|
||||
useBusterDashboardContextSelector,
|
||||
useBusterDashboardIndividual
|
||||
} from '@/context/Dashboards';
|
||||
import { useBusterCollectionIndividualContextSelector } from '@/context/Collections';
|
||||
import { SegmentedValue } from 'antd/es/segmented';
|
||||
import { BusterSearchRequest } from '@/api/buster_socket/search';
|
||||
|
|
|
@ -32,7 +32,7 @@ export const FavoriteStar: React.FC<{
|
|||
title: string;
|
||||
className?: string;
|
||||
iconStyle?: 'default' | 'tertiary';
|
||||
}> = React.memo(({ title, id, type, className = '', iconStyle = 'default' }) => {
|
||||
}> = React.memo(({ title: name, id, type, className = '', iconStyle = 'default' }) => {
|
||||
const userFavorites = useUserConfigContextSelector((state) => state.userFavorites);
|
||||
const removeItemFromFavorite = useUserConfigContextSelector(
|
||||
(state) => state.removeItemFromFavorite
|
||||
|
@ -51,7 +51,7 @@ export const FavoriteStar: React.FC<{
|
|||
return await addItemToFavorite({
|
||||
asset_type: type,
|
||||
id,
|
||||
title
|
||||
name
|
||||
});
|
||||
|
||||
await removeItemFromFavorite({
|
||||
|
|
|
@ -38,13 +38,16 @@ export const StatusBadgeButton: React.FC<{
|
|||
if ((!isAdmin && !userStatus.includes(newStatus)) || newStatus === status) {
|
||||
return;
|
||||
}
|
||||
const ids = Array.isArray(id) ? id : [id];
|
||||
|
||||
const verifyFunction =
|
||||
type === 'dashboard'
|
||||
? (id: string) => onVerifiedDashboard({ dashboardId: id, status: newStatus })
|
||||
: (id: string) => onVerifiedMetric({ metricId: id, status: newStatus });
|
||||
|
||||
const ids = Array.isArray(id) ? id : [id];
|
||||
await Promise.all(ids.map(verifyFunction));
|
||||
const allPromises = ids.map((id) => verifyFunction(id));
|
||||
|
||||
await Promise.all(allPromises);
|
||||
setIsOpen(false);
|
||||
onChangedStatus?.();
|
||||
});
|
||||
|
|
|
@ -111,19 +111,20 @@ const createListItem = ({
|
|||
let icon = asset_typeToIcon(item.asset_type, {
|
||||
open: openedIds.includes(item.collection_id || '')
|
||||
});
|
||||
let name = item.title || item.collection_name;
|
||||
let name = item.name || item.collection_name;
|
||||
const assetType = item.asset_type;
|
||||
|
||||
if (item.title === ShareAssetType.METRIC) {
|
||||
if (assetType === ShareAssetType.METRIC) {
|
||||
link = createBusterRoute({
|
||||
route: BusterRoutes.APP_METRIC_ID,
|
||||
metricId: item.id
|
||||
});
|
||||
} else if (item.title === ShareAssetType.DASHBOARD) {
|
||||
} else if (assetType === ShareAssetType.DASHBOARD) {
|
||||
link = createBusterRoute({
|
||||
route: BusterRoutes.APP_DASHBOARD_ID,
|
||||
dashboardId: item.id
|
||||
});
|
||||
} else if (item.title === ShareAssetType.COLLECTION) {
|
||||
} else if (assetType === ShareAssetType.COLLECTION) {
|
||||
link = createBusterRoute({
|
||||
route: BusterRoutes.APP_COLLECTIONS_ID,
|
||||
collectionId: item.collection_id!
|
||||
|
|
|
@ -21,8 +21,8 @@ const DEFAULT_EMPTY_CONFIG: DashboardConfig = {};
|
|||
|
||||
export const DashboardContentController: React.FC<{
|
||||
allowEdit?: boolean;
|
||||
metrics: BusterDashboardResponse['metrics'];
|
||||
dashboard: BusterDashboardResponse['dashboard'];
|
||||
metrics: BusterDashboardResponse['metrics'] | undefined;
|
||||
dashboard: BusterDashboardResponse['dashboard'] | undefined;
|
||||
onUpdateDashboardConfig: ReturnType<typeof useBusterDashboards>['onUpdateDashboardConfig'];
|
||||
openAddContentModal: () => void;
|
||||
}> = React.memo(
|
||||
|
@ -33,7 +33,7 @@ export const DashboardContentController: React.FC<{
|
|||
metrics = DEFAULT_EMPTY_METRICS,
|
||||
onUpdateDashboardConfig
|
||||
}) => {
|
||||
const dashboardConfig = dashboard.config || DEFAULT_EMPTY_CONFIG;
|
||||
const dashboardConfig = dashboard?.config || DEFAULT_EMPTY_CONFIG;
|
||||
const configRows = dashboardConfig?.rows || DEFAULT_EMPTY_ROWS;
|
||||
const hasMetrics = !isEmpty(metrics);
|
||||
const [draggingId, setDraggingId] = useState<string | null>(null);
|
||||
|
@ -52,7 +52,7 @@ export const DashboardContentController: React.FC<{
|
|||
}))
|
||||
};
|
||||
});
|
||||
onUpdateDashboardConfig({ rows: formattedRows }, dashboard.id);
|
||||
onUpdateDashboardConfig({ rows: formattedRows }, dashboard!.id);
|
||||
});
|
||||
|
||||
const remapMetrics = useMemo(() => {
|
||||
|
@ -77,7 +77,7 @@ export const DashboardContentController: React.FC<{
|
|||
<DashboardMetricItem
|
||||
key={item.id}
|
||||
metricId={item.id}
|
||||
dashboardId={dashboard.id}
|
||||
dashboardId={dashboard!.id}
|
||||
allowEdit={allowEdit}
|
||||
numberOfMetrics={metrics.length}
|
||||
/>
|
||||
|
@ -97,14 +97,14 @@ export const DashboardContentController: React.FC<{
|
|||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (remapMetrics && dashboard.id) {
|
||||
if (remapMetrics && dashboard?.id) {
|
||||
debouncedForInitialRenderOnUpdateDashboardConfig({ rows }, dashboard.id);
|
||||
}
|
||||
}, [dashboard.id, remapMetrics]);
|
||||
}, [dashboard?.id, remapMetrics]);
|
||||
|
||||
return (
|
||||
<div className="dashboard-content-controller">
|
||||
{hasMetrics && !!dashboardRows.length ? (
|
||||
{hasMetrics && !!dashboardRows.length && !!dashboard ? (
|
||||
<DashboardContentControllerProvider dashboard={dashboard}>
|
||||
<BusterResizeableGrid
|
||||
rows={dashboardRows}
|
||||
|
|
|
@ -11,8 +11,8 @@ export const DashboardEditTitles: React.FC<{
|
|||
allowEdit?: boolean;
|
||||
dashboardId: string;
|
||||
}> = React.memo(({ onUpdateDashboard, allowEdit, title, description, dashboardId }) => {
|
||||
const onChangeTitle = useMemoizedFn((title: string) => {
|
||||
onUpdateDashboard({ title, id: dashboardId });
|
||||
const onChangeTitle = useMemoizedFn((name: string) => {
|
||||
onUpdateDashboard({ name, id: dashboardId });
|
||||
});
|
||||
|
||||
const onChangeDescription = useMemoizedFn((description: string) => {
|
||||
|
|
|
@ -2,8 +2,8 @@ import { useUserConfigContextSelector } from '@/context/Users';
|
|||
import { DashboardViewProps } from '../config';
|
||||
import React from 'react';
|
||||
import {
|
||||
useBusterDashboardIndividual,
|
||||
useBusterDashboardContextSelector
|
||||
useBusterDashboardContextSelector,
|
||||
useBusterDashboardIndividual
|
||||
} from '@/context/Dashboards';
|
||||
import { ShareRole } from '@/api/asset_interfaces';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
|
@ -12,7 +12,7 @@ import { DashboardContentController } from './DashboardContentController';
|
|||
|
||||
export const DashboardViewDashboardController: React.FC<DashboardViewProps> = ({ dashboardId }) => {
|
||||
const isAnonymousUser = useUserConfigContextSelector((state) => state.isAnonymousUser);
|
||||
const { dashboardResponse: dashboardResponse } = useBusterDashboardIndividual({
|
||||
const { dashboardResponse, metrics, dashboard } = useBusterDashboardIndividual({
|
||||
dashboardId
|
||||
});
|
||||
const onUpdateDashboard = useBusterDashboardContextSelector((x) => x.onUpdateDashboard);
|
||||
|
@ -21,8 +21,6 @@ export const DashboardViewDashboardController: React.FC<DashboardViewProps> = ({
|
|||
);
|
||||
const setOpenAddContentModal = useBusterDashboardContextSelector((x) => x.setOpenAddContentModal);
|
||||
|
||||
const metrics = dashboardResponse?.metrics;
|
||||
const dashboard = dashboardResponse?.dashboard;
|
||||
const allowEdit = dashboardResponse?.permission !== ShareRole.VIEWER && !isAnonymousUser;
|
||||
|
||||
const onOpenAddContentModal = useMemoizedFn(() => {
|
||||
|
@ -35,7 +33,7 @@ export const DashboardViewDashboardController: React.FC<DashboardViewProps> = ({
|
|||
onUpdateDashboard={onUpdateDashboard}
|
||||
dashboardId={dashboardId}
|
||||
allowEdit={allowEdit}
|
||||
title={dashboardResponse?.dashboard?.title || ''}
|
||||
title={dashboardResponse?.dashboard?.name || ''}
|
||||
description={dashboardResponse?.dashboard?.description || ''}
|
||||
/>
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ export const DashboardViewFileController: React.FC<DashboardViewProps> = React.m
|
|||
const { openSuccessMessage } = useBusterNotifications();
|
||||
const onUpdateDashboard = useBusterDashboardContextSelector((x) => x.onUpdateDashboard);
|
||||
|
||||
const { file: fileProp, file_name } = dashboard;
|
||||
const { file: fileProp, file_name } = dashboard || {};
|
||||
|
||||
const [file, setFile] = React.useState(fileProp);
|
||||
|
||||
|
@ -40,9 +40,9 @@ export const DashboardViewFileController: React.FC<DashboardViewProps> = React.m
|
|||
return (
|
||||
<div className="relative h-full overflow-hidden p-3">
|
||||
<CodeCard
|
||||
code={file}
|
||||
code={file || ''}
|
||||
language="yaml"
|
||||
fileName={file_name}
|
||||
fileName={file_name || ''}
|
||||
onChange={setFile}
|
||||
onMetaEnter={onSaveFile}
|
||||
/>
|
||||
|
|
|
@ -143,12 +143,10 @@ const useMetricParams = (fileId: string) => {
|
|||
};
|
||||
|
||||
const useDashboardParams = (fileId: string) => {
|
||||
const dashboardTitle = useBusterDashboardContextSelector(
|
||||
(x) => x.dashboards[fileId]?.dashboard?.title
|
||||
);
|
||||
const dashboardVersionNumber = useBusterDashboardContextSelector(
|
||||
(x) => x.dashboards[fileId]?.dashboard?.version_number
|
||||
);
|
||||
const getDashboardMemoized = useBusterDashboardContextSelector((x) => x.getDashboardMemoized);
|
||||
const dashboard = getDashboardMemoized(fileId);
|
||||
const dashboardTitle = dashboard?.dashboard?.name;
|
||||
const dashboardVersionNumber = dashboard?.dashboard?.version_number;
|
||||
|
||||
return { dashboardTitle, dashboardVersionNumber };
|
||||
};
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export * from './useFileFallback';
|
|
@ -1,141 +0,0 @@
|
|||
import type { SelectedFile } from '@appLayouts/ChatLayout';
|
||||
import { useBusterDashboardContextSelector } from '@/context/Dashboards';
|
||||
import { useBusterMetricsIndividualContextSelector } from '@/context/Metrics';
|
||||
import { useMemo } from 'react';
|
||||
import type { IBusterChat, IBusterChatMessage } from '../../interfaces';
|
||||
import { FileType } from '@/api/asset_interfaces';
|
||||
|
||||
export const useFileFallback = ({
|
||||
defaultSelectedFile
|
||||
}: {
|
||||
//if metricId is provided (without a chatId), we can assume that the chat is a new chat starting from a metric
|
||||
defaultSelectedFile?: SelectedFile;
|
||||
}) => {
|
||||
const fileId = defaultSelectedFile?.id || '';
|
||||
const { metricTitle, metricVersionNumber } = useMetricParams(fileId);
|
||||
const { dashboardTitle, dashboardVersionNumber } = useDashboardParams(fileId);
|
||||
|
||||
const fileType: FileType = useMemo(() => {
|
||||
if (defaultSelectedFile?.type === 'metric') {
|
||||
return 'metric';
|
||||
} else {
|
||||
return 'dashboard';
|
||||
}
|
||||
}, [defaultSelectedFile]);
|
||||
|
||||
const title = useMemo(() => {
|
||||
if (fileType === 'metric') {
|
||||
return metricTitle;
|
||||
} else if (fileType === 'dashboard') {
|
||||
return dashboardTitle;
|
||||
}
|
||||
}, [fileType, metricTitle, dashboardTitle]);
|
||||
|
||||
const versionNumber = useMemo(() => {
|
||||
if (fileType === 'metric') {
|
||||
return metricVersionNumber || 1;
|
||||
} else if (fileType === 'dashboard') {
|
||||
return dashboardVersionNumber || 1;
|
||||
}
|
||||
return 1;
|
||||
}, [fileType, metricVersionNumber, dashboardVersionNumber]);
|
||||
|
||||
const memoizedFallbackToMetricChat = useMemo(() => {
|
||||
return fallbackToFileChat({
|
||||
id: fileId
|
||||
});
|
||||
}, [fileId]);
|
||||
|
||||
const memoizedFallbackToChatMessage = useMemo(() => {
|
||||
return fallbackToFileChatMessage({
|
||||
id: fileId,
|
||||
title: title,
|
||||
versionNumber: versionNumber,
|
||||
type: fileType
|
||||
});
|
||||
}, [fileId, title, versionNumber, fileType]);
|
||||
|
||||
return { memoizedFallbackToMetricChat, memoizedFallbackToChatMessage };
|
||||
};
|
||||
|
||||
const fallbackToFileChat = ({ id }: { id: string }): IBusterChat => {
|
||||
return {
|
||||
id,
|
||||
messages: [fallbackMessageId(id)],
|
||||
title: '',
|
||||
is_favorited: false,
|
||||
updated_at: '',
|
||||
created_at: '',
|
||||
created_by: '',
|
||||
created_by_id: '',
|
||||
created_by_name: '',
|
||||
created_by_avatar: '',
|
||||
isNewChat: false
|
||||
};
|
||||
};
|
||||
|
||||
const fallbackMessageId = (id: string) => {
|
||||
return `init-message-${id}`;
|
||||
};
|
||||
|
||||
const fallbackToFileChatMessage = ({
|
||||
id,
|
||||
title,
|
||||
versionNumber,
|
||||
type = 'metric'
|
||||
}: {
|
||||
id: string;
|
||||
title: string | undefined;
|
||||
versionNumber: number;
|
||||
type: FileType;
|
||||
}): IBusterChatMessage => {
|
||||
return {
|
||||
request_message: null,
|
||||
reasoning: [],
|
||||
response_messages: [
|
||||
{
|
||||
id: 'init',
|
||||
type: 'text',
|
||||
message: `I've pulled in your ${type}. How can I help? Is there anything you'd like to modify?`
|
||||
},
|
||||
{
|
||||
id,
|
||||
type: 'file',
|
||||
file_type: type,
|
||||
file_name: title || `New ${type}`,
|
||||
version_number: versionNumber,
|
||||
version_id: id,
|
||||
filter_version_id: null,
|
||||
metadata: [
|
||||
{
|
||||
status: 'completed',
|
||||
message: `Retrieved ${type}`
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
created_at: '',
|
||||
id: fallbackMessageId(id),
|
||||
isCompletedStream: false
|
||||
};
|
||||
};
|
||||
|
||||
const useMetricParams = (fileId: string) => {
|
||||
const metricTitle = useBusterMetricsIndividualContextSelector((x) => x.metrics[fileId]?.title);
|
||||
const metricVersionNumber = useBusterMetricsIndividualContextSelector(
|
||||
(x) => x.metrics[fileId]?.version_number
|
||||
);
|
||||
|
||||
return { metricTitle, metricVersionNumber };
|
||||
};
|
||||
|
||||
const useDashboardParams = (fileId: string) => {
|
||||
const dashboardTitle = useBusterDashboardContextSelector(
|
||||
(x) => x.dashboards[fileId]?.dashboard?.title
|
||||
);
|
||||
const dashboardVersionNumber = useBusterDashboardContextSelector(
|
||||
(x) => x.dashboards[fileId]?.dashboard?.version_number
|
||||
);
|
||||
|
||||
return { dashboardTitle, dashboardVersionNumber };
|
||||
};
|
|
@ -8,38 +8,45 @@ import {
|
|||
import { BusterDashboardResponse } from '@/api/asset_interfaces';
|
||||
import { useDashboardAssosciations } from './useDashboardAssosciations';
|
||||
import { useDashboardCreate } from './useDashboardCreate';
|
||||
import { useShareDashboard } from './useDashboardShare';
|
||||
import { useDashboardSubscribe } from './useDashboardSubscribe';
|
||||
import { useDashboardUpdateConfig } from './useDashboardUpdateConfig';
|
||||
import { createQueryKey } from '@/hooks';
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useBusterAssetsContextSelector } from '@/context/Assets/BusterAssetsProvider';
|
||||
|
||||
export const useBusterDashboards = () => {
|
||||
const [openAddContentModal, setOpenAddContentModal] = useState(false);
|
||||
const queryClient = useQueryClient();
|
||||
const getAssetPassword = useBusterAssetsContextSelector((state) => state.getAssetPassword);
|
||||
|
||||
const [dashboards, setDashboard] = useState<Record<string, BusterDashboardResponse>>({});
|
||||
const getDashboard = useQuery({
|
||||
queryKey: ['/dashboards/get:getDashboardState', { id: '1' }],
|
||||
queryFn: () => {
|
||||
return { id: '1' };
|
||||
},
|
||||
enabled: false
|
||||
});
|
||||
|
||||
const dashboardSubscribe = useDashboardSubscribe({ setDashboard });
|
||||
const getDashboardMemoized = useMemoizedFn((dashboardId: string) => {
|
||||
const { password } = getAssetPassword(dashboardId);
|
||||
const queryKey = createQueryKey(
|
||||
{ route: '/dashboards/get:getDashboardState' },
|
||||
{ route: '/dashboards/get', payload: { id: dashboardId, password } }
|
||||
);
|
||||
return queryClient.getQueryData<BusterDashboardResponse>(queryKey);
|
||||
});
|
||||
|
||||
const dashboardUpdateConfig = useDashboardUpdateConfig({ dashboards, setDashboard });
|
||||
const dashboardUpdateConfig = useDashboardUpdateConfig({ getDashboardMemoized });
|
||||
|
||||
const dashboardAssosciations = useDashboardAssosciations({ setDashboard });
|
||||
const dashboardAssosciations = useDashboardAssosciations();
|
||||
|
||||
const dashboardCreate = useDashboardCreate({
|
||||
onUpdateDashboard: dashboardUpdateConfig.onUpdateDashboard
|
||||
});
|
||||
|
||||
const dashboardShare = useShareDashboard({
|
||||
initializeDashboard: dashboardSubscribe.initializeDashboard
|
||||
});
|
||||
|
||||
const getDashboardMemoized = useMemoizedFn((id: string) => dashboards[id]);
|
||||
|
||||
return {
|
||||
...dashboardAssosciations,
|
||||
...dashboardCreate,
|
||||
...dashboardUpdateConfig,
|
||||
...dashboardSubscribe,
|
||||
...dashboardShare,
|
||||
dashboards,
|
||||
openAddContentModal,
|
||||
getDashboardMemoized,
|
||||
setOpenAddContentModal
|
||||
|
@ -59,34 +66,3 @@ export const BusterDashboardIndividualProvider: React.FC<PropsWithChildren> = ({
|
|||
export const useBusterDashboardContextSelector = <T,>(
|
||||
selector: ContextSelector<ReturnType<typeof useBusterDashboards>, T>
|
||||
) => useContextSelector(BusterDashboards, selector);
|
||||
|
||||
export const useBusterDashboardIndividual = ({
|
||||
dashboardId
|
||||
}: {
|
||||
dashboardId: string | undefined;
|
||||
}) => {
|
||||
const dashboardResponse = useBusterDashboardContextSelector(
|
||||
(state) => state.dashboards[dashboardId || '']
|
||||
);
|
||||
const subscribeToDashboard = useBusterDashboardContextSelector(
|
||||
(state) => state.subscribeToDashboard
|
||||
);
|
||||
const unSubscribeToDashboard = useBusterDashboardContextSelector((x) => x.unSubscribeToDashboard);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (dashboardId) subscribeToDashboard({ dashboardId });
|
||||
}, [dashboardId]);
|
||||
|
||||
useUnmount(() => {
|
||||
if (dashboardId) unSubscribeToDashboard({ dashboardId });
|
||||
});
|
||||
|
||||
const dashboard = dashboardResponse?.dashboard;
|
||||
const metrics = dashboardResponse?.metrics;
|
||||
|
||||
return {
|
||||
dashboard,
|
||||
metrics,
|
||||
dashboardResponse
|
||||
};
|
||||
};
|
||||
|
|
|
@ -72,7 +72,7 @@ export const generateMockDashboard = (numMetrics: number): DashboardMockResponse
|
|||
|
||||
const dashboard: BusterDashboard = {
|
||||
id: '123',
|
||||
title: 'Mock Dashboard',
|
||||
name: 'Mock Dashboard',
|
||||
file: `title: Mock Dashboard
|
||||
description: A sample dashboard configuration
|
||||
version: 1.0
|
||||
|
|
|
@ -8,7 +8,7 @@ export const defaultBusterDashboard: BusterDashboard = {
|
|||
created_at: '',
|
||||
deleted_at: '',
|
||||
description: '',
|
||||
title: '',
|
||||
name: '',
|
||||
updated_at: '',
|
||||
created_by: '',
|
||||
updated_by: '',
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
export * from './DashboardIndividualProvider';
|
||||
export * from './useBusterDashboardIndividual';
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
import { BusterDashboardResponse } from '@/api/asset_interfaces';
|
||||
import { useBusterAssetsContextSelector } from '@/context/Assets/BusterAssetsProvider';
|
||||
import { useBusterWebSocket } from '@/context/BusterWebSocket';
|
||||
import { useMemoizedFn, useMount } from 'ahooks';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useBusterMetricsIndividualContextSelector } from '@/context/Metrics';
|
||||
import { useSocketQueryEmitOn } from '@/hooks';
|
||||
|
||||
export const useDashboardIndividual = ({ dashboardId }: { dashboardId: string }) => {
|
||||
export const useBusterDashboardIndividual = ({
|
||||
dashboardId = ''
|
||||
}: {
|
||||
dashboardId: string | undefined;
|
||||
}) => {
|
||||
const onInitializeMetric = useBusterMetricsIndividualContextSelector(
|
||||
(state) => state.onInitializeMetric
|
||||
);
|
||||
const getAssetPassword = useBusterAssetsContextSelector((state) => state.getAssetPassword);
|
||||
const { password } = getAssetPassword(dashboardId);
|
||||
|
||||
const { data, refetch: refreshDashboard } = useSocketQueryEmitOn(
|
||||
const { data: dashboardResponse, refetch: refreshDashboard } = useSocketQueryEmitOn(
|
||||
{ route: '/dashboards/get', payload: { id: dashboardId, password } },
|
||||
{ route: '/dashboards/get:getDashboardState' },
|
||||
{ enabled: !!dashboardId }
|
||||
|
@ -28,13 +31,18 @@ export const useDashboardIndividual = ({ dashboardId }: { dashboardId: string })
|
|||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
initializeDashboard(data);
|
||||
if (dashboardResponse) {
|
||||
initializeDashboard(dashboardResponse);
|
||||
}
|
||||
}, [data]);
|
||||
}, [dashboardResponse]);
|
||||
|
||||
const dashboard = dashboardResponse?.dashboard;
|
||||
const metrics = dashboardResponse?.metrics || [];
|
||||
|
||||
return {
|
||||
refreshDashboard,
|
||||
initializeDashboard
|
||||
dashboard,
|
||||
metrics,
|
||||
dashboardResponse,
|
||||
refreshDashboard
|
||||
};
|
||||
};
|
|
@ -2,14 +2,10 @@ import type { BusterDashboardResponse } from '@/api/asset_interfaces';
|
|||
import { useBusterNotifications } from '@/context/BusterNotifications';
|
||||
import { useBusterWebSocket } from '@/context/BusterWebSocket';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import React from 'react';
|
||||
import { useBusterDashboardListContextSelector } from '../DashboardListProvider/DashboardListProvider';
|
||||
import { useSocketQueryMutation } from '@/hooks';
|
||||
|
||||
export const useDashboardAssosciations = ({
|
||||
setDashboard
|
||||
}: {
|
||||
setDashboard: React.Dispatch<React.SetStateAction<Record<string, BusterDashboardResponse>>>;
|
||||
}) => {
|
||||
export const useDashboardAssosciations = () => {
|
||||
const busterSocket = useBusterWebSocket();
|
||||
const { openConfirmModal } = useBusterNotifications();
|
||||
const removeItemFromDashboardsList = useBusterDashboardListContextSelector(
|
||||
|
@ -66,18 +62,18 @@ export const useDashboardAssosciations = ({
|
|||
|
||||
const removeItemFromIndividualDashboard = useMemoizedFn(
|
||||
({ dashboardId, metricId }: { dashboardId: string; metricId: string }) => {
|
||||
setDashboard((prevDashboards) => {
|
||||
const dashboardResponse: BusterDashboardResponse | undefined = prevDashboards[dashboardId];
|
||||
if (!dashboardResponse) return prevDashboards;
|
||||
const newMetrics = dashboardResponse.metrics.filter((t) => t.id !== metricId);
|
||||
return {
|
||||
...prevDashboards,
|
||||
[dashboardId]: {
|
||||
...prevDashboards[dashboardId],
|
||||
metrics: newMetrics
|
||||
}
|
||||
};
|
||||
});
|
||||
// setDashboard((prevDashboards) => {
|
||||
// const dashboardResponse: BusterDashboardResponse | undefined = prevDashboards[dashboardId];
|
||||
// if (!dashboardResponse) return prevDashboards;
|
||||
// const newMetrics = dashboardResponse.metrics.filter((t) => t.id !== metricId);
|
||||
// return {
|
||||
// ...prevDashboards,
|
||||
// [dashboardId]: {
|
||||
// ...prevDashboards[dashboardId],
|
||||
// metrics: newMetrics
|
||||
// }
|
||||
// };
|
||||
// });
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
import { BusterDashboardResponse } from '@/api/asset_interfaces';
|
||||
import { DashboardUpdate } from '@/api/buster_socket/dashboards';
|
||||
import { useBusterWebSocket } from '@/context/BusterWebSocket';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
|
||||
export const useShareDashboard = ({
|
||||
initializeDashboard
|
||||
}: {
|
||||
initializeDashboard: (d: BusterDashboardResponse) => void;
|
||||
}) => {
|
||||
const busterSocket = useBusterWebSocket();
|
||||
|
||||
const onShareDashboard = useMemoizedFn(
|
||||
async (
|
||||
props: Pick<
|
||||
DashboardUpdate['payload'],
|
||||
| 'id'
|
||||
| 'publicly_accessible'
|
||||
| 'public_password'
|
||||
| 'user_permissions'
|
||||
| 'team_permissions'
|
||||
| 'public_expiry_date'
|
||||
| 'remove_users'
|
||||
| 'remove_teams'
|
||||
>
|
||||
) => {
|
||||
return busterSocket.emitAndOnce({
|
||||
emitEvent: {
|
||||
route: '/dashboards/update',
|
||||
payload: props
|
||||
},
|
||||
responseEvent: {
|
||||
route: '/dashboards/update:updateDashboard',
|
||||
callback: initializeDashboard
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
onShareDashboard
|
||||
};
|
||||
};
|
|
@ -3,80 +3,77 @@ import type {
|
|||
BusterDashboardResponse,
|
||||
VerificationStatus
|
||||
} from '@/api/asset_interfaces';
|
||||
import { DashboardUpdate } from '@/api/buster_socket/dashboards';
|
||||
import { useBusterWebSocket } from '@/context/BusterWebSocket';
|
||||
import { useSocketQueryMutation } from '@/hooks';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import React from 'react';
|
||||
import { create } from 'mutative';
|
||||
|
||||
export const useDashboardUpdateConfig = ({
|
||||
dashboards,
|
||||
setDashboard
|
||||
getDashboardMemoized
|
||||
}: {
|
||||
dashboards: Record<string, BusterDashboardResponse>;
|
||||
setDashboard: React.Dispatch<React.SetStateAction<Record<string, BusterDashboardResponse>>>;
|
||||
getDashboardMemoized: (dashboardId: string) => BusterDashboardResponse | undefined;
|
||||
}) => {
|
||||
const busterSocket = useBusterWebSocket();
|
||||
|
||||
const _updateDashboardResponseToServer = useMemoizedFn(
|
||||
(newDashboard: Partial<BusterDashboardResponse>, dashboardId: string) => {
|
||||
const newDashboardState: BusterDashboardResponse = {
|
||||
...dashboards[dashboardId],
|
||||
...newDashboard
|
||||
};
|
||||
|
||||
const oldDashboard = dashboards[dashboardId];
|
||||
if (isEqual(oldDashboard, newDashboard)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setDashboard((prevDashboards) => {
|
||||
return {
|
||||
...prevDashboards,
|
||||
[dashboardId]: newDashboardState
|
||||
};
|
||||
});
|
||||
|
||||
busterSocket.emit({
|
||||
route: '/dashboards/update',
|
||||
payload: {
|
||||
id: dashboardId,
|
||||
description: newDashboardState.dashboard.description,
|
||||
title: newDashboardState.dashboard.title,
|
||||
config: newDashboardState.dashboard.config
|
||||
const { mutateAsync: updateDashboard, isPending: isUpdatingDashboard } = useSocketQueryMutation(
|
||||
{ route: '/dashboards/update' },
|
||||
{ route: '/dashboards/update:updateDashboard' },
|
||||
{
|
||||
preSetQueryDataFunction: {
|
||||
responseRoute: '/dashboards/get:getDashboardState',
|
||||
callback: (data, variables) => {
|
||||
const newObject: BusterDashboardResponse = create(data!, (draft) => {
|
||||
Object.assign(draft.dashboard, variables, {
|
||||
config: { ...draft.dashboard.config, ...variables.config }
|
||||
});
|
||||
});
|
||||
return newObject;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const onUpdateDashboard = useMemoizedFn(
|
||||
(newDashboard: Partial<BusterDashboard> & { id: string }) => {
|
||||
const id = newDashboard.id;
|
||||
const currentDashboard = dashboards[id] || {};
|
||||
const newDashboardState = {
|
||||
...currentDashboard,
|
||||
dashboard: {
|
||||
...currentDashboard.dashboard,
|
||||
...newDashboard
|
||||
}
|
||||
};
|
||||
const currentDashboard = getDashboardMemoized(newDashboard.id);
|
||||
const newDashboardState: BusterDashboard = create(currentDashboard?.dashboard!, (draft) => {
|
||||
Object.assign(draft, newDashboard);
|
||||
});
|
||||
return updateDashboard({
|
||||
id: newDashboard.id,
|
||||
name: newDashboardState.name,
|
||||
description: newDashboardState.description,
|
||||
config: newDashboardState.config
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
_updateDashboardResponseToServer(newDashboardState, id);
|
||||
const onShareDashboard = useMemoizedFn(
|
||||
async (
|
||||
props: Pick<
|
||||
DashboardUpdate['payload'],
|
||||
| 'id'
|
||||
| 'publicly_accessible'
|
||||
| 'public_password'
|
||||
| 'user_permissions'
|
||||
| 'team_permissions'
|
||||
| 'public_expiry_date'
|
||||
| 'remove_users'
|
||||
| 'remove_teams'
|
||||
>
|
||||
) => {
|
||||
return updateDashboard(props);
|
||||
}
|
||||
);
|
||||
|
||||
const onUpdateDashboardConfig = useMemoizedFn(
|
||||
(newDashboard: Partial<BusterDashboard['config']>, dashboardId: string) => {
|
||||
const newDashboardState = {
|
||||
...dashboards[dashboardId],
|
||||
dashboard: {
|
||||
...dashboards[dashboardId].dashboard,
|
||||
config: {
|
||||
...dashboards[dashboardId].dashboard.config,
|
||||
...newDashboard
|
||||
}
|
||||
}
|
||||
};
|
||||
_updateDashboardResponseToServer(newDashboardState, dashboardId);
|
||||
const currentDashboard = getDashboardMemoized(dashboardId);
|
||||
const newDashboardState: BusterDashboard = create(currentDashboard?.dashboard!, (draft) => {
|
||||
Object.assign(draft.config, newDashboard);
|
||||
});
|
||||
return onUpdateDashboard(newDashboardState);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -89,9 +86,15 @@ export const useDashboardUpdateConfig = ({
|
|||
}
|
||||
);
|
||||
|
||||
const refreshDashboard = useMemoizedFn((dashboardId: string) => {
|
||||
busterSocket.emit({ route: '/dashboards/get', payload: { id: dashboardId } });
|
||||
});
|
||||
|
||||
return {
|
||||
onShareDashboard,
|
||||
onUpdateDashboardConfig,
|
||||
onUpdateDashboard,
|
||||
onVerifiedDashboard
|
||||
onVerifiedDashboard,
|
||||
refreshDashboard
|
||||
};
|
||||
};
|
||||
|
|
|
@ -46,6 +46,8 @@ export const useUpdateMetricConfig = ({
|
|||
_prepareMetricAndSaveToServer(newMetric, currentMetric);
|
||||
}
|
||||
});
|
||||
|
||||
return newMetric;
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -258,7 +258,7 @@ const Example = () => {
|
|||
mutate({
|
||||
id: 'some-asset-id',
|
||||
asset_type: ShareAssetType.DASHBOARD,
|
||||
title: 'some-title'
|
||||
name: 'some-title'
|
||||
});
|
||||
|
||||
return null;
|
||||
|
|
Loading…
Reference in New Issue