version update

This commit is contained in:
Nate Kelley 2025-03-28 14:23:24 -06:00
parent 0ce645d893
commit 78a11f374c
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
11 changed files with 59 additions and 41 deletions

View File

@ -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
});
}
});

View File

@ -6,7 +6,7 @@ const collectionsGetList = (
filters?: Omit<Parameters<typeof collectionsGetListRequest>[0], 'page' | 'page_size'>
) =>
queryOptions<BusterCollectionListItem[]>({
queryKey: ['collections', 'list', filters] as const,
queryKey: ['collections', 'list', filters || {}] as const,
staleTime: 60 * 1000,
initialData: [],
initialDataUpdatedAt: 0

View File

@ -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<DataSourceTypes | null>(
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(() => {

View File

@ -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<BusterChartProps> = 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<BusterChartProps> = React.memo(
});
const SwitchComponent = useMemoizedFn(() => {
if (loading || error) {
if (loading || error || !isMounted) {
return <PreparingYourRequestLoader error={error} />;
}
@ -129,6 +130,12 @@ export const BusterChart: React.FC<BusterChartProps> = React.memo(
);
}
if (!isMounted) {
return (
<div className="to-bg-gradient-to-r to-border/10 h-full w-full bg-gradient-to-b from-transparent" />
);
}
const chartProps: BusterChartRenderComponentProps = {
...DEFAULT_CHART_CONFIG,
columnMetadata: props.columnMetadata ?? [],
@ -150,6 +157,12 @@ export const BusterChart: React.FC<BusterChartProps> = React.memo(
return <BusterChartComponent {...chartProps} />;
});
useMount(() => {
setTimeout(() => {
setIsMounted(true);
}, 25);
});
return (
<BusterChartErrorWrapper>
<BusterChartWrapper id={id} className={className} loading={loading}>

View File

@ -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 (
<Popover
align="end"
side="right"
className="max-h-[420px] max-w-[265px]! min-w-[200px] overflow-x-hidden overflow-y-auto px-0 py-1"
align="center"
side="left"
className="flex max-h-[420px] max-w-[265px]! min-w-[200px] flex-col overflow-hidden px-0 py-0.5"
content={
<div className="flex flex-col space-y-1 p-0.5">
{legendItems.map((item) => {
return (
<LegendItem
key={item.id + item.serieName}
item={item}
onClickItem={onClickItem}
onFocusItem={onFocusClick}
onHoverItem={onHoverItem}
/>
);
})}
</div>
<ScrollArea className="flex flex-col">
<div className="flex flex-col space-y-1 p-0.5">
{legendItems.map((item) => {
return (
<LegendItem
key={item.id + item.serieName}
item={item}
onClickItem={onClickItem}
onFocusItem={onFocusClick}
onHoverItem={onHoverItem}
/>
);
})}
</div>
</ScrollArea>
}>
<div
className={cn(

View File

@ -22,10 +22,8 @@ export const BusterChartWrapper = React.memo<{
id={id}
className={cn(
className,
'flex h-full w-full flex-col',
'transition duration-300',
loading ? 'bg-transparent!' : undefined,
'overflow-hidden'
'flex h-full w-full flex-col overflow-hidden transition duration-300',
loading && 'bg-transparent!'
)}>
{children}
</div>

View File

@ -68,7 +68,7 @@ const DashboardMetricItemBase: React.FC<{
className={`metric-item flex h-full w-full flex-col overflow-auto ${className}`}>
<CardHeader
size="small"
className="hover:bg-item-hover group h-12 justify-center overflow-hidden border-b p-0!">
className="hover:bg-item-hover group min-h-13! justify-center overflow-hidden border-b px-4 py-2">
<MetricTitle
name={metric?.name || ''}
timeFrame={metric?.time_frame}
@ -84,6 +84,7 @@ const DashboardMetricItemBase: React.FC<{
<div
className={cn(
`h-full w-full overflow-hidden bg-transparent`,
isTable ? '' : 'p-3',
isDragOverlay ? 'pointer-events-none' : 'pointer-events-auto'
)}>
{renderChart && (

View File

@ -35,7 +35,7 @@ export const MetricTitle: React.FC<{
const useEllipsis = !isDragOverlay && !isDragging;
return (
<Link className="flex px-4" href={metricLink} prefetch>
<Link className="flex" href={metricLink} prefetch>
<div
{...attributes}
{...listeners}
@ -68,7 +68,7 @@ export const MetricTitle: React.FC<{
{isDragOverlay || readOnly ? (
<></>
) : (
<ThreeDotMenu className="" dashboardId={dashboardId} metricId={metricId} />
<ThreeDotMenu dashboardId={dashboardId} metricId={metricId} />
)}
</Link>
);

View File

@ -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;

View File

@ -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 }));
}
})
},

View File

@ -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: <Trash />,
onClick: async () => {
await deleteDashboard({ dashboardId });
onChangePage(createBusterRoute({ route: BusterRoutes.APP_DASHBOARDS }));
}
}),
[dashboardId]