Просмотр исходного кода

Merge pull request #10253 from weseek/imrpv/170380-assistant-wizard-ui

imprv: Assistant wizard UI
Yuki Takei 7 месяцев назад
Родитель
Сommit
dc6e782daf

+ 14 - 1
apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementHome.tsx

@@ -1,5 +1,5 @@
 import React, {
-  useCallback, useState, useMemo, type JSX,
+  useCallback, useState, useMemo, useRef, useEffect, type JSX,
 } from 'react';
 
 import { useTranslation } from 'react-i18next';
@@ -19,6 +19,7 @@ import { AiAssistantManagementHeader } from './AiAssistantManagementHeader';
 import { ShareScopeWarningModal } from './ShareScopeWarningModal';
 
 type Props = {
+  isActivePane: boolean;
   shouldEdit: boolean;
   name: string;
   description: string;
@@ -35,6 +36,7 @@ type Props = {
 
 export const AiAssistantManagementHome = (props: Props): JSX.Element => {
   const {
+    isActivePane,
     shouldEdit,
     name,
     description,
@@ -56,6 +58,8 @@ export const AiAssistantManagementHome = (props: Props): JSX.Element => {
 
   const [isShareScopeWarningModalOpen, setIsShareScopeWarningModalOpen] = useState(false);
 
+  const inputRef = useRef<HTMLInputElement>(null);
+
   const totalSelectedPageCount = useMemo(() => {
     return selectedPages.reduce((total, selectedPage) => {
       const descendantCount = selectedPage.descendantCount ?? 0;
@@ -113,6 +117,14 @@ export const AiAssistantManagementHome = (props: Props): JSX.Element => {
     await onUpsertAiAssistant();
   }, [accessScope, onUpsertAiAssistant, selectedUserGroupsForAccessScope, selectedUserGroupsForShareScope, shareScope]);
 
+  // Autofocus
+  useEffect(() => {
+    // Only when creating a new assistant
+    if (isActivePane && !shouldEdit) {
+      inputRef.current?.focus();
+    }
+  }, [isActivePane, shouldEdit]);
+
   return (
     <>
       <AiAssistantManagementHeader
@@ -130,6 +142,7 @@ export const AiAssistantManagementHome = (props: Props): JSX.Element => {
               className="border-0 border-bottom border-2 px-0 rounded-0"
               value={name}
               onChange={e => onNameChange(e.target.value)}
+              innerRef={inputRef}
             />
           </div>
 

+ 20 - 10
apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementKeywordSearch.tsx

@@ -1,15 +1,15 @@
 import React, {
-  useRef, useMemo, useCallback, useState, type KeyboardEvent,
+  useRef, useMemo, useCallback, useState, useEffect, type KeyboardEvent,
 } from 'react';
 
 import type { IPageHasId } from '@growi/core';
 import { isGlobPatternPath } from '@growi/core/dist/utils/page-path-utils';
 import { type TypeaheadRef, Typeahead } from 'react-bootstrap-typeahead';
 import { useTranslation } from 'react-i18next';
-import SimpleBar from 'simplebar-react';
 import {
   ModalBody,
 } from 'reactstrap';
+import SimpleBar from 'simplebar-react';
 
 import { useSWRxSearch } from '~/stores/search';
 
@@ -37,12 +37,13 @@ const isSelectedSearchKeyword = (value: unknown): value is SelectedSearchKeyword
 
 
 type Props = {
+  isActivePane: boolean
   baseSelectedPages: SelectablePage[],
   updateBaseSelectedPages: (pages: SelectablePage[]) => void;
 }
 
 export const AiAssistantKeywordSearch = (props: Props): JSX.Element => {
-  const { baseSelectedPages, updateBaseSelectedPages } = props;
+  const { isActivePane, baseSelectedPages, updateBaseSelectedPages } = props;
 
   const [selectedSearchKeywords, setSelectedSearchKeywords] = useState<Array<SelectedSearchKeyword>>([]);
   const {
@@ -136,6 +137,13 @@ export const AiAssistantKeywordSearch = (props: Props): JSX.Element => {
     changePageMode(isNewAiAssistant ? AiAssistantManagementModalPageMode.HOME : AiAssistantManagementModalPageMode.PAGES);
   }, [changePageMode, isNewAiAssistant, selectedPages, updateBaseSelectedPages]);
 
+  // Autofocus
+  useEffect(() => {
+    if (isActivePane) {
+      typeaheadRef.current?.focus();
+    }
+  }, [isActivePane]);
+
   return (
     <div className={moduleClass}>
       <AiAssistantManagementHeader
@@ -173,13 +181,15 @@ export const AiAssistantKeywordSearch = (props: Props): JSX.Element => {
               {t('modal_ai_assistant.select_assistant_reference_pages')}
             </h4>
             <div className="px-4">
-              <SelectablePagePageList
-                isEditable
-                pages={pagesWithGlobPath ?? []}
-                method="add"
-                onClickMethodButton={addPage}
-                disablePagePaths={selectedPagesArray.map(page => page.path)}
-              />
+              <SimpleBar className="page-list-container" style={{ maxHeight: '300px' }}>
+                <SelectablePagePageList
+                  isEditable
+                  pages={pagesWithGlobPath ?? []}
+                  method="add"
+                  onClickMethodButton={addPage}
+                  disablePagePaths={selectedPagesArray.map(page => page.path)}
+                />
+              </SimpleBar>
             </div>
           </>
         )}

+ 2 - 0
apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementModal.tsx

@@ -249,6 +249,7 @@ const AiAssistantManagementModalSubstance = (): JSX.Element => {
 
         <TabPane tabId={AiAssistantManagementModalPageMode.KEYWORD_SEARCH}>
           <AiAssistantKeywordSearch
+            isActivePane={pageMode === AiAssistantManagementModalPageMode.KEYWORD_SEARCH}
             baseSelectedPages={selectedPages}
             updateBaseSelectedPages={selectPageHandler}
           />
@@ -263,6 +264,7 @@ const AiAssistantManagementModalSubstance = (): JSX.Element => {
 
         <TabPane tabId={AiAssistantManagementModalPageMode.HOME}>
           <AiAssistantManagementHome
+            isActivePane={pageMode === AiAssistantManagementModalPageMode.HOME}
             shouldEdit={shouldEdit}
             name={name}
             description={description}

+ 1 - 1
apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementPageTreeSelection.module.scss

@@ -5,7 +5,7 @@
 
   .page-tree-item {
     .list-group-item {
-      padding: 0.4rem 0 !important;
+      padding: 0.4rem 1rem !important;
     }
   }
 }

+ 1 - 1
apps/app/src/features/openai/client/components/AiAssistant/AiAssistantManagementModal/AiAssistantManagementPageTreeSelection.tsx

@@ -48,7 +48,7 @@ const SelectablePageTree = memo((props: { onClickAddPageButton: (page: Selectabl
       return (
         <button
           type="button"
-          className="border-0 rounded btn p-0 me-2"
+          className="border-0 rounded btn p-0"
           onClick={(e) => {
             e.stopPropagation();
             pageTreeItemClickHandler(page);

+ 1 - 1
apps/app/src/features/openai/client/components/AiAssistant/Sidebar/AiAssistantList.tsx

@@ -183,7 +183,7 @@ export const AiAssistantList: React.FC<AiAssistantListProps> = ({
         </h3>
         <span
           className="material-symbols-outlined"
-        >{`keyboard_arrow_${isCollapsed ? 'up' : 'down'}`}
+        >{`keyboard_arrow_${isCollapsed ? 'down' : 'right'}`}
         </span>
       </button>