Skip to content

Commit

Permalink
Header tabs (#27)
Browse files Browse the repository at this point in the history
* refactor(Header): separate Export and Save/load json into different btns

* chore: rename 'Syntax' route to 'syntax'

* fix(layout): better layout for aggregations

* cleanup examples table
  • Loading branch information
matias-lg authored Nov 4, 2023
1 parent 99f6387 commit 310ec2b
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 333 deletions.
13 changes: 7 additions & 6 deletions src/app/components/CodeEditor/ExamplesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ interface ExamplesTableProps {
onExampleClick: (newExample: string) => void;
}

const fetchedExamples: { [key: string]: string } = {};

const ExamplesTable = ({ onExampleClick }: ExamplesTableProps) => {
const [isOpen, setIsOpen] = useState<boolean>(false);
const t = useTranslations("home.examples");
Expand All @@ -27,16 +29,15 @@ const ExamplesTable = ({ onExampleClick }: ExamplesTableProps) => {
};

const onExampleClickHandler = (exampleName: string) => {
const exampleKey = `example ${exampleName}`;
const storedExample = localStorage.getItem(exampleKey);
if (storedExample !== null) {
onExampleClick(storedExample);
const alreadyFetchedExample = fetchedExamples[exampleName];
if (alreadyFetchedExample !== undefined) {
onExampleClick(alreadyFetchedExample);
return;
}
fetchExample(exampleName)
.then((example) => {
if (example) {
localStorage.setItem(`example ${exampleName}`, example);
fetchedExamples[exampleName] = example;
onExampleClick(example);
}
})
Expand All @@ -60,7 +61,7 @@ const ExamplesTable = ({ onExampleClick }: ExamplesTableProps) => {
{EXAMPLE_NAMES.map((exampleName) => (
<Button
key={exampleName}
className="mr-1 bg-blue-500 text-white hover:bg-blue-600"
className="mr-1 mt-3 bg-blue-500 text-white hover:bg-blue-600"
onClick={() => onExampleClickHandler(exampleName)}
>
{t(exampleName)}
Expand Down
15 changes: 4 additions & 11 deletions src/app/components/ErDiagram/hooks/useLayoutedElements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,6 @@ const getLayoutedElements = async (
const elk = new ELK();
const layoutOptions = { ...defaultOptions, ...elkOptions };

const aggregationSubGraphOptions = {
"elk.algorithm": "org.eclipse.elk.force",
"elk.force.temperature": "0.03",
"elk.spacing.nodeNode": "2.1",
"elk.force.iterations": "80",
};

const subGraphOptions = {
"elk.algorithm": "org.eclipse.elk.radial",
// "org.eclipse.elk.radial.compactor": "WEDGE_COMPACTION",
Expand Down Expand Up @@ -128,9 +121,7 @@ const getLayoutedElements = async (
isRelationship: parentNode.type === "relationship",
represents: parentNode.id,
layoutOptions:
parentNode.type === "aggregation"
? aggregationSubGraphOptions
: subGraphOptions,
parentNode.type === "aggregation" ? defaultOptions : subGraphOptions,
children: subGraphNodes,
edges: childrenEdges,
};
Expand Down Expand Up @@ -206,7 +197,8 @@ const getLayoutedElements = async (
// @ts-ignore
edges: notInSubGraphEdges.filter((n) => n.considered === undefined),
};
debug(rootGraph);

//debug(rootGraph);

// layout nodes
let layout = await elk.layout(rootGraph as unknown as ElkNode);
Expand Down Expand Up @@ -252,6 +244,7 @@ const debug = (graph: any): any => {
return asElk;
};
const str = JSON.stringify(recur(graph), null, 2);
// Visualize the resulting ELK graph in https://rtsys.informatik.uni-kiel.de/elklive/json.html using the logged object
console.log("#####");
console.log(str);
};
Expand Down
1 change: 0 additions & 1 deletion src/app/components/Header/ExportButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ const ExportButton = () => {
items={[
[t("asPDF"), () => exportToPDF(1920, 1080).catch(() => {})],
[t("asSVG"), () => onItemClick(downloadFlow(toSvg, "svg"), true)],
[t("asJSON"), () => exportToJSON()],
[t("asPNG"), () => onItemClick(downloadFlow(toPng, "png"), true)],
[t("asJPEG"), () => onItemClick(downloadFlow(toJpeg, "jpeg"), false)],
]}
Expand Down
28 changes: 23 additions & 5 deletions src/app/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,27 @@ import { useMemo } from "react";
import { BiSolidBook } from "react-icons/bi";
import { MdDownload } from "react-icons/md";
import AutoLayoutSwitch from "./AutoLayoutSwitch";
import { HeaderElement } from "./HeaderElement";
import ImportJSONButton from "./ImportJSONButton";
import SaveLoadFileButton from "./SaveLoadFileButton";

const PROJECT_GITHUB = "https://github.com/matias-lg/er";

const HeaderElement = ({
children,
className = "",
}: {
children: JSX.Element;
className: string;
}) => (
<div
className={
"mx-0 flex items-center border-border px-4 py-2 text-center tracking-wide text-slate-200 " +
className
}
>
{children}
</div>
);

const GITHUB_URL = "https://github.com/matias-lg/er";
export const Header = () => {
const t = useTranslations("home.header");
const DynamicExportButton = useMemo(
Expand Down Expand Up @@ -35,8 +52,9 @@ export const Header = () => {
<AutoLayoutSwitch title={t("autoLayout")} />
</>
</HeaderElement>

<HeaderElement className="border-l-[1px]">
<ImportJSONButton
<SaveLoadFileButton
title={t("import")}
modalTitle={t("importModal.title")}
modalDescription={t("importModal.description")}
Expand Down Expand Up @@ -64,7 +82,7 @@ const GitHubButton = () => {
return (
<a
className="ml-6 block pr-6 text-slate-400 hover:text-slate-300"
href={GITHUB_URL}
href={PROJECT_GITHUB}
target="_blank"
>
<svg
Expand Down
16 changes: 0 additions & 16 deletions src/app/components/Header/HeaderElement.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import {
useDisclosure,
} from "@chakra-ui/react";
import { ChangeEventHandler, useRef } from "react";
import { MdUpload } from "react-icons/md";
import { LuFileJson } from "react-icons/lu";
import { useJSON } from "./hooks/useJSON";
import { Dropdown } from "./Dropdown";
import { useTranslations } from "next-intl";

const validate = (json: any): boolean => {
if (!json.erDoc) return false;
Expand All @@ -37,7 +39,7 @@ const validate = (json: any): boolean => {
return true;
};

const ImportJSONButton = ({
const SaveLoadFileButton = ({
title,
modalTitle,
modalDescription,
Expand All @@ -49,7 +51,8 @@ const ImportJSONButton = ({
modalConfirm: string;
}) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const { importJSON } = useJSON();
const { importJSON, exportToJSON } = useJSON();
const t = useTranslations("home.header.saveLoad");

let fileRef = useRef<HTMLInputElement | null>(null);

Expand All @@ -59,14 +62,21 @@ const ImportJSONButton = ({
if (!files?.length) {
return;
}

// check if file is not a binary file
if (files[0].type !== "application/json") {
alert(t("invalidFile"));
return;
}

fileReader.readAsText(files[0], "UTF-8");
fileReader.onload = (e) => {
if (e.target === null) return;
const content = e.target.result;
const json = JSON.parse(content as string);
const isValid = validate(json);
if (!isValid) {
alert("Invalid JSON");
alert(t("invalidJsonFile"));
return;
}
importJSON(json);
Expand All @@ -76,9 +86,18 @@ const ImportJSONButton = ({

return (
<>
<button className="flex items-center" onClick={onOpen}>
<MdUpload size={25} /> <span className="pl-2">{title}</span>
</button>
<Dropdown
title={
<div className="flex items-center">
<LuFileJson size={25} /> <span className="pl-2">{title}</span>
</div>
}
items={[
["Save file", exportToJSON],
["Load JSON file", onOpen],
]}
/>

<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
Expand Down Expand Up @@ -106,4 +125,4 @@ const ImportJSONButton = ({
);
};

export default ImportJSONButton;
export default SaveLoadFileButton;
Loading

0 comments on commit 310ec2b

Please sign in to comment.