mirror of https://github.com/buster-so/buster.git
version update
This commit is contained in:
parent
0ce645d893
commit
78a11f374c
|
@ -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
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(() => {
|
||||
|
|
|
@ -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}>
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 && (
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 }));
|
||||
}
|
||||
})
|
||||
},
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in New Issue