mirror of https://github.com/buster-so/buster.git
toggle for metric slideout
This commit is contained in:
parent
4ca917195c
commit
d17899f3d4
|
@ -1,4 +1,4 @@
|
||||||
import type { BusterChatMessageResponse } from './chatMessageInterfaces';
|
import type { BusterChatMessage, BusterChatMessageResponse } from './chatMessageInterfaces';
|
||||||
|
|
||||||
enum BusterChatStepProgress {
|
enum BusterChatStepProgress {
|
||||||
IN_PROGRESS = 'in_progress',
|
IN_PROGRESS = 'in_progress',
|
||||||
|
@ -17,5 +17,9 @@ export type ChatPost_generatingTitle = {
|
||||||
} & BusterChatStepBase;
|
} & BusterChatStepBase;
|
||||||
|
|
||||||
export type ChatPost_generatingMessage = {
|
export type ChatPost_generatingMessage = {
|
||||||
message: BusterChatMessageResponse;
|
resposnse_message: BusterChatMessageResponse;
|
||||||
|
} & BusterChatStepBase;
|
||||||
|
|
||||||
|
export type ChatPost_complete = {
|
||||||
|
message: BusterChatMessage;
|
||||||
} & BusterChatStepBase;
|
} & BusterChatStepBase;
|
||||||
|
|
|
@ -8,6 +8,7 @@ export type ChatCreateNewChat = BusterSocketRequestBase<
|
||||||
chat_id?: string | null; //send if we are following up on a chat
|
chat_id?: string | null; //send if we are following up on a chat
|
||||||
suggestion_id?: string | null; //send if we clicked on a suggestion
|
suggestion_id?: string | null; //send if we clicked on a suggestion
|
||||||
message_id?: string; //send if we want to REPLACE current message
|
message_id?: string; //send if we want to REPLACE current message
|
||||||
|
metric_id?: string; //send if we want to create a chat from a metric
|
||||||
draft_session_id?: string; //TODO: do we need this?
|
draft_session_id?: string; //TODO: do we need this?
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
@ -39,7 +40,7 @@ export type ChatsDuplicateChat = BusterSocketRequestBase<
|
||||||
'/chats/duplicate',
|
'/chats/duplicate',
|
||||||
{
|
{
|
||||||
id: string;
|
id: string;
|
||||||
message_id?: string; //send if we want to duplciate the chat starting from a specific message
|
message_id: string; //send if we want to duplciate the chat starting from a specific message
|
||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,6 @@ export type ShareRequest = {
|
||||||
user_email: string;
|
user_email: string;
|
||||||
role: ShareRole;
|
role: ShareRole;
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
remove_users?: string[]; // user_id
|
remove_users?: string[]; // user_id
|
||||||
team_permissions?: {
|
team_permissions?: {
|
||||||
team_id: string;
|
team_id: string;
|
||||||
|
|
|
@ -23,52 +23,28 @@ export type MetricSubscribeToMetric = BusterSocketRequestBase<
|
||||||
{ id: string; password?: string }
|
{ id: string; password?: string }
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type MetricCreateNewMetric = BusterSocketRequestBase<
|
|
||||||
'/metrics/post',
|
|
||||||
{
|
|
||||||
dataset_id: string | null;
|
|
||||||
metric_id: string | null;
|
|
||||||
suggestion_id?: string | null;
|
|
||||||
prompt?: string;
|
|
||||||
message_id?: string; //only send if we want to REPLACE current message
|
|
||||||
draft_session_id?: string;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type MetricUpdateMetric = BusterSocketRequestBase<
|
export type MetricUpdateMetric = BusterSocketRequestBase<
|
||||||
'/metrics/update',
|
'/metrics/update',
|
||||||
{
|
{
|
||||||
id: string; //metric id
|
id: string; //metric id
|
||||||
|
title?: string;
|
||||||
save_to_dashboard?: string;
|
save_to_dashboard?: string;
|
||||||
remove_from_dashboard?: string; // dashboard_id optional
|
remove_from_dashboard?: string; // dashboard_id optional
|
||||||
add_to_collections?: string[]; // collection_id
|
add_to_collections?: string[]; // collection_id
|
||||||
remove_from_collections?: string[]; // collection_id
|
remove_from_collections?: string[]; // collection_id
|
||||||
save_draft?: boolean;
|
|
||||||
} & ShareRequest
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type MetricUpdateMessage = BusterSocketRequestBase<
|
|
||||||
'/metrics/messages/update',
|
|
||||||
{
|
|
||||||
id: string; //messageid id
|
|
||||||
chart_config?: BusterChartConfigProps;
|
|
||||||
title?: string;
|
|
||||||
sql?: string;
|
sql?: string;
|
||||||
feedback?: 'negative';
|
chart_config?: BusterChartConfigProps;
|
||||||
status?: VerificationStatus;
|
save_draft?: boolean; //send if we want the metric (which is currently in draft) to be saved
|
||||||
}
|
feedback?: 'negative'; //send if we want to update the feedback of the metric
|
||||||
|
status?: VerificationStatus; //admin only: send if we want to update the status of the metric
|
||||||
|
} & ShareRequest
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type MetricDelete = BusterSocketRequestBase<'/metrics/delete', { ids: string[] }>;
|
export type MetricDelete = BusterSocketRequestBase<'/metrics/delete', { ids: string[] }>;
|
||||||
|
|
||||||
export type MetricGetDataByMessageId = BusterSocketRequestBase<'/metrics/data', { id: string }>;
|
export type MetricGetDataByMessageId = BusterSocketRequestBase<'/metrics/data', { id: string }>;
|
||||||
|
|
||||||
export type MetricSearch = BusterSocketRequestBase<
|
export type MetricSearch = BusterSocketRequestBase<'/metrics/search', { prompt: string }>;
|
||||||
'/metrics/search',
|
|
||||||
{
|
|
||||||
prompt: string;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type MetricDuplicate = BusterSocketRequestBase<
|
export type MetricDuplicate = BusterSocketRequestBase<
|
||||||
'/metrics/duplicate',
|
'/metrics/duplicate',
|
||||||
|
@ -84,9 +60,7 @@ export type MetricEmits =
|
||||||
| MetricListEmitPayload
|
| MetricListEmitPayload
|
||||||
| MetricUnsubscribeEmitPayload
|
| MetricUnsubscribeEmitPayload
|
||||||
| MetricUpdateMetric
|
| MetricUpdateMetric
|
||||||
| MetricCreateNewMetric
|
|
||||||
| MetricSubscribeToMetric
|
| MetricSubscribeToMetric
|
||||||
| MetricDelete
|
| MetricDelete
|
||||||
| MetricUpdateMessage
|
|
||||||
| MetricGetDataByMessageId
|
| MetricGetDataByMessageId
|
||||||
| MetricSearch;
|
| MetricSearch;
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
export default function Page() {
|
import { MetricController } from '@appControllers/MetricController';
|
||||||
return <></>;
|
import { AppAssetCheckLayout } from '@appLayouts/AppAssetCheckLayout';
|
||||||
|
|
||||||
|
export default function Page({
|
||||||
|
params: { chatId, metricId }
|
||||||
|
}: {
|
||||||
|
params: { chatId: string; metricId: string };
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<AppAssetCheckLayout metricId={metricId} type="metric">
|
||||||
|
<MetricController metricId={metricId} />
|
||||||
|
</AppAssetCheckLayout>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { AppAssetCheckLayout } from '@/app/app/_layouts/AppAssetCheckLayout';
|
import { MetricController } from '@appControllers/MetricController';
|
||||||
|
import { AppAssetCheckLayout } from '@appLayouts/AppAssetCheckLayout';
|
||||||
|
|
||||||
export default function MetricPage({
|
export default function MetricPage({
|
||||||
params: { metricId },
|
params: { metricId },
|
||||||
|
@ -10,16 +11,8 @@ export default function MetricPage({
|
||||||
const embedView = embed === 'true';
|
const embedView = embed === 'true';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppAssetCheckLayout metricId={metricId} type="metric">
|
// <AppAssetCheckLayout metricId={metricId} type="metric">
|
||||||
<></>
|
<MetricController metricId={metricId} />
|
||||||
</AppAssetCheckLayout>
|
// </AppAssetCheckLayout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
/* <MetricContentController
|
|
||||||
metricLayout={metricLayout}
|
|
||||||
metricId={metricId}
|
|
||||||
chartOnlyView={embedView}
|
|
||||||
/> */
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export const MetricController: React.FC<{
|
||||||
|
metricId: string;
|
||||||
|
}> = React.memo(({ metricId }) => {
|
||||||
|
return <div>MetricController</div>;
|
||||||
|
});
|
||||||
|
|
||||||
|
MetricController.displayName = 'MetricController';
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './MetricController';
|
|
@ -17,7 +17,7 @@ export const ChatContainer = React.memo(
|
||||||
}, [chatContentRef, scroll?.top]);
|
}, [chatContentRef, scroll?.top]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref} className="flex h-full w-full flex-col">
|
<div ref={ref} className="flex h-full w-full min-w-[225px] flex-col">
|
||||||
<ChatHeader showScrollOverflow={showScrollOverflow} />
|
<ChatHeader showScrollOverflow={showScrollOverflow} />
|
||||||
<ChatContent chatContentRef={chatContentRef} />
|
<ChatContent chatContentRef={chatContentRef} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -48,7 +48,7 @@ export const ChatInput: React.FC = React.memo(() => {
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
styles.inputCard,
|
styles.inputCard,
|
||||||
'z-10 flex flex-col items-center space-y-1.5 px-3 pb-2 pt-0.5'
|
'z-10 mx-3 mt-0.5 flex flex-col items-center space-y-1.5 overflow-hidden pb-2'
|
||||||
)}>
|
)}>
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
|
@ -60,7 +60,7 @@ export const ChatInput: React.FC = React.memo(() => {
|
||||||
variant="borderless"
|
variant="borderless"
|
||||||
onBlur={onBlurInput}
|
onBlur={onBlurInput}
|
||||||
onFocus={onFocusInput}
|
onFocus={onFocusInput}
|
||||||
className="inline-block !pl-3.5 !pr-9 align-middle"
|
className="inline-block !pl-3.5 !pr-9 !pt-2 align-middle"
|
||||||
placeholder="Ask a follow up..."
|
placeholder="Ask a follow up..."
|
||||||
value={inputValue}
|
value={inputValue}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
|
@ -78,9 +78,7 @@ export const ChatInput: React.FC = React.memo(() => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Text size="xs" type="tertiary">
|
<AIWarning />
|
||||||
Our AI may make mistakes. Check important info.
|
|
||||||
</Text>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -105,3 +103,15 @@ const useStyles = createStyles(({ token, css }) => ({
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const AIWarning = React.memo(() => {
|
||||||
|
return (
|
||||||
|
<div className="w-full overflow-hidden truncate text-center">
|
||||||
|
<Text size="xs" type="tertiary" className="truncate">
|
||||||
|
Our AI may make mistakes. Check important info.
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
AIWarning.displayName = 'AIWarning';
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {
|
||||||
createContext,
|
createContext,
|
||||||
useContextSelector
|
useContextSelector
|
||||||
} from '@fluentui/react-context-selector';
|
} from '@fluentui/react-context-selector';
|
||||||
import React, { PropsWithChildren, useTransition } from 'react';
|
import React, { PropsWithChildren, useState, useTransition } from 'react';
|
||||||
import type { SelectedFile } from '../interfaces';
|
import type { SelectedFile } from '../interfaces';
|
||||||
import type { ChatSplitterProps } from '../ChatLayout';
|
import type { ChatSplitterProps } from '../ChatLayout';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
|
@ -30,8 +30,6 @@ export const useChatLayout = ({
|
||||||
const [isPending, startTransition] = useTransition();
|
const [isPending, startTransition] = useTransition();
|
||||||
const onChangePage = useAppLayoutContextSelector((state) => state.onChangePage);
|
const onChangePage = useAppLayoutContextSelector((state) => state.onChangePage);
|
||||||
|
|
||||||
const selectedLayout = defaultSelectedLayout;
|
|
||||||
|
|
||||||
const animateOpenSplitter = useMemoizedFn((side: 'left' | 'right' | 'both') => {
|
const animateOpenSplitter = useMemoizedFn((side: 'left' | 'right' | 'both') => {
|
||||||
if (appSplitterRef.current) {
|
if (appSplitterRef.current) {
|
||||||
const { animateWidth, isSideClosed } = appSplitterRef.current;
|
const { animateWidth, isSideClosed } = appSplitterRef.current;
|
||||||
|
@ -41,6 +39,8 @@ export const useChatLayout = ({
|
||||||
animateWidth('100%', 'right');
|
animateWidth('100%', 'right');
|
||||||
} else if (side === 'both' && (isSideClosed('right') || isSideClosed('left'))) {
|
} else if (side === 'both' && (isSideClosed('right') || isSideClosed('left'))) {
|
||||||
animateWidth(DEFAULT_CHAT_OPTION, 'left');
|
animateWidth(DEFAULT_CHAT_OPTION, 'left');
|
||||||
|
setIsPureChat(false);
|
||||||
|
setIsPureFile(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -56,7 +56,6 @@ export const useChatLayout = ({
|
||||||
|
|
||||||
if (route) {
|
if (route) {
|
||||||
onChangePage(route);
|
onChangePage(route);
|
||||||
setIsPureChat(false);
|
|
||||||
startTransition(() => {
|
startTransition(() => {
|
||||||
animateOpenSplitter('both');
|
animateOpenSplitter('both');
|
||||||
});
|
});
|
||||||
|
@ -64,15 +63,34 @@ export const useChatLayout = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
const onCollapseFileClick = useMemoizedFn((close?: boolean) => {
|
const onCollapseFileClick = useMemoizedFn((close?: boolean) => {
|
||||||
const isCloseAction = close ?? selectedLayout === 'both';
|
const isCloseAction = close ?? isCollapseOpen;
|
||||||
if (isCloseAction) {
|
|
||||||
animateOpenSplitter('left');
|
if (defaultSelectedLayout === 'file') {
|
||||||
|
if (!isCloseAction && defaultSelectedFile) {
|
||||||
|
setIsCollapseOpen(true);
|
||||||
|
animateOpenSplitter('both');
|
||||||
|
} else {
|
||||||
|
setIsCollapseOpen(false);
|
||||||
|
animateOpenSplitter('right');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
animateOpenSplitter('both');
|
if (isCloseAction) {
|
||||||
|
animateOpenSplitter('left');
|
||||||
|
} else {
|
||||||
|
animateOpenSplitter('both');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { setIsPureChat, isPureFile, isPureChat } = useAutoSetLayout({
|
const {
|
||||||
|
setIsPureChat,
|
||||||
|
setIsCollapseOpen,
|
||||||
|
isPureFile,
|
||||||
|
isPureChat,
|
||||||
|
setIsPureFile,
|
||||||
|
collapseDirection,
|
||||||
|
isCollapseOpen
|
||||||
|
} = useAutoSetLayout({
|
||||||
defaultSelectedLayout
|
defaultSelectedLayout
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -83,6 +101,8 @@ export const useChatLayout = ({
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...fileLayoutContext,
|
...fileLayoutContext,
|
||||||
|
collapseDirection,
|
||||||
|
isCollapseOpen,
|
||||||
isPureFile,
|
isPureFile,
|
||||||
isPureChat,
|
isPureChat,
|
||||||
onSetSelectedFile,
|
onSetSelectedFile,
|
||||||
|
|
|
@ -7,7 +7,7 @@ interface FileContainerProps {
|
||||||
|
|
||||||
export const FileContainer: React.FC<FileContainerProps> = React.memo(({ children }) => {
|
export const FileContainer: React.FC<FileContainerProps> = React.memo(({ children }) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex min-w-[370px] flex-col">
|
<div className="flex min-w-[325px] flex-col">
|
||||||
<FileContainerHeader />
|
<FileContainerHeader />
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,29 +1,38 @@
|
||||||
import { AppMaterialIcons } from '@/components';
|
import { AppMaterialIcons } from '@/components';
|
||||||
import { Button } from 'antd';
|
import { Button } from 'antd';
|
||||||
import React from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import { useChatLayoutContextSelector } from '../../ChatLayoutContext';
|
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
|
|
||||||
const animation = {
|
|
||||||
initial: { opacity: 0 },
|
|
||||||
animate: { opacity: 1 },
|
|
||||||
exit: { opacity: 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
export const CollapseFileButton: React.FC<{
|
export const CollapseFileButton: React.FC<{
|
||||||
showCollapseButton: boolean;
|
showCollapseButton: boolean;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
}> = React.memo(({ showCollapseButton, isOpen }) => {
|
collapseDirection: 'left' | 'right';
|
||||||
const onCollapseFileClick = useChatLayoutContextSelector((state) => state.onCollapseFileClick);
|
onCollapseFileClick: (value?: boolean) => void;
|
||||||
const icon = !isOpen ? 'keyboard_double_arrow_left' : 'keyboard_double_arrow_right';
|
}> = React.memo(({ showCollapseButton, isOpen, collapseDirection, onCollapseFileClick }) => {
|
||||||
|
const icon = useMemo(() => {
|
||||||
|
if (collapseDirection === 'left') {
|
||||||
|
return isOpen ? 'keyboard_double_arrow_left' : 'keyboard_double_arrow_right';
|
||||||
|
}
|
||||||
|
return isOpen ? 'keyboard_double_arrow_right' : 'keyboard_double_arrow_left';
|
||||||
|
}, [isOpen, collapseDirection]);
|
||||||
|
|
||||||
const onClick = useMemoizedFn(() => {
|
const onClick = useMemoizedFn(() => {
|
||||||
onCollapseFileClick();
|
onCollapseFileClick();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const animation = useMemo(() => {
|
||||||
|
const baseAnimation = {
|
||||||
|
initial: { opacity: 0 },
|
||||||
|
animate: { opacity: 1 },
|
||||||
|
exit: { opacity: 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
return baseAnimation;
|
||||||
|
}, [collapseDirection, isOpen]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnimatePresence mode="wait">
|
<AnimatePresence mode="wait" initial={false}>
|
||||||
{showCollapseButton && (
|
{showCollapseButton && (
|
||||||
<motion.div variants={animation}>
|
<motion.div variants={animation}>
|
||||||
<Button onClick={onClick} type="text" icon={<AppMaterialIcons icon={icon} />}></Button>
|
<Button onClick={onClick} type="text" icon={<AppMaterialIcons icon={icon} />}></Button>
|
||||||
|
|
|
@ -23,9 +23,11 @@ export const FileContainerHeader: React.FC = React.memo(() => {
|
||||||
const { styles, cx } = useStyles();
|
const { styles, cx } = useStyles();
|
||||||
const selectedFileType = useChatLayoutContextSelector((x) => x.selectedFileType);
|
const selectedFileType = useChatLayoutContextSelector((x) => x.selectedFileType);
|
||||||
const selectedFileView = useChatLayoutContextSelector((x) => x.selectedFileView);
|
const selectedFileView = useChatLayoutContextSelector((x) => x.selectedFileView);
|
||||||
|
const onCollapseFileClick = useChatLayoutContextSelector((state) => state.onCollapseFileClick);
|
||||||
|
const collapseDirection = useChatLayoutContextSelector((state) => state.collapseDirection);
|
||||||
|
const isCollapseOpen = useChatLayoutContextSelector((state) => state.isCollapseOpen);
|
||||||
|
|
||||||
const showCollapseButton = true;
|
const showCollapseButton = true;
|
||||||
const isCollapseOpen = true; //I could get the defaultSelectedLayout from the context and check if it is 'both'?
|
|
||||||
|
|
||||||
const SelectedFileSegment = React.useMemo(
|
const SelectedFileSegment = React.useMemo(
|
||||||
() => (selectedFileType ? SelectedFileSegmentRecord[selectedFileType] : () => <></>),
|
() => (selectedFileType ? SelectedFileSegmentRecord[selectedFileType] : () => <></>),
|
||||||
|
@ -39,9 +41,17 @@ export const FileContainerHeader: React.FC = React.memo(() => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(styles.container, 'flex w-full items-center justify-between space-x-3.5 px-3')}>
|
className={cx(
|
||||||
|
styles.container,
|
||||||
|
'flex w-full items-center justify-between space-x-1 overflow-hidden px-3'
|
||||||
|
)}>
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<CollapseFileButton showCollapseButton={showCollapseButton} isOpen={isCollapseOpen} />
|
<CollapseFileButton
|
||||||
|
collapseDirection={collapseDirection}
|
||||||
|
showCollapseButton={showCollapseButton}
|
||||||
|
isOpen={isCollapseOpen}
|
||||||
|
onCollapseFileClick={onCollapseFileClick}
|
||||||
|
/>
|
||||||
{selectedFileView && <SelectedFileSegment selectedFileView={selectedFileView} />}
|
{selectedFileView && <SelectedFileSegment selectedFileView={selectedFileView} />}
|
||||||
</div>
|
</div>
|
||||||
<SelectedFileButtons selectedFileView={selectedFileView} />
|
<SelectedFileButtons selectedFileView={selectedFileView} />
|
||||||
|
|
|
@ -1,22 +1,31 @@
|
||||||
import { useUpdateLayoutEffect } from 'ahooks';
|
import { useUpdateLayoutEffect } from 'ahooks';
|
||||||
import { useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
|
|
||||||
export const useAutoSetLayout = ({
|
export const useAutoSetLayout = ({
|
||||||
defaultSelectedLayout
|
defaultSelectedLayout
|
||||||
}: {
|
}: {
|
||||||
defaultSelectedLayout: 'chat' | 'file' | 'both' | undefined;
|
defaultSelectedLayout: 'chat' | 'file' | 'both' | undefined;
|
||||||
}): {
|
}) => {
|
||||||
isPureFile: boolean;
|
|
||||||
isPureChat: boolean;
|
|
||||||
setIsPureChat: (value: boolean) => void;
|
|
||||||
} => {
|
|
||||||
const [isPureFile, setIsPureFile] = useState(defaultSelectedLayout === 'file');
|
const [isPureFile, setIsPureFile] = useState(defaultSelectedLayout === 'file');
|
||||||
const [isPureChat, setIsPureChat] = useState(defaultSelectedLayout === 'chat');
|
const [isPureChat, setIsPureChat] = useState(defaultSelectedLayout === 'chat');
|
||||||
|
const [isCollapseOpen, setIsCollapseOpen] = useState(isPureChat ? true : false);
|
||||||
|
|
||||||
useUpdateLayoutEffect(() => {
|
useUpdateLayoutEffect(() => {
|
||||||
if (isPureFile === true) setIsPureFile(defaultSelectedLayout === 'file');
|
if (isPureFile === true) setIsPureFile(defaultSelectedLayout === 'file');
|
||||||
if (isPureChat === true) setIsPureChat(defaultSelectedLayout === 'chat');
|
if (isPureChat === true) setIsPureChat(defaultSelectedLayout === 'chat');
|
||||||
}, [defaultSelectedLayout]);
|
}, [defaultSelectedLayout]);
|
||||||
|
|
||||||
return { isPureFile, isPureChat, setIsPureChat };
|
const collapseDirection: 'left' | 'right' = useMemo(() => {
|
||||||
|
return defaultSelectedLayout === 'file' ? 'left' : 'right';
|
||||||
|
}, [defaultSelectedLayout]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
isPureFile,
|
||||||
|
isPureChat,
|
||||||
|
setIsPureChat,
|
||||||
|
setIsPureFile,
|
||||||
|
collapseDirection,
|
||||||
|
setIsCollapseOpen,
|
||||||
|
isCollapseOpen
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -205,7 +205,7 @@ const MetricsEmptyState: React.FC<{
|
||||||
<ListEmptyStateWithButton
|
<ListEmptyStateWithButton
|
||||||
title="You don’t have any logs yet."
|
title="You don’t have any logs yet."
|
||||||
description="You don’t have any logs. As soon as you do, they will start to appear here."
|
description="You don’t have any logs. As soon as you do, they will start to appear here."
|
||||||
buttonText="New metric"
|
buttonText="New chat"
|
||||||
onClick={openNewMetricModal}
|
onClick={openNewMetricModal}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -215,7 +215,7 @@ const MetricsEmptyState: React.FC<{
|
||||||
<ListEmptyStateWithButton
|
<ListEmptyStateWithButton
|
||||||
title="You don’t have any metrics yet."
|
title="You don’t have any metrics yet."
|
||||||
description="You don’t have any metrics. As soon as you do, they will start to appear here."
|
description="You don’t have any metrics. As soon as you do, they will start to appear here."
|
||||||
buttonText="New metric"
|
buttonText="New chat"
|
||||||
onClick={openNewMetricModal}
|
onClick={openNewMetricModal}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -37,7 +37,7 @@ export const MetricSidebarHeader: React.FC<{
|
||||||
icon={<AppMaterialIcons icon="edit_square" />}
|
icon={<AppMaterialIcons icon="edit_square" />}
|
||||||
type="default"
|
type="default"
|
||||||
onClick={onToggleChatsModalPreflight}>
|
onClick={onToggleChatsModalPreflight}>
|
||||||
New metric
|
New Chat
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue