From ed7fd87f7a026851f878952f6d335664cbba16a0 Mon Sep 17 00:00:00 2001 From: 1ilit <1ilit@proton.me> Date: Sat, 31 Aug 2024 19:49:43 +0400 Subject: [PATCH] Fix gists being controlled on button load --- src/components/EditorHeader/ControlPanel.jsx | 9 +- src/components/EditorHeader/Modal/Modal.jsx | 8 +- src/components/EditorHeader/Modal/Share.jsx | 118 ++++++++++--------- src/components/Workspace.jsx | 49 +++++++- 4 files changed, 116 insertions(+), 68 deletions(-) diff --git a/src/components/EditorHeader/ControlPanel.jsx b/src/components/EditorHeader/ControlPanel.jsx index e1bc35f..834a4de 100644 --- a/src/components/EditorHeader/ControlPanel.jsx +++ b/src/components/EditorHeader/ControlPanel.jsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useContext, useState } from "react"; import { IconCaretdown, IconChevronRight, @@ -71,7 +71,7 @@ import { exportSQL } from "../../utils/exportSQL"; import { databases } from "../../data/databases"; import { jsonToMermaid } from "../../utils/exportAs/mermaid"; import { isRtl } from "../../i18n/utils/rtl"; -import Share from "./Modal/Share"; +import { IdContext } from "../Workspace"; export default function ControlPanel({ diagramId, @@ -114,6 +114,7 @@ export default function ControlPanel({ const { selectedElement, setSelectedElement } = useSelect(); const { transform, setTransform } = useTransform(); const { t, i18n } = useTranslation(); + const { setGistId } = useContext(IdContext); const navigate = useNavigate(); const invertLayout = (component) => @@ -783,6 +784,7 @@ export default function ControlPanel({ setEnums([]); setUndoStack([]); setRedoStack([]); + setGistId(""); }) .catch(() => Toast.error(t("oops_smth_went_wrong"))); }, @@ -1372,12 +1374,11 @@ export default function ControlPanel({ onClick={() => setModal(MODAL.SHARE)} > {t("share")} - {" "} + )} {layout.toolbar && toolbar()} - { - if (modal === MODAL.SHARE) return; switch (modal) { case MODAL.IMPORT: return ( @@ -341,8 +341,8 @@ export default function Modal({ return ; case MODAL.LANGUAGE: return ; - // case MODAL.SHARE: - // return ; + case MODAL.SHARE: + return ; case MODAL.GITHUB_TOKEN: return ; default: @@ -354,7 +354,7 @@ export default function Modal({ { setExportData(() => ({ diff --git a/src/components/EditorHeader/Modal/Share.jsx b/src/components/EditorHeader/Modal/Share.jsx index 58f46f3..c776576 100644 --- a/src/components/EditorHeader/Modal/Share.jsx +++ b/src/components/EditorHeader/Modal/Share.jsx @@ -1,16 +1,27 @@ -import { Button, Input, Modal, Spin, Toast } from "@douyinfe/semi-ui"; -import { MODAL } from "../../../data/constants"; +import { Button, Input, Spin, Toast } from "@douyinfe/semi-ui"; import { useCallback, useContext, useEffect, useState, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { Octokit } from "octokit"; import { IdContext } from "../../Workspace"; import { IconLink } from "@douyinfe/semi-icons"; -import { isRtl } from "../../../i18n/utils/rtl"; +import { + useAreas, + useDiagram, + useEnums, + useNotes, + useTypes, +} from "../../../hooks"; +import { databases } from "../../../data/databases"; -export default function Share({ modal, setModal }) { - const { t, i18n } = useTranslation(); +export default function Share({ title }) { + const { t } = useTranslation(); const { gistId, setGistId } = useContext(IdContext); - const [loading, setLoading] = useState(false); + const [loading, setLoading] = useState(true); + const { tables, relationships, database } = useDiagram(); + const { notes } = useNotes(); + const { areas } = useAreas(); + const { types } = useTypes(); + const { enums } = useEnums(); const userToken = localStorage.getItem("github_token"); const octokit = useMemo(() => { @@ -23,6 +34,19 @@ export default function Share({ modal, setModal }) { [gistId], ); + const diagramToString = useCallback(() => { + return JSON.stringify({ + tables: tables, + relationships: relationships, + notes: notes, + subjectAreas: areas, + database: database, + ...(databases[database].hasTypes && { types: types }), + ...(databases[database].hasEnums && { enums: enums }), + title: title, + }); + }, [areas, notes, tables, relationships, database, title, enums, types]); + const updateGist = useCallback(async () => { setLoading(true); try { @@ -30,8 +54,8 @@ export default function Share({ modal, setModal }) { gist_id: gistId, description: "drawDB diagram", files: { - "test.json": { - content: '{"Hello":"SEAMAN"}', + "share.json": { + content: diagramToString(), }, }, headers: { @@ -43,7 +67,7 @@ export default function Share({ modal, setModal }) { } finally { setLoading(false); } - }, [gistId, octokit]); + }, [gistId, octokit, diagramToString]); const generateLink = useCallback(async () => { setLoading(true); @@ -52,8 +76,8 @@ export default function Share({ modal, setModal }) { description: "drawDB diagram", public: false, files: { - "test.json": { - content: '{"Hello":"WORLD"}', + "share.json": { + content: diagramToString(), }, }, headers: { @@ -66,7 +90,7 @@ export default function Share({ modal, setModal }) { } finally { setLoading(false); } - }, [octokit, setGistId]); + }, [octokit, setGistId, diagramToString]); useEffect(() => { const updateOrGenerateLink = async () => { @@ -83,7 +107,7 @@ export default function Share({ modal, setModal }) { } }; updateOrGenerateLink(); - }, [gistId, generateLink, setModal, updateGist]); + }, [gistId, generateLink, updateGist]); const copyLink = () => { navigator.clipboard @@ -96,48 +120,32 @@ export default function Share({ modal, setModal }) { }); }; + if (loading) + return ( +
+ +
{t("loading")}
+
+ ); + return ( - } - onCancel={() => setModal(MODAL.NONE)} - centered - closeOnEsc={true} - cancelText={t("cancel")} - width={600} - bodyStyle={{ - maxHeight: window.innerHeight - 280, - overflow: "auto", - direction: "ltr", - }} - > - {loading ? ( -
- -
{t("loading")}
-
- ) : ( -
-
- - -
-
-
- * Sharing this link will not create a live real-time collaboration - session -
-
- )} -
+
+
+ + +
+
+
+ * Sharing this link will not create a live real-time collaboration + session +
+
); } diff --git a/src/components/Workspace.jsx b/src/components/Workspace.jsx index b0e861f..a845b51 100644 --- a/src/components/Workspace.jsx +++ b/src/components/Workspace.jsx @@ -1,4 +1,10 @@ -import { useState, useEffect, useCallback, createContext } from "react"; +import { + useState, + useEffect, + useCallback, + createContext, + useMemo, +} from "react"; import ControlPanel from "./EditorHeader/ControlPanel"; import Canvas from "./EditorCanvas/Canvas"; import { CanvasContextProvider } from "../context/CanvasContext"; @@ -23,6 +29,8 @@ import { Modal } from "@douyinfe/semi-ui"; import { useTranslation } from "react-i18next"; import { databases } from "../data/databases"; import { isRtl } from "../i18n/utils/rtl"; +import { useSearchParams } from "react-router-dom"; +import { Octokit } from "octokit"; export const IdContext = createContext({ gistId: "" }); @@ -54,7 +62,13 @@ export default function WorkSpace() { } = useDiagram(); const { undoStack, redoStack, setUndoStack, setRedoStack } = useUndoRedo(); const { t, i18n } = useTranslation(); - + let [searchParams] = useSearchParams(); + const userToken = localStorage.getItem("github_token"); + const octokit = useMemo(() => { + return new Octokit({ + auth: userToken ?? import.meta.env.VITE_GITHUB_ACCESS_TOKEN, + }); + }, [userToken]); const handleResize = (e) => { if (!resize) return; const w = isRtl(i18n.language) ? window.innerWidth - e.clientX : e.clientX; @@ -307,6 +321,24 @@ export default function WorkSpace() { selectedDb, ]); + const loadFromGist = useCallback( + async (shareId) => { + try { + const res = await octokit.request(`GET /gists/${shareId}`, { + gist_id: shareId, + headers: { + "X-GitHub-Api-Version": "2022-11-28", + }, + }); + const diagramSrc = res.data.files["share.json"].content; + console.log(diagramSrc); + } catch (e) { + console.log(e); + } + }, + [octokit], + ); + useEffect(() => { if ( tables?.length === 0 && @@ -336,7 +368,9 @@ export default function WorkSpace() { ]); useEffect(() => { - setSaveState(State.SAVING); + if (gistId && gistId !== "") { + setSaveState(State.SAVING); + } }, [gistId, setSaveState]); useEffect(() => { @@ -348,8 +382,13 @@ export default function WorkSpace() { useEffect(() => { document.title = "Editor | drawDB"; - load(); - }, [load]); + const shareId = searchParams.get("shareId"); + if (shareId) { + loadFromGist(shareId); + } else { + load(); + } + }, [load, searchParams, loadFromGist]); return (