mirror of https://github.com/buster-so/buster.git
select file update
This commit is contained in:
parent
d5ee691de4
commit
be050b3521
|
@ -0,0 +1,3 @@
|
|||
export default function Page() {
|
||||
return <></>;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export default function Page() {
|
||||
return <div className="h-full w-full bg-orange-500">Dashboard swag</div>;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export default function Page() {
|
||||
return <></>;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export default function Page() {
|
||||
return <></>;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export default function Page() {
|
||||
return <></>;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export default function Page() {
|
||||
return <></>;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export default function Page() {
|
||||
return <div className="h-full w-full bg-red-500">Dashboard swag</div>;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export default function Page() {
|
||||
return <></>;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { ChatLayout, useSelectedFileByParams } from '@chatLayout/index';
|
||||
|
||||
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
const { selectedFile, selectedLayout, chatId } = useSelectedFileByParams();
|
||||
|
||||
return (
|
||||
<ChatLayout
|
||||
chatId={chatId}
|
||||
defaultSelectedLayout={selectedLayout}
|
||||
defaultSelectedFile={selectedFile}>
|
||||
{children}
|
||||
</ChatLayout>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export default function Page() {
|
||||
return <></>;
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
import React, { useMemo } from 'react';
|
||||
import { useChatSplitterContextSelector } from '../../ChatLayoutContext';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { AppChatMessageFileType } from '@/components/messages/AppChatMessageContainer';
|
||||
import type { FileType } from '@/api/buster_socket/chats';
|
||||
|
||||
const colors = [
|
||||
'red-200',
|
||||
|
@ -49,11 +48,11 @@ const ChatContentItem = React.memo(({ index }: { index: number }) => {
|
|||
|
||||
const link = useMemo(() => {
|
||||
if (isPureChat) {
|
||||
return `/test/splitter/chat/${index}`;
|
||||
return `/app/chat/${index}`;
|
||||
} else if (isChat && typeOfItem !== 'chat') {
|
||||
return `/test/splitter/chat/${index}/${typeOfItem}/${index}`;
|
||||
return `/app/chat/${index}/${typeOfItem}/${index}`;
|
||||
} else {
|
||||
return `/test/splitter/${typeOfItem}/${index}`;
|
||||
return `/app/chat/${typeOfItem}/${index}`;
|
||||
}
|
||||
}, [index, typeOfItem, isPureChat, isChat]);
|
||||
|
||||
|
@ -61,7 +60,7 @@ const ChatContentItem = React.memo(({ index }: { index: number }) => {
|
|||
if (isPureChat) {
|
||||
router.push(link);
|
||||
} else {
|
||||
onSetSelectedFile({ id: index.toString(), type: typeOfItem as AppChatMessageFileType });
|
||||
onSetSelectedFile({ id: index.toString(), type: typeOfItem as FileType });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import { FileContainer } from './FileContainer';
|
|||
import { ChatSplitterContextProvider } from './ChatLayoutContext';
|
||||
import { useChatLayout } from './ChatLayoutContext';
|
||||
import { SelectedFile } from './interfaces';
|
||||
import { useUpdateEffect, useUpdateLayoutEffect } from 'ahooks';
|
||||
import { useAutoSetLayout, useDefaultSplitterLayout } from './hooks';
|
||||
|
||||
export interface ChatSplitterProps {
|
||||
showChatCollapse?: boolean;
|
||||
|
@ -20,13 +20,8 @@ export interface ChatSplitterProps {
|
|||
export const ChatLayout: React.FC<ChatSplitterProps> = React.memo(
|
||||
({ defaultSelectedFile, defaultSelectedLayout = 'chat', children, chatId }) => {
|
||||
const appSplitterRef = useRef<AppSplitterRef>(null);
|
||||
const [isPureFile, setIsPureFile] = useState(defaultSelectedLayout === 'file');
|
||||
|
||||
const defaultSplitterLayout = useMemo(() => {
|
||||
if (defaultSelectedLayout === 'chat') return ['100%', '0%'];
|
||||
if (defaultSelectedLayout === 'file') return ['0%', '100%'];
|
||||
return ['325px', 'auto'];
|
||||
}, [defaultSelectedLayout]);
|
||||
const defaultSplitterLayout = useDefaultSplitterLayout({ defaultSelectedLayout });
|
||||
|
||||
const useChatSplitterProps = useChatLayout({
|
||||
appSplitterRef,
|
||||
|
@ -34,24 +29,8 @@ export const ChatLayout: React.FC<ChatSplitterProps> = React.memo(
|
|||
defaultSelectedLayout,
|
||||
chatId
|
||||
});
|
||||
const { onSetSelectedFile, selectedFileType, selectedLayout, hasFile } = useChatSplitterProps;
|
||||
|
||||
useUpdateEffect(() => {
|
||||
if (appSplitterRef.current) {
|
||||
const { animateWidth, isSideClosed } = appSplitterRef.current;
|
||||
if (selectedLayout === 'chat') {
|
||||
animateWidth('100%', 'left');
|
||||
} else if (selectedLayout === 'file') {
|
||||
animateWidth('100%', 'right');
|
||||
} else if (selectedLayout === 'both' && (isSideClosed('right') || isSideClosed('left'))) {
|
||||
animateWidth('320px', 'left');
|
||||
}
|
||||
}
|
||||
}, [selectedLayout]);
|
||||
|
||||
useUpdateLayoutEffect(() => {
|
||||
if (isPureFile === true) setIsPureFile(selectedLayout === 'file');
|
||||
}, [selectedLayout]);
|
||||
const { hasFile, isPureChat, isPureFile } = useChatSplitterProps;
|
||||
|
||||
return (
|
||||
<ChatSplitterContextProvider useChatSplitterProps={useChatSplitterProps}>
|
||||
|
@ -61,12 +40,13 @@ export const ChatLayout: React.FC<ChatSplitterProps> = React.memo(
|
|||
rightChildren={<FileContainer children={children} />}
|
||||
autoSaveId="chat-splitter"
|
||||
defaultLayout={defaultSplitterLayout}
|
||||
rightHidden={isPureChat}
|
||||
preserveSide="left"
|
||||
leftPanelMinSize={hasFile ? 250 : undefined}
|
||||
leftPanelMinSize={hasFile ? 225 : undefined}
|
||||
/>
|
||||
</ChatSplitterContextProvider>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
ChatLayout.displayName = 'ChatSplitter';
|
||||
ChatLayout.displayName = 'ChatLayout';
|
||||
|
|
|
@ -3,13 +3,15 @@ import {
|
|||
createContext,
|
||||
useContextSelector
|
||||
} from '@fluentui/react-context-selector';
|
||||
import React, { PropsWithChildren, useLayoutEffect, useMemo, useState } from 'react';
|
||||
import React, { PropsWithChildren, useMemo, useState, useTransition } from 'react';
|
||||
import type { SelectedFile } from '../interfaces';
|
||||
import type { ChatSplitterProps } from '../ChatLayout';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import type { AppSplitterRef } from '@/components/layout';
|
||||
import { AppChatMessageFileType } from '@/components/messages/AppChatMessageContainer';
|
||||
import { createChatAssetRoute, createFileRoute } from './helpers';
|
||||
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
|
||||
import { DEFAULT_CHAT_OPTION } from './config';
|
||||
import { useAutoSetLayout } from '../hooks';
|
||||
|
||||
interface UseChatSplitterProps {
|
||||
defaultSelectedFile: SelectedFile | undefined;
|
||||
|
@ -24,49 +26,62 @@ export const useChatLayout = ({
|
|||
appSplitterRef,
|
||||
chatId
|
||||
}: UseChatSplitterProps) => {
|
||||
const router = useRouter();
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const onChangePage = useAppLayoutContextSelector((state) => state.onChangePage);
|
||||
const selectedLayout = defaultSelectedLayout;
|
||||
const selectedFileId = defaultSelectedFile?.id;
|
||||
const selectedFileType = defaultSelectedFile?.type;
|
||||
const hasFile = !!selectedFileId;
|
||||
|
||||
const [selectedLayout, setSelectedLayout] = useState(defaultSelectedLayout);
|
||||
const [selectedFile, setSelectedFile] = useState(defaultSelectedFile);
|
||||
|
||||
const selectedFileTitle: string = useMemo(() => {
|
||||
if (!selectedFileId) return '';
|
||||
return 'test';
|
||||
}, [selectedFileId]);
|
||||
|
||||
const animateOpenSplitter = useMemoizedFn((side: 'left' | 'right' | 'both') => {
|
||||
if (appSplitterRef.current) {
|
||||
const { animateWidth, isSideClosed } = appSplitterRef.current;
|
||||
if (side === 'left') {
|
||||
animateWidth('100%', 'left');
|
||||
} else if (side === 'right') {
|
||||
animateWidth('100%', 'right');
|
||||
} else if (side === 'both' && (isSideClosed('right') || isSideClosed('left'))) {
|
||||
animateWidth(DEFAULT_CHAT_OPTION, 'left');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const onSetSelectedFile = useMemoizedFn((file: SelectedFile) => {
|
||||
const isChatView = defaultSelectedLayout === 'chat' || defaultSelectedLayout === 'both';
|
||||
const fileType = file.type;
|
||||
const fileId = file.id;
|
||||
if (isChatView && chatId) {
|
||||
const routeRecord: Record<AppChatMessageFileType, string> = {
|
||||
collection: `/test/splitter/chat/${chatId}/collection/${file.id}`,
|
||||
dataset: `/test/splitter/chat/${chatId}/dataset/${file.id}`,
|
||||
metric: `/test/splitter/chat/${chatId}/metric/${file.id}`,
|
||||
dashboard: `/test/splitter/chat/${chatId}/dashboard/${file.id}`
|
||||
};
|
||||
if (routeRecord[fileType]) router.push(routeRecord[fileType]);
|
||||
} else {
|
||||
router.push(`/test/splitter/${fileType}/${fileId}`);
|
||||
const route =
|
||||
isChatView && chatId
|
||||
? createChatAssetRoute({ chatId, assetId: fileId, type: fileType })
|
||||
: createFileRoute({ assetId: fileId, type: fileType });
|
||||
|
||||
if (route) {
|
||||
onChangePage(route);
|
||||
setIsPureChat(false);
|
||||
startTransition(() => {
|
||||
animateOpenSplitter('both');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const onCollapseFileClick = useMemoizedFn((close?: boolean) => {
|
||||
const isCloseAction = close ?? selectedLayout === 'both';
|
||||
if (isCloseAction) {
|
||||
setSelectedLayout('chat');
|
||||
animateOpenSplitter('left');
|
||||
} else {
|
||||
setSelectedLayout('both');
|
||||
appSplitterRef.current?.animateWidth('320px', 'left');
|
||||
animateOpenSplitter('both');
|
||||
}
|
||||
});
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (defaultSelectedLayout) setSelectedLayout(defaultSelectedLayout);
|
||||
}, [defaultSelectedLayout]);
|
||||
const { setIsPureChat, isPureFile, isPureChat } = useAutoSetLayout({
|
||||
defaultSelectedLayout,
|
||||
selectedLayout
|
||||
});
|
||||
|
||||
return {
|
||||
selectedFileTitle,
|
||||
|
@ -74,9 +89,11 @@ export const useChatLayout = ({
|
|||
selectedLayout,
|
||||
selectedFileId,
|
||||
hasFile,
|
||||
|
||||
isPureFile,
|
||||
isPureChat,
|
||||
onSetSelectedFile,
|
||||
onCollapseFileClick
|
||||
onCollapseFileClick,
|
||||
animateOpenSplitter
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export const DEFAULT_CHAT_OPTION = '320px';
|
|
@ -0,0 +1,73 @@
|
|||
import type { FileType } from '@/api/buster_socket/chats';
|
||||
import { BusterRoutes, createBusterRoute } from '@/routes';
|
||||
|
||||
const chatRouteRecord: Record<FileType, (chatId: string, assetId: string) => string> = {
|
||||
collection: (chatId, assetId) =>
|
||||
createBusterRoute({
|
||||
route: BusterRoutes.APP_CHAT_ID_COLLECTION_ID,
|
||||
chatId,
|
||||
collectionId: assetId
|
||||
}),
|
||||
dataset: (chatId, assetId) =>
|
||||
createBusterRoute({
|
||||
route: BusterRoutes.APP_CHAT_ID_DATASET_ID,
|
||||
chatId,
|
||||
datasetId: assetId
|
||||
}),
|
||||
metric: (chatId, assetId) =>
|
||||
createBusterRoute({
|
||||
route: BusterRoutes.APP_CHAT_ID_METRIC_ID,
|
||||
chatId,
|
||||
metricId: assetId
|
||||
}),
|
||||
dashboard: (chatId, assetId) =>
|
||||
createBusterRoute({
|
||||
route: BusterRoutes.APP_CHAT_ID_DASHBOARD_ID,
|
||||
chatId,
|
||||
dashboardId: assetId
|
||||
}),
|
||||
term: (chatId, assetId) =>
|
||||
createBusterRoute({
|
||||
route: BusterRoutes.APP_CHAT_ID_TERM_ID,
|
||||
chatId,
|
||||
termId: assetId
|
||||
}),
|
||||
value: (chatId, assetId) =>
|
||||
createBusterRoute({
|
||||
route: BusterRoutes.APP_CHAT_ID_VALUE_ID,
|
||||
chatId,
|
||||
valueId: assetId
|
||||
})
|
||||
};
|
||||
|
||||
export const createChatAssetRoute = ({
|
||||
chatId,
|
||||
assetId,
|
||||
type
|
||||
}: {
|
||||
chatId: string;
|
||||
assetId: string;
|
||||
type: FileType;
|
||||
}) => {
|
||||
const routeBuilder = chatRouteRecord[type];
|
||||
if (!routeBuilder) return '';
|
||||
return routeBuilder(chatId, assetId);
|
||||
};
|
||||
|
||||
const fileRouteRecord: Record<FileType, (assetId: string) => string> = {
|
||||
collection: (assetId) =>
|
||||
createBusterRoute({ route: BusterRoutes.APP_COLLECTIONS_ID, collectionId: assetId }),
|
||||
dataset: (assetId) =>
|
||||
createBusterRoute({ route: BusterRoutes.APP_DATASETS_ID, datasetId: assetId }),
|
||||
metric: (assetId) => createBusterRoute({ route: BusterRoutes.APP_METRIC_ID, metricId: assetId }),
|
||||
dashboard: (assetId) =>
|
||||
createBusterRoute({ route: BusterRoutes.APP_DASHBOARD_ID, dashboardId: assetId }),
|
||||
term: (assetId) => createBusterRoute({ route: BusterRoutes.APP_TERMS_ID, termId: assetId }),
|
||||
value: (assetId) => createBusterRoute({ route: BusterRoutes.APP_VALUE_ID, valueId: assetId })
|
||||
};
|
||||
|
||||
export const createFileRoute = ({ assetId, type }: { assetId: string; type: FileType }) => {
|
||||
const routeBuilder = fileRouteRecord[type];
|
||||
if (!routeBuilder) return '';
|
||||
return routeBuilder(assetId);
|
||||
};
|
|
@ -1 +1,3 @@
|
|||
export * from './useDefaultFile';
|
||||
export * from './useAutoSetLayout';
|
||||
export * from './useDefaultSplitterLayout';
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { useUpdateLayoutEffect } from 'ahooks';
|
||||
import { useState } from 'react';
|
||||
|
||||
export const useAutoSetLayout = ({
|
||||
defaultSelectedLayout,
|
||||
selectedLayout
|
||||
}: {
|
||||
defaultSelectedLayout: 'chat' | 'file' | 'both' | undefined;
|
||||
selectedLayout: 'chat' | 'file' | 'both' | undefined;
|
||||
}): {
|
||||
isPureFile: boolean;
|
||||
isPureChat: boolean;
|
||||
setIsPureChat: (value: boolean) => void;
|
||||
} => {
|
||||
const [isPureFile, setIsPureFile] = useState(defaultSelectedLayout === 'file');
|
||||
const [isPureChat, setIsPureChat] = useState(defaultSelectedLayout === 'chat');
|
||||
|
||||
useUpdateLayoutEffect(() => {
|
||||
if (isPureFile === true) setIsPureFile(selectedLayout === 'file');
|
||||
if (isPureChat === true) setIsPureChat(selectedLayout === 'chat');
|
||||
}, [selectedLayout]);
|
||||
|
||||
return { isPureFile, isPureChat, setIsPureChat };
|
||||
};
|
|
@ -0,0 +1,15 @@
|
|||
import { useMemo } from 'react';
|
||||
|
||||
export const useDefaultSplitterLayout = ({
|
||||
defaultSelectedLayout
|
||||
}: {
|
||||
defaultSelectedLayout: 'chat' | 'file' | 'both';
|
||||
}) => {
|
||||
const defaultSplitterLayout = useMemo(() => {
|
||||
if (defaultSelectedLayout === 'chat') return ['100%', '0%'];
|
||||
if (defaultSelectedLayout === 'file') return ['0%', '100%'];
|
||||
return ['325px', 'auto'];
|
||||
}, [defaultSelectedLayout]);
|
||||
|
||||
return defaultSplitterLayout;
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
import type { AppChatMessageFileType } from '@/components/messages/AppChatMessageContainer';
|
||||
import type { FileType } from '@/api/buster_socket/chats';
|
||||
|
||||
export type SelectedFile = {
|
||||
id: string;
|
||||
type: AppChatMessageFileType;
|
||||
type: FileType;
|
||||
};
|
||||
|
|
|
@ -39,8 +39,12 @@ export const useAppLayout = () => {
|
|||
return createBusterRoute(params);
|
||||
});
|
||||
|
||||
const onChangePage = useMemoizedFn((params: BusterRoutesWithArgsRoute) => {
|
||||
const onChangePage = useMemoizedFn((params: BusterRoutesWithArgsRoute | string) => {
|
||||
if (typeof params === 'string') {
|
||||
push(params);
|
||||
} else {
|
||||
push(createBusterRoute(params));
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -149,3 +149,13 @@ export const useBusterChatIndividual = ({ chatId }: { chatId: string }) => {
|
|||
onSetSelectedAssetId
|
||||
};
|
||||
};
|
||||
|
||||
export const useBusterChatAssetIndividual = ({
|
||||
chatId,
|
||||
assetId,
|
||||
type
|
||||
}: {
|
||||
chatId: string;
|
||||
assetId: string;
|
||||
type: FileType;
|
||||
}) => {};
|
||||
|
|
|
@ -12,6 +12,7 @@ export enum BusterAppRoutes {
|
|||
APP_LOGS = '/app/logs',
|
||||
APP_DATASETS = '/app/datasets',
|
||||
APP_DATASETS_ID = '/app/datasets/:datasetId',
|
||||
|
||||
APP_DATASETS_ID_OVERVIEW = '/app/datasets/:datasetId/overview',
|
||||
APP_DATASETS_ID_PERMISSIONS_OVERVIEW = '/app/datasets/:datasetId/permissions/overview',
|
||||
APP_DATASETS_ID_PERMISSIONS_PERMISSION_GROUPS = '/app/datasets/:datasetId/permissions/permission-groups',
|
||||
|
@ -20,6 +21,18 @@ export enum BusterAppRoutes {
|
|||
APP_DATASETS_ID_EDITOR = '/app/datasets/:datasetId/editor',
|
||||
APP_TERMS = '/app/terms',
|
||||
APP_TERMS_ID = '/app/terms/:termId',
|
||||
|
||||
//NEW CHAT
|
||||
APP_CHAT_ID = '/app/chat/:chatId',
|
||||
APP_CHAT_ID_METRIC_ID = '/app/chat/:chatId/metric/:metricId',
|
||||
APP_CHAT_ID_COLLECTION_ID = '/app/chat/:chatId/collection/:collectionId',
|
||||
APP_CHAT_ID_DASHBOARD_ID = '/app/chat/:chatId/dashboard/:dashboardId',
|
||||
APP_CHAT_ID_DATASET_ID = '/app/chat/:chatId/dataset/:datasetId',
|
||||
APP_CHAT_ID_TERM_ID = '/app/chat/:chatId/term/:termId',
|
||||
APP_CHAT_ID_VALUE_ID = '/app/chat/:chatId/value/:valueId',
|
||||
APP_METRIC_ID = '/app/metric/:metricId',
|
||||
APP_VALUE_ID = '/app/value/:valueId',
|
||||
|
||||
SETTINGS = '/app/settings',
|
||||
SETTINGS_GENERAL = '/app/settings/general',
|
||||
SETTINGS_PERMISSIONS = '/app/settings/permissions',
|
||||
|
@ -193,4 +206,35 @@ export type BusterAppRoutesWithArgs = {
|
|||
};
|
||||
[BusterAppRoutes.APP_SETTINGS_ATTRIBUTES]: { route: BusterAppRoutes.APP_SETTINGS_ATTRIBUTES };
|
||||
[BusterAppRoutes.APP_SETTINGS_SECURITY]: { route: BusterAppRoutes.APP_SETTINGS_SECURITY };
|
||||
[BusterAppRoutes.APP_CHAT_ID]: { route: BusterAppRoutes.APP_CHAT_ID; chatId: string };
|
||||
[BusterAppRoutes.APP_CHAT_ID_METRIC_ID]: {
|
||||
route: BusterAppRoutes.APP_CHAT_ID_METRIC_ID;
|
||||
chatId: string;
|
||||
metricId: string;
|
||||
};
|
||||
[BusterAppRoutes.APP_CHAT_ID_COLLECTION_ID]: {
|
||||
route: BusterAppRoutes.APP_CHAT_ID_COLLECTION_ID;
|
||||
chatId: string;
|
||||
collectionId: string;
|
||||
};
|
||||
[BusterAppRoutes.APP_CHAT_ID_DASHBOARD_ID]: {
|
||||
route: BusterAppRoutes.APP_CHAT_ID_DASHBOARD_ID;
|
||||
chatId: string;
|
||||
dashboardId: string;
|
||||
};
|
||||
[BusterAppRoutes.APP_CHAT_ID_DATASET_ID]: {
|
||||
route: BusterAppRoutes.APP_CHAT_ID_DATASET_ID;
|
||||
chatId: string;
|
||||
datasetId: string;
|
||||
};
|
||||
[BusterAppRoutes.APP_CHAT_ID_TERM_ID]: {
|
||||
route: BusterAppRoutes.APP_CHAT_ID_TERM_ID;
|
||||
chatId: string;
|
||||
termId: string;
|
||||
};
|
||||
[BusterAppRoutes.APP_CHAT_ID_VALUE_ID]: {
|
||||
route: BusterAppRoutes.APP_CHAT_ID_VALUE_ID;
|
||||
chatId: string;
|
||||
valueId: string;
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue