Browse Source

simplify code

Aykut Saraç 3 years ago
parent
commit
11e67298a0

+ 19 - 25
src/components/Sidebar/index.tsx

@@ -13,12 +13,7 @@ import { MdAutoGraph } from "react-icons/md";
 import { useLocalStorage } from "usehooks-ts";
 import { defaultValue } from "src/containers/JsonEditor";
 import { getNextLayout } from "src/containers/LiveEditor/helpers";
-
-interface Config {
-  layout: "TB" | "BT" | "LR" | "RL";
-  minimap: boolean;
-  controls: boolean;
-}
+import { StorageConfig } from "src/typings/global";
 
 const StyledSidebar = styled.div`
   display: flex;
@@ -93,14 +88,25 @@ const StyledImportFile = styled.label`
 `;
 
 export const Sidebar = () => {
-  const [jsonFile, setJsonFile] = React.useState<File | any>(null);
-  const [_, setJson] = useLocalStorage("json", JSON.stringify(defaultValue));
-  const [config, setConfig] = useLocalStorage<Config>("config", {
+  const [jsonFile, setJsonFile] = React.useState<File | null>(null);
+  const [json, setJson] = useLocalStorage("json", JSON.stringify(defaultValue));
+  const [config, setConfig] = useLocalStorage<StorageConfig>("config", {
     layout: "RL",
     minimap: true,
     controls: true,
   });
 
+  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    if (e.target.files) setJsonFile(e.target.files?.item(0));
+  };
+
+  const toggle = (setting: "minimap" | "controls") => {
+    setConfig((c) => ({
+      ...c,
+      [setting]: !c[setting],
+    }));
+  };
+
   React.useEffect(() => {
     if (jsonFile) {
       const reader = new FileReader();
@@ -110,8 +116,6 @@ export const Sidebar = () => {
         setJson(data.target?.result as string);
       };
     }
-
-    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [jsonFile]);
 
   return (
@@ -152,24 +156,14 @@ export const Sidebar = () => {
         <StyledElement
           title="Toggle Minimap"
           as="a"
-          onClick={() =>
-            setConfig((c) => ({
-              ...c,
-              minimap: !c.minimap,
-            }))
-          }
+          onClick={() => toggle("minimap")}
         >
           <FaMap />
         </StyledElement>
         <StyledElement
           title="Toggle Controls"
           as="a"
-          onClick={() =>
-            setConfig((c) => ({
-              ...c,
-              controls: !c.controls,
-            }))
-          }
+          onClick={() => toggle("controls")}
         >
           <AiFillControl />
         </StyledElement>
@@ -177,8 +171,8 @@ export const Sidebar = () => {
           <a>
             <StyledImportFile>
               <input
-                key={jsonFile}
-                onChange={(e) => setJsonFile(e.target.files?.item(0))}
+                key={jsonFile?.name}
+                onChange={handleFileChange}
                 type="file"
                 accept="application/JSON"
               />

+ 4 - 8
src/containers/JsonEditor/index.tsx

@@ -4,14 +4,14 @@ import JSONInput from "react-json-editor-ajrm";
 import { useLocalStorage } from "usehooks-ts";
 import locale from "react-json-editor-ajrm/locale/en";
 
-type JsonData = {
+interface JsonData {
   plainText: string;
   markupText: string;
   json: string;
   jsObject?: object;
   lines: number;
   error: boolean;
-};
+}
 
 const StyledJSONInput = styled(JSONInput)`
   margin-top: 10px;
@@ -66,12 +66,7 @@ export const JsonEditor: React.FC = () => {
   }, []);
 
   const handleChange = (data: JsonData) => {
-    try {
-      JSON.parse(data.json);
-      setJson(data.json);
-    } catch (error: any) {
-      console.error("Invalid JSON!", error.stack);
-    }
+    if (!data.error) setJson(data.json);
   };
 
   return (
@@ -80,6 +75,7 @@ export const JsonEditor: React.FC = () => {
       onChange={handleChange}
       locale={locale}
       height="100%"
+      width="auto"
     />
   );
 };

+ 10 - 6
src/containers/LiveEditor/FlowWrapper.tsx

@@ -5,7 +5,9 @@ import ReactFlow, {
   Elements,
   MiniMap,
   NodeExtent,
+  OnLoadParams,
 } from "react-flow-renderer";
+import { StorageConfig } from "src/typings/global";
 import { useLocalStorage } from "usehooks-ts";
 import { defaultValue } from "../JsonEditor";
 import { getLayout, getLayoutPosition } from "./helpers";
@@ -22,16 +24,20 @@ const nodeTypes = {
 
 export const FlowWrapper: React.FC = () => {
   const [json] = useLocalStorage("json", JSON.stringify(defaultValue));
-  const [config] = useLocalStorage("config", {
+  const [config] = useLocalStorage<StorageConfig>("config", {
     layout: "RL",
     minimap: true,
     controls: true,
   });
 
   const [elements, setElements] = React.useState<Elements>([]);
-  const [rfInstance, setRfInstance] = React.useState<any>(null);
+  const [rfInstance, setRfInstance] = React.useState<OnLoadParams | null>(null);
   const [valid, setValid] = React.useState(true);
 
+  const handleClick = () => {
+    setElements(getLayoutPosition(config.layout, elements));
+  };
+
   React.useEffect(() => {
     if (rfInstance) rfInstance.fitView();
   }, [rfInstance]);
@@ -53,15 +59,13 @@ export const FlowWrapper: React.FC = () => {
       nodeExtent={nodeExtent}
       elements={elements}
       nodeTypes={nodeTypes}
-      onLoad={(rf: any) => setRfInstance(rf)}
+      onLoad={setRfInstance}
     >
       {config.minimap && <MiniMap />}
       {config.controls && (
         <Controls>
           <ControlButton
-            onClick={() =>
-              setElements(getLayoutPosition(config.layout, elements))
-            }
+            onClick={handleClick}
             style={{ gridColumn: "1 / 3", width: "auto" }}
           >
             Format

+ 4 - 2
src/containers/LiveEditor/Node.tsx

@@ -2,6 +2,8 @@ import React from "react";
 import { Handle, Position } from "react-flow-renderer";
 import styled from "styled-components";
 
+type Data = { label: string | object };
+
 const StyledWrapper = styled.div<{
   isArray?: boolean;
   isElement?: boolean;
@@ -24,7 +26,7 @@ const StyledKey = styled.span`
   color: ${({ theme }) => theme.BLURPLE};
 `;
 
-export const CustomNodeComponent: React.FC<{ data: any; id: string }> = ({
+export const CustomNodeComponent: React.FC<{ data: Data; id: string }> = ({
   id,
   data,
 }) => {
@@ -49,7 +51,7 @@ export const CustomNodeComponent: React.FC<{ data: any; id: string }> = ({
     );
   }
 
-  if (typeof json === "object") {
+  if (json instanceof Object) {
     const keyPairs = Object.entries(json);
 
     // temporary solution for array items

+ 3 - 2
src/containers/LiveEditor/helpers.ts

@@ -1,5 +1,6 @@
 import dagre from "dagre";
 import { Elements, isNode, Position } from "react-flow-renderer";
+import { Layout } from "src/typings/global";
 import { parser } from "src/utils/json-editor-parser";
 
 const dagreGraph = new dagre.graphlib.Graph();
@@ -39,7 +40,7 @@ export const getLayoutPosition = (direction: string, elements: Elements, dynamic
   return layoutedElements;
 };
 
-export function getNextLayout(layout: "TB" | "BT" | "RL" | "LR") {
+export function getNextLayout(layout: Layout) {
   switch (layout) {
     case "TB":
       return "BT";
@@ -55,7 +56,7 @@ export function getNextLayout(layout: "TB" | "BT" | "RL" | "LR") {
   }
 }
 
-export function getLayout(layout: string, json: string, dynamic = false) {
+export function getLayout(layout: Layout, json: string, dynamic = false) {
   const jsonToGraph = parser(json);
   const layoutedElements = getLayoutPosition(layout, jsonToGraph, dynamic);