diff --git a/packages/ui/index.html b/packages/ui/index.html index 69895eb22..39a9286d4 100644 --- a/packages/ui/index.html +++ b/packages/ui/index.html @@ -3,7 +3,8 @@ - Ignition + + Hardhat Ignition
diff --git a/packages/ui/public/favicon.ico b/packages/ui/public/favicon.ico new file mode 100644 index 000000000..d5e6b335e Binary files /dev/null and b/packages/ui/public/favicon.ico differ diff --git a/packages/ui/src/components/shared.tsx b/packages/ui/src/components/shared.tsx index 1210b0ccf..48005feea 100644 --- a/packages/ui/src/components/shared.tsx +++ b/packages/ui/src/components/shared.tsx @@ -14,3 +14,7 @@ export const Panel = styled.div` border: 1px solid black; padding: 1rem; `; + +export const Breadcrumb = styled.div` + padding-bottom: 1rem; +`; diff --git a/packages/ui/src/main.tsx b/packages/ui/src/main.tsx index 1bcf46e48..246006793 100644 --- a/packages/ui/src/main.tsx +++ b/packages/ui/src/main.tsx @@ -7,7 +7,6 @@ import { } from "@nomicfoundation/ignition-core/ui-helpers"; import ReactDOM from "react-dom/client"; import { RouterProvider, createHashRouter } from "react-router-dom"; -import { FutureDetails } from "./pages/future-details/future-details"; import { VisualizationOverview } from "./pages/visualization-overview/visualization-overview"; const loadDeploymentFromEmbeddedDiv = (): IgnitionModule< @@ -49,10 +48,6 @@ const main = async () => { path: "/", element: , }, - { - path: "/future/:futureId", - element: , - }, ]); ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( diff --git a/packages/ui/src/pages/future-details/components/future-summary.tsx b/packages/ui/src/pages/future-details/components/future-summary.tsx deleted file mode 100644 index 3ffbd30e8..000000000 --- a/packages/ui/src/pages/future-details/components/future-summary.tsx +++ /dev/null @@ -1,193 +0,0 @@ -import { - Future, - FutureType, - isFuture, -} from "@nomicfoundation/ignition-core/ui-helpers"; -import { PageTitle, Panel } from "../../../components/shared"; -import { SummaryHeader } from "../../../components/summary-header"; -import { argumentTypeToString } from "../../../utils/argumentTypeToString"; - -export const FutureSummary: React.FC<{ - future: Future; -}> = ({ future }) => { - const title = resolveTitleFor(future); - - return ( -
-
- {title} -
- - - - -
- -
-
-
- ); -}; - -function resolveTitleFor(future: Future): string { - switch (future.type) { - case FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT: - return `Contract deploy - ${future.contractName}`; - case FutureType.CONTRACT_DEPLOYMENT: - return `Contract deploy from Artifact - ${future.contractName}`; - case FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT: - return `Library deploy - ${future.contractName}`; - case FutureType.LIBRARY_DEPLOYMENT: - return `Library deploy from Artifact - ${future.contractName}`; - case FutureType.CONTRACT_CALL: - return `Call - ${future.contract.contractName}/${future.functionName}`; - case FutureType.STATIC_CALL: - return `Static call - ${future.contract.contractName}/${future.functionName}`; - case FutureType.NAMED_ARTIFACT_CONTRACT_AT: - return `Existing contract - ${future.contractName} (${ - typeof future.address === "string" - ? future.address - : isFuture(future.address) - ? future.address.id - : argumentTypeToString(future.address) - })`; - case FutureType.CONTRACT_AT: - return `Existing contract from Artifact - ${future.contractName} (${ - typeof future.address === "string" - ? future.address - : isFuture(future.address) - ? future.address.id - : argumentTypeToString(future.address) - })`; - case FutureType.READ_EVENT_ARGUMENT: - return `Read event argument from future - ${future.id}`; - case FutureType.SEND_DATA: - return `Send data - ${future.id}`; - } -} - -const FutureDetailsSection: React.FC<{ future: Future }> = ({ future }) => { - switch (future.type) { - case FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT: - return ( -
-

Contract - {future.contractName}

-

Constructor Args

-
    - {Object.entries(future.constructorArgs).map(([key, value]) => ( -
  • - {key} - {argumentTypeToString(value)} -
  • - ))} -
-
- ); - case FutureType.CONTRACT_DEPLOYMENT: - return ( -
-

Contract - {future.contractName}

-

Constructor Args

-
    - {Object.entries(future.constructorArgs).map(([key, value]) => ( -
  • - {key} - {argumentTypeToString(value)} -
  • - ))} -
-
- ); - case FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT: - return ( -
-

Library - {future.contractName}

-
- ); - case FutureType.LIBRARY_DEPLOYMENT: - return ( -
-

Library - {future.contractName}

-
- ); - case FutureType.CONTRACT_CALL: - return ( -
-

Contract - {future.contract.contractName}

-

function - {future.functionName}

-

Args

-
    - {Object.entries(future.args).map(([, value]) => ( -
  • {argumentTypeToString(value)}
  • - ))} -
-
- ); - case FutureType.STATIC_CALL: - return ( -
-

Contract - {future.contract.contractName}

-

function - {future.functionName}

-

Args

-
    - {Object.entries(future.args).map(([, value]) => ( -
  • {argumentTypeToString(value)}
  • - ))} -
-
- ); - case FutureType.NAMED_ARTIFACT_CONTRACT_AT: - return ( -
-

Contract - {future.contractName}

-

- Address -{" "} - {typeof future.address === "string" - ? future.address - : isFuture(future.address) - ? future.address.id - : argumentTypeToString(future.address)} -

-
- ); - - case FutureType.CONTRACT_AT: - return ( -
-

Contract - {future.contractName}

-

- Address -{" "} - {typeof future.address === "string" - ? future.address - : isFuture(future.address) - ? future.address.id - : argumentTypeToString(future.address)} -

-
- ); - case FutureType.READ_EVENT_ARGUMENT: - return ( -
-

Future - {future.futureToReadFrom.id}

- {future.futureToReadFrom !== future.emitter ? ( -

Emitter - {future.emitter.id}

- ) : null} -

Event - {future.eventName}

-

Event index - {future.eventIndex}

-

Argument - {future.nameOrIndex}

-
- ); - case FutureType.SEND_DATA: - return ( -
-

- To -{" "} - {typeof future.to === "string" - ? future.to - : isFuture(future.to) - ? future.to.id - : argumentTypeToString(future.to)} -

-

Data - {future.data}

-
- ); - } -}; diff --git a/packages/ui/src/pages/future-details/future-details.tsx b/packages/ui/src/pages/future-details/future-details.tsx deleted file mode 100644 index 5b0a22027..000000000 --- a/packages/ui/src/pages/future-details/future-details.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { - IgnitionModule, - IgnitionModuleResult, -} from "@nomicfoundation/ignition-core/ui-helpers"; -import React, { useMemo } from "react"; -import { useParams } from "react-router-dom"; -import { Page } from "../../components/shared"; -import { getFutureById } from "../../queries/futures"; -import { FutureSummary } from "./components/future-summary"; - -export const FutureDetails: React.FC<{ - ignitionModule: IgnitionModule>; -}> = ({ ignitionModule }) => { - const { futureId } = useParams(); - - const future = useMemo( - () => getFutureById(ignitionModule, futureId), - [ignitionModule, futureId] - ); - - if (future === undefined) { - return ( - -

Future not found

-
- ); - } - - return ( - - - - ); -}; diff --git a/packages/ui/src/pages/visualization-overview/components/action.tsx b/packages/ui/src/pages/visualization-overview/components/action.tsx deleted file mode 100644 index 848173066..000000000 --- a/packages/ui/src/pages/visualization-overview/components/action.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { - Future, - FutureType, - isFuture, -} from "@nomicfoundation/ignition-core/ui-helpers"; -import React, { useCallback } from "react"; -import { useNavigate } from "react-router-dom"; -import styled, { css } from "styled-components"; -import { argumentTypeToString } from "../../../utils/argumentTypeToString"; - -export const Action: React.FC<{ - future: Future; -}> = ({ future }) => { - const navigate = useNavigate(); - - const displayText = toDisplayText(future); - - const navigateToFuture = useCallback(() => { - return navigate(`/future/${encodeURIComponent(future.id)}`); - }, [future.id, navigate]); - - return ( - - {displayText} - - ); -}; - -function toDisplayText(future: Future): string { - switch (future.type) { - case FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT: - return `Contract deploy ${future.contractName}`; - case FutureType.CONTRACT_DEPLOYMENT: - return `Deploy contract ${future.contractName} from artifact`; - case FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT: - return `Library deploy ${future.contractName}`; - case FutureType.LIBRARY_DEPLOYMENT: - return `Library deploy ${future.contractName} from artifact`; - case FutureType.CONTRACT_CALL: - return `Call ${future.contract.contractName}/${future.functionName}`; - case FutureType.STATIC_CALL: - return `Static call ${future.contract.contractName}/${future.functionName}`; - case FutureType.NAMED_ARTIFACT_CONTRACT_AT: - return `Existing contract ${future.contractName} (${ - typeof future.address === "string" - ? future.address - : isFuture(future.address) - ? future.address.id - : argumentTypeToString(future.address) - })`; - case FutureType.CONTRACT_AT: - return `Existing contract ${future.contractName} from artifact (${ - typeof future.address === "string" - ? future.address - : isFuture(future.address) - ? future.address.id - : argumentTypeToString(future.address) - })`; - case FutureType.READ_EVENT_ARGUMENT: - return `Read event from future ${future.futureToReadFrom.id} (event ${future.eventName} argument ${future.nameOrIndex})`; - case FutureType.SEND_DATA: - return `Send data to ${ - typeof future.to === "string" - ? future.to - : isFuture(future.to) - ? future.to.id - : argumentTypeToString(future.to) - }`; - } -} - -const Text = styled.p` - margin: 0; -`; - -const ActionBtn = styled.div<{ futureType: FutureType }>` - border: 1px solid black; - padding: 1rem; - font-weight: bold; - - &:hover { - background: blue; - cursor: pointer; - } - - ${(props) => - [ - FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT, - FutureType.CONTRACT_DEPLOYMENT, - FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT, - FutureType.LIBRARY_DEPLOYMENT, - ].includes(props.futureType) && - css` - background: green; - color: white; - `} - - ${(props) => - [FutureType.CONTRACT_CALL, FutureType.STATIC_CALL].includes( - props.futureType - ) && - css` - background: yellow; - color: black; - `} -`; diff --git a/packages/ui/src/pages/visualization-overview/components/future-block.tsx b/packages/ui/src/pages/visualization-overview/components/future-block.tsx new file mode 100644 index 000000000..72f158852 --- /dev/null +++ b/packages/ui/src/pages/visualization-overview/components/future-block.tsx @@ -0,0 +1,232 @@ +import { + ArgumentType, + Future, + FutureType, + isFuture, +} from "@nomicfoundation/ignition-core/ui-helpers"; +import React from "react"; +import styled, { css } from "styled-components"; +import { argumentTypeToString } from "../../../utils/argumentTypeToString"; + +export const FutureBlock: React.FC<{ + future: Future; + toggleState: Record; + setToggled: (id: string) => void; +}> = ({ future, toggleState, setToggled }) => { + const futureId = future.id; + const toggled = toggleState[futureId]; + + const displayText = toDisplayText(future); + + const fontWeight = toggled ? "normal" : "bold"; + + const isLibrary = + future.type === FutureType.LIBRARY_DEPLOYMENT || + future.type === FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT; + + return ( + + {!isLibrary && ( + setToggled(futureId)} toggled={toggled} /> + )} + {displayText} + [{future.module.id}] + {toggled && ( + + )} + + ); +}; + +function toDisplayText(future: Future): string { + switch (future.type) { + case FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT: + return `Contract deploy ${future.id}`; + case FutureType.CONTRACT_DEPLOYMENT: + return `Deploy contract ${future.id} from artifact`; + case FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT: + return `Library deploy ${future.id}`; + case FutureType.LIBRARY_DEPLOYMENT: + return `Library deploy ${future.id} from artifact`; + case FutureType.CONTRACT_CALL: + return `Call ${future.id}`; + case FutureType.STATIC_CALL: + return `Static call ${future.id}`; + case FutureType.NAMED_ARTIFACT_CONTRACT_AT: + return `Existing contract ${future.id} (${ + typeof future.address === "string" + ? future.address + : isFuture(future.address) + ? future.address.id + : argumentTypeToString(future.address) + })`; + case FutureType.CONTRACT_AT: + return `Existing contract ${future.id} from artifact (${ + typeof future.address === "string" + ? future.address + : isFuture(future.address) + ? future.address.id + : argumentTypeToString(future.address) + })`; + case FutureType.READ_EVENT_ARGUMENT: + return `Read event from future ${future.futureToReadFrom.id} (event ${future.eventName} argument ${future.nameOrIndex})`; + case FutureType.SEND_DATA: + return `Send data ${future.id} to ${ + typeof future.to === "string" + ? future.to + : isFuture(future.to) + ? future.to.id + : argumentTypeToString(future.to) + }`; + } +} + +const Text = styled.div` + margin: 0; + display: inline; +`; + +const FutureBtn = styled.div<{ futureType: FutureType }>` + border: 1px solid black; + padding: 1rem; + font-weight: normal; + + ${(props) => + [ + FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT, + FutureType.CONTRACT_DEPLOYMENT, + FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT, + FutureType.LIBRARY_DEPLOYMENT, + ].includes(props.futureType) && + css` + background: green; + color: white; + `} + + ${(props) => + [FutureType.CONTRACT_CALL, FutureType.STATIC_CALL].includes( + props.futureType + ) && + css` + background: yellow; + color: black; + `} +`; + +const ToggleBtn: React.FC<{ + toggled: boolean; + setToggled: () => void; +}> = ({ toggled, setToggled }) => { + return ( + + {toggled ? "- " : "+ "} + + ); +}; + +const FutureDetailsSection: React.FC<{ + future: Future; + setToggled: (id: string) => void; +}> = ({ future, setToggled }) => { + switch (future.type) { + case FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT: + case FutureType.CONTRACT_DEPLOYMENT: + return ( +
+

Constructor Arguments

+
    + {Object.entries(future.constructorArgs).map(([, arg]) => ( + + ))} +
+
+ ); + case FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT: + case FutureType.LIBRARY_DEPLOYMENT: + return null; + case FutureType.CONTRACT_CALL: + return ( +
+

Arguments

+
    + {Object.entries(future.args).map(([, arg]) => ( + + ))} +
+
+ ); + case FutureType.STATIC_CALL: + return ( +
+

Arguments

+
    + {Object.entries(future.args).map(([, arg]) => ( + + ))} +
+
+ ); + case FutureType.NAMED_ARTIFACT_CONTRACT_AT: + case FutureType.CONTRACT_AT: + return ( +
+

Contract - {future.contractName}

+

+ Address -{" "} + {typeof future.address === "string" ? ( + future.address + ) : ( + + )} +

+
+ ); + case FutureType.READ_EVENT_ARGUMENT: + return ( +
+

Emitter - {future.emitter.id}

+

Event - {future.eventName}

+

Event index - {future.eventIndex}

+

Argument - {future.nameOrIndex}

+
+ ); + case FutureType.SEND_DATA: + return ( +
+

+ To -{" "} + {typeof future.to === "string" ? ( + future.to + ) : ( + + )} +

+

Data - {future.data}

+
+ ); + } +}; + +const Argument: React.FC<{ + setToggled: (id: string) => void; + arg: ArgumentType; +}> = ({ setToggled, arg }) => { + if (isFuture(arg)) { + return ( +
  • setToggled(arg.id)} + > + {argumentTypeToString(arg)} +
  • + ); + } + return
  • {argumentTypeToString(arg)}
  • ; +}; diff --git a/packages/ui/src/pages/visualization-overview/components/visualization-details.tsx b/packages/ui/src/pages/visualization-overview/components/visualization-details.tsx index f3e6213dd..299f24f0c 100644 --- a/packages/ui/src/pages/visualization-overview/components/visualization-details.tsx +++ b/packages/ui/src/pages/visualization-overview/components/visualization-details.tsx @@ -1,12 +1,13 @@ import { + FutureType, IgnitionModule, IgnitionModuleResult, } from "@nomicfoundation/ignition-core/ui-helpers"; -import { useMemo } from "react"; +import { useMemo, useState } from "react"; import styled from "styled-components"; import { Mermaid } from "../../../components/mermaid"; import { getAllFuturesForModule } from "../../../queries/futures"; -import { Action } from "./action"; +import { FutureBlock } from "./future-block"; export const VisualizationDetails: React.FC<{ ignitionModule: IgnitionModule>; @@ -16,6 +17,23 @@ export const VisualizationDetails: React.FC<{ [ignitionModule] ); + const toggleMap = Object.fromEntries( + futures + .filter( + ({ type }) => + type !== FutureType.LIBRARY_DEPLOYMENT && + type !== FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT + ) + .map(({ id }) => [id, false]) + ); + + const [toggleState, setToggledInternal] = useState(toggleMap); + + const setToggled = (id: string) => { + const newState = { ...toggleState, [id]: !toggleState[id] }; + setToggledInternal(newState); + }; + return (

    Visualization

    @@ -24,10 +42,15 @@ export const VisualizationDetails: React.FC<{
    -

    Actions

    +

    Futures

    {futures.map((future) => ( - + ))}
    diff --git a/packages/ui/src/pages/visualization-overview/components/visualization-summary.tsx b/packages/ui/src/pages/visualization-overview/components/visualization-summary.tsx index 6f16006f9..7b9847d5d 100644 --- a/packages/ui/src/pages/visualization-overview/components/visualization-summary.tsx +++ b/packages/ui/src/pages/visualization-overview/components/visualization-summary.tsx @@ -27,9 +27,8 @@ export const VisualizationSummary: React.FC<{

    - The successful completion of the deployment will send{" "} - {deployFutures.length + callFutures.length} - transactions: + The successful completion of the deployment will apply{" "} + {deployFutures.length + callFutures.length} updates on-chain:

    @@ -39,7 +38,7 @@ export const VisualizationSummary: React.FC<{ @@ -51,7 +50,9 @@ export const VisualizationSummary: React.FC<{

    {callFutures.length} calls

    @@ -63,15 +64,11 @@ export const VisualizationSummary: React.FC<{ const SummaryColumns = styled.div` display: grid; - grid-template-columns: 1fr 1fr 1fr; + grid-template-columns: 1fr 1fr; `; const SummaryColumn = styled.div` h4 { text-decoration: underline; } - - ul { - list-style-type: none; - } `; diff --git a/packages/ui/src/pages/visualization-overview/visualization-overview.tsx b/packages/ui/src/pages/visualization-overview/visualization-overview.tsx index 0f2116ced..ab940156c 100644 --- a/packages/ui/src/pages/visualization-overview/visualization-overview.tsx +++ b/packages/ui/src/pages/visualization-overview/visualization-overview.tsx @@ -13,7 +13,7 @@ export const VisualizationOverview: React.FC<{ return (
    - Ignition - {ignitionModule.id} + Hardhat Ignition - {ignitionModule.id}
    diff --git a/packages/ui/src/queries/futures.ts b/packages/ui/src/queries/futures.ts index 897ed0dfe..c1b831662 100644 --- a/packages/ui/src/queries/futures.ts +++ b/packages/ui/src/queries/futures.ts @@ -32,11 +32,13 @@ export function getAllFuturesForModule({ futures, submodules, }: IgnitionModule>): Future[] { - return Array.from(futures).concat( - Array.from(submodules.values()).flatMap((submodule) => - getAllFuturesForModule(submodule) + return Array.from(futures) + .concat( + Array.from(submodules.values()).flatMap((submodule) => + getAllFuturesForModule(submodule) + ) ) - ); + .filter((v, i, a) => a.indexOf(v) === i); // remove duplicates } /** diff --git a/packages/ui/src/utils/to-mermaid.ts b/packages/ui/src/utils/to-mermaid.ts index a9695da87..b0cc7436f 100644 --- a/packages/ui/src/utils/to-mermaid.ts +++ b/packages/ui/src/utils/to-mermaid.ts @@ -43,7 +43,7 @@ export function toMermaid( ), ].join("\n"); - return `flowchart BT\n\n${toEscapedId( + return `flowchart TB\n\n${toEscapedId( ignitionModule.id )}:::startModule\n\n${subgraphSections}${ futureDependencies === "" ? "" : "\n\n" + futureDependencies @@ -70,7 +70,7 @@ function prettyPrintModule( .map((f) => `${lineIndent}${toEscapedId(f.id)}["${toLabel(f)}"]`) .join(`\n${lineIndent}`); - return `${lineIndent}subgraph ${module.id}\n${lineIndent} direction BT\n\n${lineIndent}${futureList}\n${lineIndent}end`; + return `${lineIndent}subgraph ${module.id}\n${lineIndent} direction TB\n\n${lineIndent}${futureList}\n${lineIndent}end`; } function toLabel(f: Future): string { @@ -84,9 +84,9 @@ function toLabel(f: Future): string { case FutureType.LIBRARY_DEPLOYMENT: return `Deploy library from artifact ${f.contractName}`; case FutureType.CONTRACT_CALL: - return `Call ${f.contract.contractName}/${f.functionName}`; + return `Call ${f.contract.contractName}.${f.functionName}`; case FutureType.STATIC_CALL: - return `Static call ${f.contract.contractName}/${f.functionName}`; + return `Static call ${f.contract.contractName}.${f.functionName}`; case FutureType.NAMED_ARTIFACT_CONTRACT_AT: return `Existing contract ${f.contractName} (${ typeof f.address === "string" diff --git a/packages/ui/test/to-mermaid.ts b/packages/ui/test/to-mermaid.ts index 6695dd4fa..3a51ffa81 100644 --- a/packages/ui/test/to-mermaid.ts +++ b/packages/ui/test/to-mermaid.ts @@ -16,12 +16,12 @@ describe("to-mermaid", () => { }); const expectedResult = testFormat` - flowchart BT + flowchart TB Module:::startModule subgraph Module - direction BT + direction TB Module#Contract1["Deploy Contract1"] end @@ -40,12 +40,12 @@ describe("to-mermaid", () => { }); const expectedResult = testFormat` - flowchart BT + flowchart TB Test_registrar:::startModule subgraph Test_registrar - direction BT + direction TB Test_registrar#Contract1["Deploy Contract1"] end @@ -80,22 +80,22 @@ describe("to-mermaid", () => { }); const expectedResult = testFormat` - flowchart BT + flowchart TB Module:::startModule subgraph Module - direction BT + direction TB Module#Contract3["Deploy Contract3"] end subgraph Submodule1 - direction BT + direction TB Submodule1#Contract1["Deploy Contract1"] end subgraph Submodule2 - direction BT + direction TB Submodule2#Contract2["Deploy Contract2"] end @@ -159,20 +159,20 @@ describe("to-mermaid", () => { }); const expectedResult = testFormat` - flowchart BT + flowchart TB Module:::startModule subgraph Module - direction BT + direction TB Module#BasicContract["Deploy BasicContract"] Module#BasicLibrary["Deploy library BasicLibrary"] Module#BasicLibrary2["Deploy library from artifact BasicLibrary"] Module#ContractWithLibrary["Deploy from artifact ContractWithLibrary"] - Module#BasicContract.basicFunction["Call BasicContract/basicFunction"] + Module#BasicContract.basicFunction["Call BasicContract.basicFunction"] Module#BasicContract.BasicEvent.eventArg.0["Read event from future Module#BasicContract.basicFunction (event BasicEvent argument eventArg)"] - Module#ContractWithLibrary.readonlyFunction["Static call ContractWithLibrary/readonlyFunction"] + Module#ContractWithLibrary.readonlyFunction["Static call ContractWithLibrary.readonlyFunction"] Module#BasicContract2["Existing contract BasicContract (Module#BasicContract)"] Module#ContractWithLibrary2["Existing contract from artifact ContractWithLibrary (Module#ContractWithLibrary)"] Module#test_send["Send data to Module#BasicContract2"] @@ -203,16 +203,16 @@ describe("to-mermaid", () => { }); const expectedResult = testFormat` - flowchart BT + flowchart TB Module:::startModule subgraph Module - direction BT + direction TB Module#ens["Deploy ens"] - Module#ens.setAddr_bytes32_address_["Call ens/setAddr(bytes32,address)"] - Module#ens.getAddr_bytes32_address_["Static call ens/getAddr(bytes32,address)"] + Module#ens.setAddr_bytes32_address_["Call ens.setAddr(bytes32,address)"] + Module#ens.getAddr_bytes32_address_["Static call ens.getAddr(bytes32,address)"] end Module#ens.setAddr_bytes32_address_ --> Module#ens