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

Merge pull request #8324 from weseek/feat/136480-able-to-use-templete-modal-in-editor

feat: Able to use templete modal in editor
soma 2 лет назад
Родитель
Сommit
f4043e6266

+ 1 - 1
apps/app/src/components/TemplateModal/TemplateModal.tsx

@@ -5,6 +5,7 @@ import React, {
 import assert from 'assert';
 
 import { Lang } from '@growi/core';
+import { useTemplateModal, type TemplateModalStatus } from '@growi/editor/src/stores/use-template-modal';
 import {
   extractSupportedLocales, getLocalizedTemplate, type TemplateSummary,
 } from '@growi/pluginkit/dist/v4';
@@ -21,7 +22,6 @@ import {
 } from 'reactstrap';
 
 import { useSWRxTemplate, useSWRxTemplates } from '~/features/templates/stores';
-import { useTemplateModal, type TemplateModalStatus } from '~/stores/modal';
 import { usePersonalSettings } from '~/stores/personal-settings';
 import { usePreviewOptions } from '~/stores/renderer';
 import loggerFactory from '~/utils/logger';

+ 0 - 32
apps/app/src/stores/modal.tsx

@@ -630,38 +630,6 @@ export const useBookmarkFolderDeleteModal = (status?: DeleteBookmarkFolderModalS
   };
 };
 
-/*
- * TemplateModal
- */
-
-type TemplateSelectedCallback = (templateText: string) => void;
-type TemplateModalOptions = {
-  onSubmit?: TemplateSelectedCallback,
-}
-export type TemplateModalStatus = TemplateModalOptions & {
-  isOpened: boolean,
-}
-
-type TemplateModalUtils = {
-  open(opts: TemplateModalOptions): void,
-  close(): void,
-}
-
-export const useTemplateModal = (): SWRResponse<TemplateModalStatus, Error> & TemplateModalUtils => {
-
-  const initialStatus: TemplateModalStatus = { isOpened: false };
-  const swrResponse = useStaticSWR<TemplateModalStatus, Error>('templateModal', undefined, { fallbackData: initialStatus });
-
-  return Object.assign(swrResponse, {
-    open: (opts: TemplateModalOptions) => {
-      swrResponse.mutate({ isOpened: true, onSubmit: opts.onSubmit });
-    },
-    close: () => {
-      swrResponse.mutate({ isOpened: false });
-    },
-  });
-};
-
 /**
  * DeleteAttachmentModal
  */

+ 24 - 2
packages/editor/src/components/CodeMirrorEditor/Toolbar/TemplateButton.tsx

@@ -1,6 +1,28 @@
-export const TemplateButton = (): JSX.Element => {
+import { useCallback } from 'react';
+
+import { useCodeMirrorEditorIsolated } from '../../../stores';
+import { useTemplateModal } from '../../../stores/use-template-modal';
+
+type Props = {
+  editorKey: string,
+}
+
+export const TemplateButton = (props: Props): JSX.Element => {
+  const { editorKey } = props;
+  const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(editorKey);
+  const { open: openTemplateModal } = useTemplateModal();
+
+  const onClickTempleteButton = useCallback(() => {
+    const editor = codeMirrorEditor?.view;
+    if (editor != null) {
+      const insertText = (text: string) => editor.dispatch(editor.state.replaceSelection(text));
+      const onSubmit = (templateText: string) => insertText(templateText);
+      openTemplateModal({ onSubmit });
+    }
+  }, [codeMirrorEditor?.view, openTemplateModal]);
+
   return (
-    <button type="button" className="btn btn-toolbar-button">
+    <button type="button" className="btn btn-toolbar-button" onClick={onClickTempleteButton}>
       <span className="material-symbols-outlined fs-5">file_copy</span>
     </button>
   );

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

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

+ 30 - 0
packages/editor/src/stores/use-template-modal.ts

@@ -0,0 +1,30 @@
+import { useSWRStatic } from '@growi/core/dist/swr';
+import type { SWRResponse } from 'swr';
+
+type TemplateSelectedCallback = (templateText: string) => void;
+type TemplateModalOptions = {
+  onSubmit?: TemplateSelectedCallback,
+}
+export type TemplateModalStatus = TemplateModalOptions & {
+  isOpened: boolean,
+}
+
+type TemplateModalUtils = {
+  open(opts: TemplateModalOptions): void,
+  close(): void,
+}
+
+export const useTemplateModal = (): SWRResponse<TemplateModalStatus, Error> & TemplateModalUtils => {
+
+  const initialStatus: TemplateModalStatus = { isOpened: false };
+  const swrResponse = useSWRStatic<TemplateModalStatus, Error>('templateModal', undefined, { fallbackData: initialStatus });
+
+  return Object.assign(swrResponse, {
+    open: (opts: TemplateModalOptions) => {
+      swrResponse.mutate({ isOpened: true, onSubmit: opts.onSubmit });
+    },
+    close: () => {
+      swrResponse.mutate({ isOpened: false });
+    },
+  });
+};