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

Merge pull request #8246 from weseek/feat/134432-able-to-open-edit-table-modal

feat: Able to open edit table modal in editor
Yuki Takei 2 лет назад
Родитель
Сommit
ecf41d3014

+ 1 - 1
apps/app/src/client/services/side-effects/handsontable-modal-launcher-for-view.ts

@@ -83,7 +83,7 @@ export const useHandsontableModalLauncherForView = (opts?: {
     const handler = (bol: number, eol: number) => {
       const markdown = currentPage.revision.body;
       const currentMarkdownTable = mtu.getMarkdownTableFromLine(markdown, bol, eol);
-      openHandsontableModal(currentMarkdownTable, undefined, false, table => saveByHandsontableModal(table, bol, eol));
+      openHandsontableModal(currentMarkdownTable, false, table => saveByHandsontableModal(table, bol, eol));
     };
     globalEmitter.on('launchHandsonTableModal', handler);
 

+ 5 - 2
apps/app/src/components/PageEditor/HandsontableModal.tsx

@@ -1,5 +1,6 @@
 import React, { useState } from 'react';
 
+import { useHandsontableModalForEditor } from '@growi/editor/src/stores/use-handsontable';
 import { HotTable } from '@handsontable/react';
 import Handsontable from 'handsontable';
 import { useTranslation } from 'next-i18next';
@@ -32,11 +33,13 @@ export const HandsontableModal = (): JSX.Element => {
 
   const { t } = useTranslation('commons');
   const { data: handsontableModalData, close: closeHandsontableModal } = useHandsontableModal();
+  const { data: handsontableModalForEditorData } = useHandsontableModalForEditor();
 
   const isOpened = handsontableModalData?.isOpened ?? false;
+  const isOpendInEditor = handsontableModalForEditorData?.isOpened ?? false;
   const table = handsontableModalData?.table;
   const autoFormatMarkdownTable = handsontableModalData?.autoFormatMarkdownTable ?? false;
-  const editor = handsontableModalData?.editor;
+  const editor = handsontableModalForEditorData?.editor;
   const onSave = handsontableModalData?.onSave;
 
   const defaultMarkdownTable = () => {
@@ -441,7 +444,7 @@ export const HandsontableModal = (): JSX.Element => {
 
   return (
     <Modal
-      isOpen={isOpened}
+      isOpen={isOpened || isOpendInEditor}
       toggle={cancel}
       backdrop="static"
       keyboard={false}

+ 3 - 7
apps/app/src/stores/modal.tsx

@@ -507,8 +507,6 @@ type HandsonTableModalSaveHandler = (table: MarkdownTable) => void;
 type HandsontableModalStatus = {
   isOpened: boolean,
   table: MarkdownTable,
-  // TODO: Define editor type
-  editor?: any,
   autoFormatMarkdownTable?: boolean,
   // onSave is passed only when editing table directly from the page.
   onSave?: HandsonTableModalSaveHandler
@@ -517,7 +515,6 @@ type HandsontableModalStatus = {
 type HandsontableModalStatusUtils = {
   open(
     table: MarkdownTable,
-    editor?: any,
     autoFormatMarkdownTable?: boolean,
     onSave?: HandsonTableModalSaveHandler
   ): void
@@ -541,7 +538,6 @@ export const useHandsontableModal = (status?: HandsontableModalStatus): SWRRespo
   const initialData: HandsontableModalStatus = {
     isOpened: false,
     table: defaultMarkdownTable(),
-    editor: undefined,
     autoFormatMarkdownTable: false,
   };
 
@@ -549,14 +545,14 @@ export const useHandsontableModal = (status?: HandsontableModalStatus): SWRRespo
 
   const { mutate } = swrResponse;
 
-  const open = useCallback((table: MarkdownTable, editor?: any, autoFormatMarkdownTable?: boolean, onSave?: HandsonTableModalSaveHandler): void => {
+  const open = useCallback((table: MarkdownTable, autoFormatMarkdownTable?: boolean, onSave?: HandsonTableModalSaveHandler): void => {
     mutate({
-      isOpened: true, table, editor, autoFormatMarkdownTable, onSave,
+      isOpened: true, table, autoFormatMarkdownTable, onSave,
     });
   }, [mutate]);
   const close = useCallback((): void => {
     mutate({
-      isOpened: false, table: defaultMarkdownTable(), editor: undefined, autoFormatMarkdownTable: false, onSave: undefined,
+      isOpened: false, table: defaultMarkdownTable(), autoFormatMarkdownTable: false, onSave: undefined,
     });
   }, [mutate]);
 

+ 2 - 2
packages/editor/src/components/CodeMirrorEditor/CodeMirrorEditor.tsx

@@ -139,12 +139,12 @@ export const CodeMirrorEditor = (props: Props): JSX.Element => {
     }
 
     return '';
-  }, [isUploading, isDragAccept,isDragReject, acceptedFileType]);
+  }, [isUploading, isDragAccept, isDragReject, acceptedFileType]);
 
   return (
     <div className={`${style['codemirror-editor']} flex-expand-vert`}>
       <div {...getRootProps()} className={`dropzone ${fileUploadState} flex-expand-vert`}>
-        <FileDropzoneOverlay isEnabled={isDragActive}/>
+        <FileDropzoneOverlay isEnabled={isDragActive} />
         <CodeMirrorEditorContainer ref={containerRef} />
         <Toolbar editorKey={editorKey} onFileOpen={open} acceptedFileType={acceptedFileType} />
       </div>

+ 19 - 2
packages/editor/src/components/CodeMirrorEditor/Toolbar/TableButton.tsx

@@ -1,6 +1,23 @@
-export const TableButton = (): JSX.Element => {
+import { useCallback } from 'react';
+
+import { useCodeMirrorEditorIsolated } from '../../../stores';
+import { useHandsontableModalForEditor } from '../../../stores/use-handsontable';
+
+type Props = {
+  editorKey: string,
+}
+
+export const TableButton = (props: Props): JSX.Element => {
+  const { editorKey } = props;
+  const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(editorKey);
+  const { open: openTableModal } = useHandsontableModalForEditor();
+  const editor = codeMirrorEditor?.view;
+  const openTableModalHandler = useCallback(() => {
+    openTableModal(editor);
+  }, [editor]);
+
   return (
-    <button type="button" className="btn btn-toolbar-button">
+    <button type="button" className="btn btn-toolbar-button" onClick={openTableModalHandler}>
       <span className="material-symbols-outlined fs-5">table_chart</span>
     </button>
   );

+ 1 - 1
packages/editor/src/components/CodeMirrorEditor/Toolbar/Toolbar.tsx

@@ -27,7 +27,7 @@ export const Toolbar = memo((props: Props): JSX.Element => {
       <EmojiButton
         editorKey={editorKey}
       />
-      <TableButton />
+      <TableButton editorKey={editorKey} />
       <DiagramButton />
       <TemplateButton />
     </div>

+ 45 - 0
packages/editor/src/stores/use-handsontable.ts

@@ -0,0 +1,45 @@
+import { useCallback } from 'react';
+
+import { EditorView } from '@codemirror/view';
+import { useSWRStatic } from '@growi/core/dist/swr';
+import type { SWRResponse } from 'swr';
+
+type HandsontableModalStatus = {
+  isOpened: boolean,
+  editor?: EditorView,
+}
+
+type HandsontableModalStatusUtils = {
+  open(
+    editor?: EditorView,
+  ): void
+  close(): void
+}
+
+export const useHandsontableModalForEditor = (status?: HandsontableModalStatus): SWRResponse<HandsontableModalStatus, Error> & HandsontableModalStatusUtils => {
+  const initialData: HandsontableModalStatus = {
+    isOpened: false,
+    editor: undefined,
+  };
+
+  const swrResponse = useSWRStatic<HandsontableModalStatus, Error>('handsontableModalStatus', status, { fallbackData: initialData });
+
+  const { mutate } = swrResponse;
+
+  const open = useCallback((editor?: EditorView): void => {
+    mutate({
+      isOpened: true, editor,
+    });
+  }, [mutate]);
+  const close = useCallback((): void => {
+    mutate({
+      isOpened: false, editor: undefined,
+    });
+  }, [mutate]);
+
+  return {
+    ...swrResponse,
+    open,
+    close,
+  };
+};