From 78a11f374cfbc2e8f55eb94a4e47a182727f475e Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Fri, 28 Mar 2025 14:23:24 -0600 Subject: [PATCH] version update --- .../buster_rest/collections/queryRequests.ts | 8 ++--- web/src/api/query_keys/collection.ts | 2 +- .../(admin-restricted-space)/add/page.tsx | 5 +-- web/src/components/ui/charts/BusterChart.tsx | 19 ++++++++-- .../BusterChartLegend/OverflowContainer.tsx | 35 ++++++++++--------- .../ui/charts/BusterChartWrapper.tsx | 6 ++-- .../DashboardMetricItem.tsx | 3 +- .../DashboardMetricItem/MetricTitle.tsx | 4 +-- .../MetricViewChart/MetricViewChart.tsx | 8 ++--- .../ChatHeaderOptions/ChatHeaderDropdown.tsx | 6 ++-- .../DashboardThreeDotMenu.tsx | 4 +++ 11 files changed, 59 insertions(+), 41 deletions(-) diff --git a/web/src/api/buster_rest/collections/queryRequests.ts b/web/src/api/buster_rest/collections/queryRequests.ts index 605ee8aeb..88ac29ecb 100644 --- a/web/src/api/buster_rest/collections/queryRequests.ts +++ b/web/src/api/buster_rest/collections/queryRequests.ts @@ -109,11 +109,9 @@ export const useDeleteCollection = () => { return useMutation({ mutationFn: deleteCollection, - onMutate: (variables) => { - const queryKey = collectionQueryKeys.collectionsGetList().queryKey; - queryClient.setQueryData(queryKey, (v) => { - const ids = Array.isArray(variables.id) ? variables.id : [variables.id]; - return v?.filter((c) => !ids.includes(c.id)); + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: collectionQueryKeys.collectionsGetList().queryKey }); } }); diff --git a/web/src/api/query_keys/collection.ts b/web/src/api/query_keys/collection.ts index 71b28aba4..09489fc76 100644 --- a/web/src/api/query_keys/collection.ts +++ b/web/src/api/query_keys/collection.ts @@ -6,7 +6,7 @@ const collectionsGetList = ( filters?: Omit[0], 'page' | 'page_size'> ) => queryOptions({ - queryKey: ['collections', 'list', filters] as const, + queryKey: ['collections', 'list', filters || {}] as const, staleTime: 60 * 1000, initialData: [], initialDataUpdatedAt: 0 diff --git a/web/src/app/app/(settings_layout)/settings/(restricted-width)/(admin-only)/datasources/(admin-restricted-space)/add/page.tsx b/web/src/app/app/(settings_layout)/settings/(restricted-width)/(admin-only)/datasources/(admin-restricted-space)/add/page.tsx index 19be9a6ff..7b99fdb6b 100644 --- a/web/src/app/app/(settings_layout)/settings/(restricted-width)/(admin-only)/datasources/(admin-restricted-space)/add/page.tsx +++ b/web/src/app/app/(settings_layout)/settings/(restricted-width)/(admin-only)/datasources/(admin-restricted-space)/add/page.tsx @@ -12,13 +12,14 @@ import { AppDataSourceIcon } from '@/components/ui/icons/AppDataSourceIcons'; import { useRouter } from 'next/navigation'; import { useMemoizedFn } from '@/hooks'; import Link from 'next/link'; +import { useAppLayoutContextSelector } from '@/context/BusterAppLayout'; export default function Page({ searchParams: { type } }: { searchParams: { type?: DataSourceTypes }; }) { - const router = useRouter(); + const onChangePage = useAppLayoutContextSelector((s) => s.onChangePage); const [selectedDataSource, setSelectedDataSource] = useState( getValidType(type) ); @@ -33,7 +34,7 @@ export default function Page({ const onClearSelectedDataSource = useMemoizedFn(() => { setSelectedDataSource(null); - router.push(createBusterRoute({ route: BusterRoutes.SETTINGS_DATASOURCES_ADD })); + onChangePage(createBusterRoute({ route: BusterRoutes.SETTINGS_DATASOURCES_ADD })); }); useEffect(() => { diff --git a/web/src/components/ui/charts/BusterChart.tsx b/web/src/components/ui/charts/BusterChart.tsx index d1adfea5c..9c779199d 100644 --- a/web/src/components/ui/charts/BusterChart.tsx +++ b/web/src/components/ui/charts/BusterChart.tsx @@ -1,9 +1,9 @@ 'use client'; -import React, { useMemo } from 'react'; +import React, { useMemo, useState } from 'react'; import isEmpty from 'lodash/isEmpty'; import { doesChartHaveValidAxis } from './helpers'; -import { useMemoizedFn } from '@/hooks'; +import { useMemoizedFn, useMount } from '@/hooks'; import { NoChartData, PreparingYourRequestLoader @@ -47,6 +47,7 @@ export const BusterChart: React.FC = React.memo( columnSettings = DEFAULT_CHART_CONFIG.columnSettings, ...props }) => { + const [isMounted, setIsMounted] = useState(false); //there is a responsive bug where we need to wait for the chart to mount before we can animate it const isTable = selectedChartType === ChartType.Table; const showNoData = !loading && (isEmpty(data) || data === null); @@ -82,7 +83,7 @@ export const BusterChart: React.FC = React.memo( }); const SwitchComponent = useMemoizedFn(() => { - if (loading || error) { + if (loading || error || !isMounted) { return ; } @@ -129,6 +130,12 @@ export const BusterChart: React.FC = React.memo( ); } + if (!isMounted) { + return ( +
+ ); + } + const chartProps: BusterChartRenderComponentProps = { ...DEFAULT_CHART_CONFIG, columnMetadata: props.columnMetadata ?? [], @@ -150,6 +157,12 @@ export const BusterChart: React.FC = React.memo( return ; }); + useMount(() => { + setTimeout(() => { + setIsMounted(true); + }, 25); + }); + return ( diff --git a/web/src/components/ui/charts/BusterChartLegend/OverflowContainer.tsx b/web/src/components/ui/charts/BusterChartLegend/OverflowContainer.tsx index 3c8097b88..ab691c931 100644 --- a/web/src/components/ui/charts/BusterChartLegend/OverflowContainer.tsx +++ b/web/src/components/ui/charts/BusterChartLegend/OverflowContainer.tsx @@ -5,6 +5,7 @@ import { LegendItem } from './LegendItem'; import { cn } from '@/lib/classMerge'; import { LegendItemDot } from './LegendDot'; import { ChartType } from '@/api/asset_interfaces/metric/charts'; +import { ScrollArea } from '../../scroll-area'; export const OverflowButton: React.FC<{ legendItems: BusterChartLegendItem[]; @@ -14,23 +15,25 @@ export const OverflowButton: React.FC<{ }> = React.memo(({ legendItems, onFocusClick, onClickItem, onHoverItem }) => { return ( - {legendItems.map((item) => { - return ( - - ); - })} -
+ +
+ {legendItems.map((item) => { + return ( + + ); + })} +
+
}>
{children}
diff --git a/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/DashboardMetricItem.tsx b/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/DashboardMetricItem.tsx index eef85e7e7..c37fc5636 100644 --- a/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/DashboardMetricItem.tsx +++ b/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/DashboardMetricItem.tsx @@ -68,7 +68,7 @@ const DashboardMetricItemBase: React.FC<{ className={`metric-item flex h-full w-full flex-col overflow-auto ${className}`}> + className="hover:bg-item-hover group min-h-13! justify-center overflow-hidden border-b px-4 py-2"> {renderChart && ( diff --git a/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/MetricTitle.tsx b/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/MetricTitle.tsx index 42a70a7ff..23aa3bd6d 100644 --- a/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/MetricTitle.tsx +++ b/web/src/controllers/DashboardController/DashboardViewDashboardController/DashboardContentController/DashboardMetricItem/MetricTitle.tsx @@ -35,7 +35,7 @@ export const MetricTitle: React.FC<{ const useEllipsis = !isDragOverlay && !isDragging; return ( - +
) : ( - + )} ); diff --git a/web/src/controllers/MetricController/MetricViewChart/MetricViewChart.tsx b/web/src/controllers/MetricController/MetricViewChart/MetricViewChart.tsx index 582eb6b17..cb38e5abf 100644 --- a/web/src/controllers/MetricController/MetricViewChart/MetricViewChart.tsx +++ b/web/src/controllers/MetricController/MetricViewChart/MetricViewChart.tsx @@ -9,6 +9,7 @@ import { ChartType } from '@/api/asset_interfaces/metric/charts/enum'; import { AnimatePresence, motion } from 'framer-motion'; import { cn } from '@/lib/classMerge'; import { canEdit } from '@/lib/share'; +import { useChatLayoutContextSelector } from '@/layouts/ChatLayout'; export const MetricViewChart: React.FC<{ metricId: string; @@ -40,16 +41,15 @@ export const MetricViewChart: React.FC<{ const { data: metricData, isFetched: isFetchedMetricData, - error: metricDataError } = useGetMetricData({ id: metricId }); + const isVersionHistoryMode = useChatLayoutContextSelector((x) => x.isVersionHistoryMode); const { mutateAsync: updateMetric } = useUpdateMetric(); const { name, description, time_frame, evaluation_score, evaluation_summary } = metric || {}; + const isTable = metric?.chart_config.selectedChartType === ChartType.Table; - - const readOnly = readOnlyProp || !canEdit(metric?.permission); - + const readOnly = readOnlyProp || !canEdit(metric?.permission) || isVersionHistoryMode; const loadingData = !isFetchedMetricData; const errorData = !!metricDataError; const showEvaluation = !!evaluation_score && !!evaluation_summary; diff --git a/web/src/layouts/ChatLayout/ChatContainer/ChatHeader/ChatHeaderOptions/ChatHeaderDropdown.tsx b/web/src/layouts/ChatLayout/ChatContainer/ChatHeader/ChatHeaderOptions/ChatHeaderDropdown.tsx index dd6f98d55..13a519942 100644 --- a/web/src/layouts/ChatLayout/ChatContainer/ChatHeader/ChatHeaderOptions/ChatHeaderDropdown.tsx +++ b/web/src/layouts/ChatLayout/ChatContainer/ChatHeader/ChatHeaderOptions/ChatHeaderDropdown.tsx @@ -5,14 +5,14 @@ import { Copy, Trash, Pencil } from '@/components/ui/icons'; import { useDeleteChat, useDuplicateChat } from '@/api/buster_rest/chats'; import { CHAT_HEADER_TITLE_ID } from '../ChatHeaderTitle'; import { timeout } from '@/lib'; -import { useRouter } from 'next/navigation'; import { BusterRoutes, createBusterRoute } from '@/routes'; +import { useAppLayoutContextSelector } from '@/context/BusterAppLayout'; export const ChatContainerHeaderDropdown: React.FC<{ children: React.ReactNode; }> = React.memo(({ children }) => { const chatId = useChatIndividualContextSelector((state) => state.chatId); - const router = useRouter(); + const onChangePage = useAppLayoutContextSelector((s) => s.onChangePage); const { mutate: deleteChat, isPending: isDeleting } = useDeleteChat(); const { mutate: duplicateChat } = useDuplicateChat(); const currentMessageId = useChatIndividualContextSelector((state) => state.currentMessageId); @@ -28,7 +28,7 @@ export const ChatContainerHeaderDropdown: React.FC<{ chatId && deleteChat([chatId], { onSuccess: () => { - router.push(createBusterRoute({ route: BusterRoutes.APP_CHAT })); + onChangePage(createBusterRoute({ route: BusterRoutes.APP_CHAT })); } }) }, diff --git a/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/DashboardContainerHeaderButtons/DashboardThreeDotMenu.tsx b/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/DashboardContainerHeaderButtons/DashboardThreeDotMenu.tsx index 476670870..21cb8a832 100644 --- a/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/DashboardContainerHeaderButtons/DashboardThreeDotMenu.tsx +++ b/web/src/layouts/ChatLayout/FileContainer/FileContainerHeader/DashboardContainerHeaderButtons/DashboardThreeDotMenu.tsx @@ -34,6 +34,8 @@ import { DASHBOARD_TITLE_INPUT_ID } from '@/controllers/DashboardController/Dash import { canEdit, canFilter, getIsEffectiveOwner } from '@/lib/share'; import { getShareAssetConfig } from '@/components/features/ShareMenu/helpers'; import { useDashboardContentStore } from '@/context/Dashboards'; +import { useAppLayoutContextSelector } from '@/context/BusterAppLayout'; +import { BusterRoutes, createBusterRoute } from '@/routes/busterRoutes'; export const DashboardThreeDotMenu = React.memo(({ dashboardId }: { dashboardId: string }) => { const versionHistoryItems = useVersionHistorySelectMenu({ dashboardId }); @@ -182,6 +184,7 @@ const useFavoriteDashboardSelectMenu = ({ dashboardId }: { dashboardId: string } const useDeleteDashboardSelectMenu = ({ dashboardId }: { dashboardId: string }) => { const { mutateAsync: deleteDashboard } = useDeleteDashboards(); + const onChangePage = useAppLayoutContextSelector((s) => s.onChangePage); return useMemo( () => ({ @@ -190,6 +193,7 @@ const useDeleteDashboardSelectMenu = ({ dashboardId }: { dashboardId: string }) icon: , onClick: async () => { await deleteDashboard({ dashboardId }); + onChangePage(createBusterRoute({ route: BusterRoutes.APP_DASHBOARDS })); } }), [dashboardId]