Create and update gist on click

This commit is contained in:
1ilit 2024-08-29 17:05:47 +04:00
parent 488641ddcc
commit 7dcecf3c1f
4 changed files with 125 additions and 69 deletions

View File

@ -9,7 +9,6 @@ import {
IconUndo, IconUndo,
IconRedo, IconRedo,
IconEdit, IconEdit,
IconShareStroked,
} from "@douyinfe/semi-icons"; } from "@douyinfe/semi-icons";
import { Link, useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import icon from "../../assets/icon_dark_64.png"; import icon from "../../assets/icon_dark_64.png";
@ -71,6 +70,7 @@ import { exportSQL } from "../../utils/exportSQL";
import { databases } from "../../data/databases"; import { databases } from "../../data/databases";
import { jsonToMermaid } from "../../utils/exportAs/mermaid"; import { jsonToMermaid } from "../../utils/exportAs/mermaid";
import { isRtl } from "../../i18n/utils/rtl"; import { isRtl } from "../../i18n/utils/rtl";
import ShareButton from "./ShareButton";
export default function ControlPanel({ export default function ControlPanel({
diagramId, diagramId,
@ -1363,15 +1363,7 @@ export default function ControlPanel({
{layout.header && ( {layout.header && (
<div className="flex justify-between items-center me-7"> <div className="flex justify-between items-center me-7">
{header()} {header()}
<Button <ShareButton setModal={setModal} />
type="primary"
className="text-base me-2 pe-6 ps-5 py-[18px] rounded-md"
size="default"
icon={<IconShareStroked />}
onClick={() => setModal(MODAL.SHARE)}
>
{t("share")}
</Button>
</div> </div>
)} )}
{layout.toolbar && toolbar()} {layout.toolbar && toolbar()}

View File

@ -1,43 +1,7 @@
import { Banner, Button, Spin } from "@douyinfe/semi-ui"; import { Banner } from "@douyinfe/semi-ui";
import { IconLink } from "@douyinfe/semi-icons";
import { useTranslation } from "react-i18next";
import { Octokit } from "octokit";
import { useState } from "react";
import { MODAL } from "../../../data/constants"; import { MODAL } from "../../../data/constants";
export default function Share({ setModal }) { export default function Share({ setModal }) {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const generateLink = async () => {
setLoading(true);
const userToken = localStorage.getItem("github_token");
const octokit = new Octokit({
auth:
userToken ?? import.meta.env.VITE_GITHUB_ACCESS_TOKEN,
});
try {
const res = await octokit.request("POST /gists", {
description: "Hello world",
public: false,
files: {
"test.json": {
content: '{"Hello":"WORLD"}',
},
},
headers: {
"X-GitHub-Api-Version": "2022-11-28",
},
});
console.log(res);
} catch (e) {
console.error(e);
} finally {
setLoading(false);
}
};
return ( return (
<div id="share" className="space-y-4"> <div id="share" className="space-y-4">
@ -68,18 +32,7 @@ export default function Share({ setModal }) {
</ul> </ul>
} }
/> />
<div className="text-center">
<Button
type="primary"
theme="solid"
className="text-base me-2 pe-6 ps-5 py-[18px] rounded-md"
size="default"
icon={loading ? <Spin /> : <IconLink />}
onClick={generateLink}
>
{t("generate_link")}
</Button>
</div>
</div> </div>
); );
} }

View File

@ -0,0 +1,97 @@
import { Button, Spin } from "@douyinfe/semi-ui";
import { IconShareStroked } from "@douyinfe/semi-icons";
import { useTranslation } from "react-i18next";
import { Octokit } from "octokit";
import { MODAL } from "../../data/constants";
import { useContext, useState } from "react";
import { IdContext } from "../Workspace";
export default function ShareButton({ setModal }) {
const { t } = useTranslation();
const { gistId, setGistId } = useContext(IdContext);
const [loading, setLoading] = useState(false);
const updateGist = async () => {
setLoading(true);
const userToken = localStorage.getItem("github_token");
const octokit = new Octokit({
auth: userToken ?? import.meta.env.VITE_GITHUB_ACCESS_TOKEN,
});
try {
const res = await octokit.request(`PATCH /gists/${gistId}`, {
gist_id: gistId,
description: "drawDB diagram",
files: {
"test.json": {
content: '{"Hello":"SEAMAN"}',
},
},
headers: {
"X-GitHub-Api-Version": "2022-11-28",
},
});
console.log(res);
} catch (e) {
console.error(e);
} finally {
setLoading(false);
}
};
const generateLink = async () => {
setLoading(true);
const userToken = localStorage.getItem("github_token");
const octokit = new Octokit({
auth: userToken ?? import.meta.env.VITE_GITHUB_ACCESS_TOKEN,
});
try {
const res = await octokit.request("POST /gists", {
description: "drawDB diagram",
public: false,
files: {
"test.json": {
content: '{"Hello":"WORLD"}',
},
},
headers: {
"X-GitHub-Api-Version": "2022-11-28",
},
});
setGistId(res.data.id);
} catch (e) {
console.error(e);
} finally {
setLoading(false);
}
};
const onShare = async () => {
try {
if (!gistId || gistId === "") {
await generateLink();
} else {
await updateGist();
}
} catch (e) {
console.error(e);
} finally {
setModal(MODAL.SHARE);
}
};
return (
<Button
type="primary"
className="text-base me-2 pe-6 ps-5 py-[18px] rounded-md"
size="default"
icon={loading ? <Spin /> : <IconShareStroked />}
onClick={onShare}
>
{t("share")}
</Button>
);
}

View File

@ -1,4 +1,4 @@
import { useState, useEffect, useCallback } from "react"; import { useState, useEffect, useCallback, createContext } from "react";
import ControlPanel from "./EditorHeader/ControlPanel"; import ControlPanel from "./EditorHeader/ControlPanel";
import Canvas from "./EditorCanvas/Canvas"; import Canvas from "./EditorCanvas/Canvas";
import { CanvasContextProvider } from "../context/CanvasContext"; import { CanvasContextProvider } from "../context/CanvasContext";
@ -24,8 +24,11 @@ import { useTranslation } from "react-i18next";
import { databases } from "../data/databases"; import { databases } from "../data/databases";
import { isRtl } from "../i18n/utils/rtl"; import { isRtl } from "../i18n/utils/rtl";
export const IdContext = createContext({ gistId: "" });
export default function WorkSpace() { export default function WorkSpace() {
const [id, setId] = useState(0); const [id, setId] = useState(0);
const [gistId, setGistId] = useState("");
const [title, setTitle] = useState("Untitled Diagram"); const [title, setTitle] = useState("Untitled Diagram");
const [resize, setResize] = useState(false); const [resize, setResize] = useState(false);
const [width, setWidth] = useState(340); const [width, setWidth] = useState(340);
@ -72,6 +75,7 @@ export default function WorkSpace() {
.add({ .add({
database: database, database: database,
name: title, name: title,
gistId: gistId ?? "",
lastModified: new Date(), lastModified: new Date(),
tables: tables, tables: tables,
references: relationships, references: relationships,
@ -100,6 +104,7 @@ export default function WorkSpace() {
notes: notes, notes: notes,
areas: areas, areas: areas,
todos: tasks, todos: tasks,
gistId: gistId ?? "",
pan: transform.pan, pan: transform.pan,
zoom: transform.zoom, zoom: transform.zoom,
...(databases[database].hasEnums && { enums: enums }), ...(databases[database].hasEnums && { enums: enums }),
@ -146,6 +151,7 @@ export default function WorkSpace() {
setSaveState, setSaveState,
database, database,
enums, enums,
gistId,
]); ]);
const load = useCallback(async () => { const load = useCallback(async () => {
@ -161,6 +167,7 @@ export default function WorkSpace() {
setDatabase(DB.GENERIC); setDatabase(DB.GENERIC);
} }
setId(d.id); setId(d.id);
setGistId(d.gistId);
setTitle(d.name); setTitle(d.name);
setTables(d.tables); setTables(d.tables);
setRelationships(d.references); setRelationships(d.references);
@ -196,6 +203,7 @@ export default function WorkSpace() {
setDatabase(DB.GENERIC); setDatabase(DB.GENERIC);
} }
setId(diagram.id); setId(diagram.id);
setGistId(diagram.gistId);
setTitle(diagram.name); setTitle(diagram.name);
setTables(diagram.tables); setTables(diagram.tables);
setRelationships(diagram.references); setRelationships(diagram.references);
@ -327,11 +335,15 @@ export default function WorkSpace() {
setSaveState, setSaveState,
]); ]);
useEffect(() => {
setSaveState(State.SAVING);
}, [gistId, setSaveState]);
useEffect(() => { useEffect(() => {
if (saveState !== State.SAVING) return; if (saveState !== State.SAVING) return;
save(); save();
}, [id, saveState, save]); }, [id, gistId, saveState, save]);
useEffect(() => { useEffect(() => {
document.title = "Editor | drawDB"; document.title = "Editor | drawDB";
@ -341,6 +353,7 @@ export default function WorkSpace() {
return ( return (
<div className="h-full flex flex-col overflow-hidden theme"> <div className="h-full flex flex-col overflow-hidden theme">
<IdContext.Provider value={{ gistId, setGistId }}>
<ControlPanel <ControlPanel
diagramId={id} diagramId={id}
setDiagramId={setId} setDiagramId={setId}
@ -349,6 +362,7 @@ export default function WorkSpace() {
lastSaved={lastSaved} lastSaved={lastSaved}
setLastSaved={setLastSaved} setLastSaved={setLastSaved}
/> />
</IdContext.Provider>
<div <div
className="flex h-full overflow-y-auto" className="flex h-full overflow-y-auto"
onPointerUp={(e) => e.isPrimary && setResize(false)} onPointerUp={(e) => e.isPrimary && setResize(false)}