Bladeren bron

update embed architecture

Aykut Saraç 2 jaren geleden
bovenliggende
commit
51cae9e9f6
3 gewijzigde bestanden met toevoegingen van 82 en 21 verwijderingen
  1. 1 2
      src/components/Graph/index.tsx
  2. 54 19
      src/pages/Widget/index.tsx
  3. 27 0
      src/pages/embed.tsx

+ 1 - 2
src/components/Graph/index.tsx

@@ -46,7 +46,6 @@ const GraphComponent = ({
   setSelectedNode,
 }: LayoutProps) => {
   const [minScale, setMinScale] = React.useState(0.4);
-  const setGraphValue = useGraph(state => state.setGraphValue);
   const setLoading = useGraph(state => state.setLoading);
   const setConfig = useConfig(state => state.setConfig);
   const centerView = useConfig(state => state.centerView);
@@ -98,7 +97,7 @@ const GraphComponent = ({
         });
       }
     },
-    [centerView, setGraphValue, size.height, size.width]
+    [centerView, setLoading, size.height, size.width]
   );
 
   const onCanvasClick = React.useCallback(() => {

+ 54 - 19
src/pages/Widget/index.tsx

@@ -1,11 +1,12 @@
 import React from "react";
 import dynamic from "next/dynamic";
 import { useRouter } from "next/router";
-import { decompress } from "compress-json";
 import { parse } from "jsonc-parser";
-import { baseURL } from "src/constants/data";
+import toast from "react-hot-toast";
+import { baseURL, defaultJson } from "src/constants/data";
+import { NodeModal } from "src/containers/Modals/NodeModal";
+import useConfig from "src/hooks/store/useConfig";
 import useGraph from "src/hooks/store/useGraph";
-import { isValidJson } from "src/utils/isValidJson";
 import { parser } from "src/utils/jsonParser";
 import styled from "styled-components";
 
@@ -39,34 +40,68 @@ function inIframe() {
 }
 
 const WidgetPage = () => {
-  const { query, push } = useRouter();
+  const [json, setJson] = React.useState(defaultJson);
+  const [isModalVisible, setModalVisible] = React.useState(false);
+  const [selectedNode, setSelectedNode] = React.useState<[string, string][]>([]);
+
+  const collapsedNodes = useGraph(state => state.collapsedNodes);
+  const collapsedEdges = useGraph(state => state.collapsedEdges);
+  const loading = useGraph(state => state.loading);
   const setGraphValue = useGraph(state => state.setGraphValue);
+  const centerView = useConfig(state => state.centerView);
+  const { push } = useRouter();
 
+  const openModal = React.useCallback(() => setModalVisible(true), []);
   React.useEffect(() => {
-    if (query.json) {
-      const jsonURI = decodeURIComponent(query.json as string);
-      const isJsonValid = isValidJson(jsonURI);
+    const nodeList = collapsedNodes.map(id => `[id$="node-${id}"]`);
+    const edgeList = collapsedEdges.map(id => `[class$="edge-${id}"]`);
+
+    const hiddenItems = document.querySelectorAll(".hide");
+    hiddenItems.forEach(item => item.classList.remove("hide"));
 
-      if (isJsonValid) {
-        const jsonDecoded = decompress(parse(isJsonValid));
-        const { nodes, edges } = parser(JSON.stringify(jsonDecoded));
+    if (nodeList.length) {
+      const selectedNodes = document.querySelectorAll(nodeList.join(","));
+      const selectedEdges = document.querySelectorAll(edgeList.join(","));
 
-        setGraphValue("nodes", nodes);
-        setGraphValue("edges", edges);
+      selectedNodes.forEach(node => node.classList.add("hide"));
+      selectedEdges.forEach(edge => edge.classList.add("hide"));
+    }
+  }, [collapsedNodes, collapsedEdges, loading]);
+
+  React.useEffect(() => {
+    const handler = (event: { data: string }) => {
+      try {
+        const parsedJson = JSON.stringify(parse(event.data));
+        setJson(parsedJson);
+      } catch (error) {
+        toast.error("Invalid JSON!");
       }
+    };
+
+    window.addEventListener("message", handler);
+    return () => window.removeEventListener("message", handler);
+  }, []);
+
+  React.useEffect(() => {
+    if (json) {
+      const { nodes, edges } = parser(json);
+
+      setGraphValue("nodes", nodes);
+      setGraphValue("edges", edges);
     }
 
     if (!inIframe()) push("/");
-  }, [push, query.json, setGraphValue]);
+  }, [push, json, setGraphValue, centerView]);
 
   return (
     <>
-      <Graph isWidget />
-      <StyledAttribute
-        href={`${baseURL}/editor?json=${query.json}`}
-        target="_blank"
-        rel="noreferrer"
-      >
+      <Graph openModal={openModal} setSelectedNode={setSelectedNode} isWidget />
+      <NodeModal
+        selectedNode={selectedNode}
+        visible={isModalVisible}
+        closeModal={() => setModalVisible(false)}
+      />
+      <StyledAttribute href={`${baseURL}/editor`} target="_blank" rel="noreferrer">
         jsoncrack.com
       </StyledAttribute>
     </>

+ 27 - 0
src/pages/embed.tsx

@@ -0,0 +1,27 @@
+import React from "react";
+import styled from "styled-components";
+
+const StyledPageWrapper = styled.iframe`
+  height: 100vh;
+  width: 100%;
+  border: none;
+`;
+
+const Embed = () => {
+  return (
+    <StyledPageWrapper
+      scrolling="no"
+      title="Untitled"
+      src="https://codepen.io/AykutSarac/embed/PoawZYo?default-tab=html%2Cresult"
+      loading="lazy"
+      allowTransparency
+      allowFullScreen
+    >
+      See the Pen <a href="https://codepen.io/AykutSarac/pen/PoawZYo">Untitled</a> by
+      Aykut Saraç (<a href="https://codepen.io/AykutSarac">@AykutSarac</a>) on{" "}
+      <a href="https://codepen.io">CodePen</a>.
+    </StyledPageWrapper>
+  );
+};
+
+export default Embed;