mirror of https://github.com/buster-so/buster.git
open in metric page should collapse the menu
This commit is contained in:
parent
24c561a07a
commit
7f970b4e9a
|
@ -13,7 +13,6 @@ import { AppTooltip } from '@/components/ui/tooltip';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useGetFileLink } from '@/context/Assets/useGetFileLink';
|
import { useGetFileLink } from '@/context/Assets/useGetFileLink';
|
||||||
import { useChatLayoutContextSelector } from '@/layouts/ChatLayout';
|
import { useChatLayoutContextSelector } from '@/layouts/ChatLayout';
|
||||||
import { useRouter } from 'next/navigation';
|
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
export const VersionHistoryPanel = React.memo(
|
export const VersionHistoryPanel = React.memo(
|
||||||
|
|
|
@ -242,7 +242,7 @@ export const DropdownContent = <T,>({
|
||||||
}}>
|
}}>
|
||||||
{hasShownItem ? (
|
{hasShownItem ? (
|
||||||
<>
|
<>
|
||||||
{selectedItems.map((item) => {
|
{selectedItems.map((item, index) => {
|
||||||
// Only increment index for selectable items
|
// Only increment index for selectable items
|
||||||
if ((item as DropdownItem).value && !(item as DropdownItem).items) {
|
if ((item as DropdownItem).value && !(item as DropdownItem).items) {
|
||||||
hotkeyIndex++;
|
hotkeyIndex++;
|
||||||
|
@ -250,7 +250,7 @@ export const DropdownContent = <T,>({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownItemSelector
|
<DropdownItemSelector
|
||||||
key={dropdownItemKey(item, hotkeyIndex)}
|
key={dropdownItemKey(item, index)}
|
||||||
item={item}
|
item={item}
|
||||||
index={hotkeyIndex}
|
index={hotkeyIndex}
|
||||||
selectType={selectType}
|
selectType={selectType}
|
||||||
|
@ -264,7 +264,7 @@ export const DropdownContent = <T,>({
|
||||||
|
|
||||||
{selectedItems.length > 0 && <DropdownMenuSeparator />}
|
{selectedItems.length > 0 && <DropdownMenuSeparator />}
|
||||||
|
|
||||||
{dropdownItems.map((item) => {
|
{dropdownItems.map((item, index) => {
|
||||||
// Only increment index for selectable items
|
// Only increment index for selectable items
|
||||||
if ((item as DropdownItem).value && !(item as DropdownItem).items) {
|
if ((item as DropdownItem).value && !(item as DropdownItem).items) {
|
||||||
hotkeyIndex++;
|
hotkeyIndex++;
|
||||||
|
@ -272,7 +272,7 @@ export const DropdownContent = <T,>({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownItemSelector
|
<DropdownItemSelector
|
||||||
key={dropdownItemKey(item, hotkeyIndex)}
|
key={dropdownItemKey(item, index)}
|
||||||
item={item}
|
item={item}
|
||||||
index={hotkeyIndex}
|
index={hotkeyIndex}
|
||||||
selectType={selectType}
|
selectType={selectType}
|
||||||
|
|
|
@ -27,7 +27,6 @@ export const useAutoChangeLayout = ({
|
||||||
const secondaryView = useChatLayoutContextSelector((x) => x.secondaryView);
|
const secondaryView = useChatLayoutContextSelector((x) => x.secondaryView);
|
||||||
const dashboardVersionNumber = useChatLayoutContextSelector((x) => x.dashboardVersionNumber);
|
const dashboardVersionNumber = useChatLayoutContextSelector((x) => x.dashboardVersionNumber);
|
||||||
const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber);
|
const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber);
|
||||||
const isVersionHistoryMode = useChatLayoutContextSelector((x) => x.isVersionHistoryMode);
|
|
||||||
const isCompletedStream = useGetChatMessage(lastMessageId, (x) => x?.isCompletedStream);
|
const isCompletedStream = useGetChatMessage(lastMessageId, (x) => x?.isCompletedStream);
|
||||||
|
|
||||||
const getInitialChatFileHref = useGetInitialChatFile();
|
const getInitialChatFileHref = useGetInitialChatFile();
|
||||||
|
|
|
@ -92,7 +92,9 @@ export const useLayoutConfig = ({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (secondaryView) {
|
if (!chatId) {
|
||||||
|
animateOpenSplitter('right');
|
||||||
|
} else if (secondaryView) {
|
||||||
animateOpenSplitter('right');
|
animateOpenSplitter('right');
|
||||||
|
|
||||||
//if the chat is open, we need to wait for the splitter to close before opening the secondary view
|
//if the chat is open, we need to wait for the splitter to close before opening the secondary view
|
||||||
|
@ -192,7 +194,7 @@ export const useLayoutConfig = ({
|
||||||
fileView,
|
fileView,
|
||||||
secondaryView: secondaryViewFromSelected
|
secondaryView: secondaryViewFromSelected
|
||||||
});
|
});
|
||||||
}, [metricId, secondaryView, dashboardId, currentRoute]);
|
}, [metricId, secondaryView, chatId, dashboardId, currentRoute]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
selectedLayout,
|
selectedLayout,
|
||||||
|
|
|
@ -17,11 +17,15 @@ import { canEdit, getIsEffectiveOwner } from '@/lib/share';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { assetParamsToRoute } from '@/lib/assets';
|
import { assetParamsToRoute } from '@/lib/assets';
|
||||||
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
|
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
|
||||||
|
import { useIsMetricReadOnly } from '@/context/Metrics/useIsMetricReadOnly';
|
||||||
|
|
||||||
export const MetricContainerHeaderButtons: React.FC<FileContainerButtonsProps> = React.memo(() => {
|
export const MetricContainerHeaderButtons: React.FC<FileContainerButtonsProps> = React.memo(() => {
|
||||||
const selectedLayout = useChatLayoutContextSelector((x) => x.selectedLayout);
|
const selectedLayout = useChatLayoutContextSelector((x) => x.selectedLayout);
|
||||||
const selectedFileId = useChatIndividualContextSelector((x) => x.selectedFileId)!;
|
const metricId = useChatIndividualContextSelector((x) => x.selectedFileId)!;
|
||||||
const metricId = selectedFileId;
|
const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber);
|
||||||
|
const { isViewingOldVersion } = useIsMetricReadOnly({
|
||||||
|
metricId: metricId || ''
|
||||||
|
});
|
||||||
const { error: metricError, data: permission } = useGetMetric(
|
const { error: metricError, data: permission } = useGetMetric(
|
||||||
{ id: metricId },
|
{ id: metricId },
|
||||||
{ select: (x) => x.permission }
|
{ select: (x) => x.permission }
|
||||||
|
@ -35,12 +39,16 @@ export const MetricContainerHeaderButtons: React.FC<FileContainerButtonsProps> =
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FileButtonContainer>
|
<FileButtonContainer>
|
||||||
{isEditor && <EditChartButton metricId={metricId} />}
|
{isEditor && !isViewingOldVersion && <EditChartButton metricId={metricId} />}
|
||||||
{isEffectiveOwner && <EditSQLButton metricId={metricId} />}
|
{isEffectiveOwner && !isViewingOldVersion && <EditSQLButton metricId={metricId} />}
|
||||||
<SaveToCollectionButton metricId={metricId} />
|
<SaveToCollectionButton metricId={metricId} />
|
||||||
<SaveToDashboardButton metricId={metricId} />
|
<SaveToDashboardButton metricId={metricId} />
|
||||||
{isEffectiveOwner && <ShareMetricButton metricId={metricId} />}
|
{isEffectiveOwner && !isViewingOldVersion && <ShareMetricButton metricId={metricId} />}
|
||||||
<ThreeDotMenuButton metricId={metricId} />
|
<ThreeDotMenuButton
|
||||||
|
metricId={metricId}
|
||||||
|
isViewingOldVersion={isViewingOldVersion}
|
||||||
|
versionNumber={metricVersionNumber}
|
||||||
|
/>
|
||||||
<HideButtonContainer show={selectedLayout === 'file-only'}>
|
<HideButtonContainer show={selectedLayout === 'file-only'}>
|
||||||
<CreateChatButton assetId={metricId} assetType="metric" />
|
<CreateChatButton assetId={metricId} assetType="metric" />
|
||||||
</HideButtonContainer>
|
</HideButtonContainer>
|
||||||
|
@ -55,8 +63,8 @@ const EditChartButton = React.memo(({ metricId }: { metricId: string }) => {
|
||||||
(x) => x.selectedFileViewSecondary
|
(x) => x.selectedFileViewSecondary
|
||||||
);
|
);
|
||||||
const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
|
const onChangePage = useAppLayoutContextSelector((x) => x.onChangePage);
|
||||||
const onChangeQueryParams = useAppLayoutContextSelector((x) => x.onChangeQueryParams);
|
|
||||||
const chatId = useChatIndividualContextSelector((x) => x.chatId);
|
const chatId = useChatIndividualContextSelector((x) => x.chatId);
|
||||||
|
const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber);
|
||||||
const editableSecondaryView: MetricFileViewSecondary = 'chart-edit';
|
const editableSecondaryView: MetricFileViewSecondary = 'chart-edit';
|
||||||
const isSelectedView = selectedFileViewSecondary === editableSecondaryView;
|
const isSelectedView = selectedFileViewSecondary === editableSecondaryView;
|
||||||
|
|
||||||
|
@ -66,7 +74,8 @@ const EditChartButton = React.memo(({ metricId }: { metricId: string }) => {
|
||||||
chatId,
|
chatId,
|
||||||
assetId: metricId,
|
assetId: metricId,
|
||||||
type: 'metric',
|
type: 'metric',
|
||||||
secondaryView: null
|
secondaryView: null,
|
||||||
|
versionNumber: metricVersionNumber
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,9 +83,10 @@ const EditChartButton = React.memo(({ metricId }: { metricId: string }) => {
|
||||||
chatId,
|
chatId,
|
||||||
assetId: metricId,
|
assetId: metricId,
|
||||||
type: 'metric',
|
type: 'metric',
|
||||||
secondaryView: 'chart-edit'
|
secondaryView: 'chart-edit',
|
||||||
|
versionNumber: metricVersionNumber
|
||||||
});
|
});
|
||||||
}, [chatId, metricId, isSelectedView]);
|
}, [chatId, metricId, isSelectedView, metricVersionNumber]);
|
||||||
|
|
||||||
const onClickButton = useMemoizedFn(() => {
|
const onClickButton = useMemoizedFn(() => {
|
||||||
onChangePage(href, { shallow: true });
|
onChangePage(href, { shallow: true });
|
||||||
|
@ -108,6 +118,7 @@ const EditSQLButton = React.memo(({ metricId }: { metricId: string }) => {
|
||||||
);
|
);
|
||||||
const onSetFileView = useChatLayoutContextSelector((x) => x.onSetFileView);
|
const onSetFileView = useChatLayoutContextSelector((x) => x.onSetFileView);
|
||||||
const chatId = useChatIndividualContextSelector((x) => x.chatId);
|
const chatId = useChatIndividualContextSelector((x) => x.chatId);
|
||||||
|
const metricVersionNumber = useChatLayoutContextSelector((x) => x.metricVersionNumber);
|
||||||
const editableSecondaryView: MetricFileViewSecondary = 'sql-edit';
|
const editableSecondaryView: MetricFileViewSecondary = 'sql-edit';
|
||||||
const isSelectedView = selectedFileViewSecondary === editableSecondaryView;
|
const isSelectedView = selectedFileViewSecondary === editableSecondaryView;
|
||||||
|
|
||||||
|
@ -116,9 +127,10 @@ const EditSQLButton = React.memo(({ metricId }: { metricId: string }) => {
|
||||||
chatId,
|
chatId,
|
||||||
assetId: metricId,
|
assetId: metricId,
|
||||||
type: 'metric',
|
type: 'metric',
|
||||||
secondaryView: 'sql-edit'
|
secondaryView: 'sql-edit',
|
||||||
|
versionNumber: metricVersionNumber
|
||||||
});
|
});
|
||||||
}, [chatId, metricId]);
|
}, [chatId, metricId, metricVersionNumber]);
|
||||||
|
|
||||||
const onClickButton = useMemoizedFn(() => {
|
const onClickButton = useMemoizedFn(() => {
|
||||||
const secondaryView = isSelectedView ? null : editableSecondaryView;
|
const secondaryView = isSelectedView ? null : editableSecondaryView;
|
||||||
|
@ -147,8 +159,3 @@ const SaveToDashboardButton = React.memo(({ metricId }: { metricId: string }) =>
|
||||||
return <SaveMetricToDashboardButton metricIds={[metricId]} />;
|
return <SaveMetricToDashboardButton metricIds={[metricId]} />;
|
||||||
});
|
});
|
||||||
SaveToDashboardButton.displayName = 'SaveToDashboardButton';
|
SaveToDashboardButton.displayName = 'SaveToDashboardButton';
|
||||||
|
|
||||||
const ShareMetricButtonLocal = React.memo(({ metricId }: { metricId: string }) => {
|
|
||||||
return <ShareMetricButton metricId={metricId} />;
|
|
||||||
});
|
|
||||||
ShareMetricButtonLocal.displayName = 'ShareMetricButtonLocal';
|
|
||||||
|
|
|
@ -56,11 +56,20 @@ import { BusterRoutes, createBusterRoute } from '@/routes';
|
||||||
import { useListVersionDropdownItems } from '@/components/features/versionHistory/useListVersionDropdownItems';
|
import { useListVersionDropdownItems } from '@/components/features/versionHistory/useListVersionDropdownItems';
|
||||||
import { useChatIndividualContextSelector } from '@/layouts/ChatLayout/ChatContext';
|
import { useChatIndividualContextSelector } from '@/layouts/ChatLayout/ChatContext';
|
||||||
|
|
||||||
export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string }) => {
|
export const ThreeDotMenuButton = React.memo(
|
||||||
|
({
|
||||||
|
metricId,
|
||||||
|
isViewingOldVersion,
|
||||||
|
versionNumber
|
||||||
|
}: {
|
||||||
|
metricId: string;
|
||||||
|
isViewingOldVersion: boolean;
|
||||||
|
versionNumber: number | undefined;
|
||||||
|
}) => {
|
||||||
const chatId = useChatIndividualContextSelector((x) => x.chatId);
|
const chatId = useChatIndividualContextSelector((x) => x.chatId);
|
||||||
const { openSuccessMessage } = useBusterNotifications();
|
const { openSuccessMessage } = useBusterNotifications();
|
||||||
const { data: permission } = useGetMetric({ id: metricId }, { select: (x) => x.permission });
|
const { data: permission } = useGetMetric({ id: metricId }, { select: (x) => x.permission });
|
||||||
const openFullScreenMetric = useOpenFullScreenMetric({ metricId });
|
const openFullScreenMetric = useOpenFullScreenMetric({ metricId, versionNumber });
|
||||||
const onSetSelectedFile = useChatLayoutContextSelector((x) => x.onSetSelectedFile);
|
const onSetSelectedFile = useChatLayoutContextSelector((x) => x.onSetSelectedFile);
|
||||||
const dashboardSelectMenu = useDashboardSelectMenu({ metricId });
|
const dashboardSelectMenu = useDashboardSelectMenu({ metricId });
|
||||||
const versionHistoryItems = useVersionHistorySelectMenu({ metricId });
|
const versionHistoryItems = useVersionHistorySelectMenu({ metricId });
|
||||||
|
@ -84,23 +93,23 @@ export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string }
|
||||||
() =>
|
() =>
|
||||||
[
|
[
|
||||||
chatId && openFullScreenMetric,
|
chatId && openFullScreenMetric,
|
||||||
isOwnerEffective && shareMenu,
|
isOwnerEffective && !isViewingOldVersion && shareMenu,
|
||||||
isEditor && statusSelectMenu,
|
isEditor && !isViewingOldVersion && statusSelectMenu,
|
||||||
{ type: 'divider' },
|
{ type: 'divider' },
|
||||||
dashboardSelectMenu,
|
!isViewingOldVersion && dashboardSelectMenu,
|
||||||
collectionSelectMenu,
|
!isViewingOldVersion && collectionSelectMenu,
|
||||||
favoriteMetric,
|
!isViewingOldVersion && favoriteMetric,
|
||||||
{ type: 'divider' },
|
{ type: 'divider' },
|
||||||
isEditor && editChartMenu,
|
isEditor && !isViewingOldVersion && editChartMenu,
|
||||||
resultsViewMenu,
|
!isViewingOldVersion && resultsViewMenu,
|
||||||
sqlEditorMenu,
|
!isViewingOldVersion && sqlEditorMenu,
|
||||||
isEditor && versionHistoryItems,
|
isEditor && versionHistoryItems,
|
||||||
{ type: 'divider' },
|
{ type: 'divider' },
|
||||||
downloadCSVMenu,
|
downloadCSVMenu,
|
||||||
downloadPNGMenu,
|
downloadPNGMenu,
|
||||||
{ type: 'divider' },
|
{ type: 'divider' },
|
||||||
isEditor && renameMetricMenu,
|
isEditor && !isViewingOldVersion && renameMetricMenu,
|
||||||
isOwner && deleteMetricMenu
|
isOwner && !isViewingOldVersion && deleteMetricMenu
|
||||||
].filter(Boolean) as DropdownItems,
|
].filter(Boolean) as DropdownItems,
|
||||||
[
|
[
|
||||||
chatId,
|
chatId,
|
||||||
|
@ -131,7 +140,8 @@ export const ThreeDotMenuButton = React.memo(({ metricId }: { metricId: string }
|
||||||
<Button prefix={<Dots />} variant="ghost" />
|
<Button prefix={<Dots />} variant="ghost" />
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
ThreeDotMenuButton.displayName = 'ThreeDotMenuButton';
|
ThreeDotMenuButton.displayName = 'ThreeDotMenuButton';
|
||||||
|
|
||||||
const useDashboardSelectMenu = ({ metricId }: { metricId: string }) => {
|
const useDashboardSelectMenu = ({ metricId }: { metricId: string }) => {
|
||||||
|
@ -499,17 +509,29 @@ export const useShareMenuSelectMenu = ({ metricId }: { metricId: string }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const useOpenFullScreenMetric = ({ metricId }: { metricId: string }) => {
|
const useOpenFullScreenMetric = ({
|
||||||
|
metricId,
|
||||||
|
versionNumber
|
||||||
|
}: {
|
||||||
|
metricId: string;
|
||||||
|
versionNumber: number | undefined;
|
||||||
|
}) => {
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
label: 'Open in metric page',
|
label: 'Open in metric page',
|
||||||
value: 'open-in-full-screen',
|
value: 'open-in-full-screen',
|
||||||
icon: <ArrowUpRight />,
|
icon: <ArrowUpRight />,
|
||||||
link: createBusterRoute({
|
link: versionNumber
|
||||||
|
? createBusterRoute({
|
||||||
|
route: BusterRoutes.APP_METRIC_ID_VERSION_NUMBER,
|
||||||
|
metricId,
|
||||||
|
versionNumber
|
||||||
|
})
|
||||||
|
: createBusterRoute({
|
||||||
route: BusterRoutes.APP_METRIC_ID_CHART,
|
route: BusterRoutes.APP_METRIC_ID_CHART,
|
||||||
metricId
|
metricId
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
[metricId]
|
[metricId, versionNumber]
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,7 +57,6 @@ export type BusterAppRoutesWithArgs = {
|
||||||
[BusterAppRoutes.APP_METRIC_ID_CHART]: {
|
[BusterAppRoutes.APP_METRIC_ID_CHART]: {
|
||||||
route: BusterAppRoutes.APP_METRIC_ID_CHART;
|
route: BusterAppRoutes.APP_METRIC_ID_CHART;
|
||||||
metricId: string;
|
metricId: string;
|
||||||
versionNumber?: number;
|
|
||||||
secondaryView?: MetricFileViewSecondary;
|
secondaryView?: MetricFileViewSecondary;
|
||||||
};
|
};
|
||||||
[BusterAppRoutes.APP_METRIC_ID_VERSION_NUMBER]: {
|
[BusterAppRoutes.APP_METRIC_ID_VERSION_NUMBER]: {
|
||||||
|
@ -132,6 +131,7 @@ export type BusterAppRoutesWithArgs = {
|
||||||
route: BusterAppRoutes.APP_CHAT_ID_METRIC_ID_CHART;
|
route: BusterAppRoutes.APP_CHAT_ID_METRIC_ID_CHART;
|
||||||
chatId: string;
|
chatId: string;
|
||||||
metricId: string;
|
metricId: string;
|
||||||
|
versionNumber?: number;
|
||||||
secondaryView?: MetricFileViewSecondary;
|
secondaryView?: MetricFileViewSecondary;
|
||||||
};
|
};
|
||||||
[BusterAppRoutes.APP_CHAT_ID_METRIC_ID_VERSION_NUMBER]: {
|
[BusterAppRoutes.APP_CHAT_ID_METRIC_ID_VERSION_NUMBER]: {
|
||||||
|
|
Loading…
Reference in New Issue