|
|
@@ -3,141 +3,20 @@ import {
|
|
|
memo, useCallback, useState, useRef, useEffect,
|
|
|
} from 'react';
|
|
|
|
|
|
-import withLoadingProps from 'next-dynamic-loading-props';
|
|
|
-import dynamic from 'next/dynamic';
|
|
|
import SimpleBar from 'simplebar-react';
|
|
|
-import { useIsomorphicLayoutEffect } from 'usehooks-ts';
|
|
|
|
|
|
-import { ResizableAreaFallback } from '~/client/components/Sidebar/ResizableArea/ResizableAreaFallback';
|
|
|
-import type { ResizableAreaProps } from '~/client/components/Sidebar/ResizableArea/props';
|
|
|
-
|
|
|
-// Constants
|
|
|
-const RIGHT_SIDEBAR_MIN_WIDTH = 320;
|
|
|
-const RIGHT_SIDEBAR_DEFAULT_WIDTH = 700;
|
|
|
-
|
|
|
-// Import ResizableArea with loading fallback
|
|
|
-const ResizableArea = withLoadingProps<ResizableAreaProps>(useLoadingProps => dynamic(
|
|
|
- () => import('~/client/components/Sidebar/ResizableArea').then(mod => mod.ResizableArea),
|
|
|
- {
|
|
|
- ssr: false,
|
|
|
- loading: () => {
|
|
|
- // eslint-disable-next-line react-hooks/rules-of-hooks
|
|
|
- const { children, ...rest } = useLoadingProps();
|
|
|
- return <ResizableAreaFallback {...rest}>{children}</ResizableAreaFallback>;
|
|
|
- },
|
|
|
- },
|
|
|
-));
|
|
|
+const RIGHT_SIDEBAR_WIDTH = 500;
|
|
|
|
|
|
// Assistant Info Component
|
|
|
const AssistantInfo: FC = () => {
|
|
|
return (
|
|
|
- <div className="p-3">
|
|
|
- <h6>アシスタントへの指示</h6>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
-
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
- <p>あなたは生成 AI の専門家および、リサーチャーです。ナレッジベースの Wiki ツールである GROWI の AI 機能に関する情報...</p>
|
|
|
-
|
|
|
-
|
|
|
- <h6 className="mt-4">参照するページ</h6>
|
|
|
- <ul className="list-unstyled">
|
|
|
- <li><a href="#">/Project/GROWI/新機能/GROWI AI/*</a></li>
|
|
|
- <li><a href="#">/AI導入検討/調査</a></li>
|
|
|
- </ul>
|
|
|
+ <div className="p-3 w-100">
|
|
|
+ {/* AI Chat Screen Implementation */}
|
|
|
+ {/* TODO: https://redmine.weseek.co.jp/issues/161511 */}
|
|
|
</div>
|
|
|
);
|
|
|
};
|
|
|
|
|
|
-// Resizable Container
|
|
|
-type ResizableContainerProps = {
|
|
|
- children: React.ReactNode;
|
|
|
- onResize?: (width: number) => void;
|
|
|
- initialWidth?: number;
|
|
|
-};
|
|
|
-
|
|
|
-const ResizableContainer: FC<ResizableContainerProps> = memo(({ children, onResize, initialWidth = RIGHT_SIDEBAR_DEFAULT_WIDTH }) => {
|
|
|
- const [width, setWidth] = useState(initialWidth);
|
|
|
-
|
|
|
- const handleResize = useCallback((newWidth: number) => {
|
|
|
- setWidth(newWidth);
|
|
|
- onResize?.(newWidth);
|
|
|
- }, [onResize]);
|
|
|
-
|
|
|
- return (
|
|
|
- <div className="d-flex h-100">
|
|
|
- <ResizableArea
|
|
|
- className="flex-grow-1 transition-width"
|
|
|
- width={width}
|
|
|
- minWidth={RIGHT_SIDEBAR_MIN_WIDTH}
|
|
|
- onResize={handleResize}
|
|
|
- >
|
|
|
- {children}
|
|
|
- </ResizableArea>
|
|
|
- </div>
|
|
|
- );
|
|
|
-});
|
|
|
-
|
|
|
// Right Sidebar Tab
|
|
|
type RightSidebarTabProps = {
|
|
|
isOpen: boolean;
|
|
|
@@ -191,20 +70,13 @@ const RightSidebarHead: FC<RightSidebarHeadProps> = memo(({ onClose }) => {
|
|
|
// Main Right Sidebar Component
|
|
|
export const RightSidebar: FC = memo((): JSX.Element => {
|
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
- const [isClient, setClient] = useState(false);
|
|
|
- const [width, setWidth] = useState(RIGHT_SIDEBAR_DEFAULT_WIDTH);
|
|
|
const sidebarRef = useRef<HTMLDivElement>(null);
|
|
|
const sidebarScrollerRef = useRef<HTMLDivElement>(null);
|
|
|
|
|
|
- useIsomorphicLayoutEffect(() => {
|
|
|
- setClient(true);
|
|
|
- }, []);
|
|
|
-
|
|
|
const handleToggle = useCallback(() => {
|
|
|
setIsOpen(prev => !prev);
|
|
|
}, []);
|
|
|
|
|
|
- // Handle clicks outside of sidebar
|
|
|
useEffect(() => {
|
|
|
const handleClickOutside = (event: MouseEvent) => {
|
|
|
if (isOpen && sidebarRef.current && !sidebarRef.current.contains(event.target as Node)) {
|
|
|
@@ -218,10 +90,6 @@ export const RightSidebar: FC = memo((): JSX.Element => {
|
|
|
};
|
|
|
}, [isOpen]);
|
|
|
|
|
|
- if (!isClient) {
|
|
|
- return <></>;
|
|
|
- }
|
|
|
-
|
|
|
return (
|
|
|
<>
|
|
|
<RightSidebarTab
|
|
|
@@ -232,30 +100,19 @@ export const RightSidebar: FC = memo((): JSX.Element => {
|
|
|
<div
|
|
|
ref={sidebarRef}
|
|
|
className="position-fixed top-0 end-0 h-100 border-start bg-white shadow-sm"
|
|
|
- style={{ zIndex: 1500 }}
|
|
|
+ style={{ zIndex: 1500, width: `${RIGHT_SIDEBAR_WIDTH}px` }}
|
|
|
data-testid="grw-right-sidebar"
|
|
|
>
|
|
|
- <ResizableContainer onResize={setWidth}>
|
|
|
- <div className="h-100 d-flex flex-column">
|
|
|
- <RightSidebarHead onClose={handleToggle} />
|
|
|
- <div className="flex-grow-1" style={{ height: 'calc(100% - 56px)' }}>
|
|
|
- <SimpleBar
|
|
|
- scrollableNodeProps={{ ref: sidebarScrollerRef }}
|
|
|
- style={{ height: '100%' }}
|
|
|
- className="h-100 position-relative"
|
|
|
- autoHide
|
|
|
- >
|
|
|
- <AssistantInfo />
|
|
|
- </SimpleBar>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </ResizableContainer>
|
|
|
+ <RightSidebarHead onClose={handleToggle} />
|
|
|
+ <SimpleBar
|
|
|
+ scrollableNodeProps={{ ref: sidebarScrollerRef }}
|
|
|
+ className="h-100 position-relative"
|
|
|
+ autoHide
|
|
|
+ >
|
|
|
+ <AssistantInfo />
|
|
|
+ </SimpleBar>
|
|
|
</div>
|
|
|
)}
|
|
|
</>
|
|
|
);
|
|
|
});
|
|
|
-
|
|
|
-// Usage example:
|
|
|
-// Usage example:
|
|
|
-// <RightSidebar />
|