Skip to content

Quick Tools imports graphs or cards from JSON or Excel files and builds diagrams on a Miro board. The application uses the Eclipse Layout Kernel (ELK) to arrange nodes and edges automatically. Shapes are generated from templates and each element can carry metadata that controls its appearance and placement.

License

Notifications You must be signed in to change notification settings

fenrick/MiroDiagramming

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Quick Tools

CI

Quick Tools imports graphs or cards from JSON files and builds diagrams on a Miro board. The application uses the Eclipse Layout Kernel (ELK) to arrange nodes and edges automatically. Shapes are generated from templates and each element can carry metadata that controls its appearance and placement.

Quickstart

Prerequisites

  • Node.js 20.x

The app builds to static assets served by Vite in development and by any static host in production. All board interactions happen client-side through the Miro Web SDK.

Environment

Create a .env file at the repository root if you need to override defaults. All variables must use the VITE_ prefix so Vite exposes them to the client. Common options:

VITE_PORT=3000
VITE_LOGFIRE_SERVICE_NAME=miro-frontend
VITE_LOGFIRE_SEND_TO_LOGFIRE=false

Development

Run the Vite dev server:

npm install
npm run dev

Production build and local preview:

npm run build
npm run preview

Uploading JSON Content

  1. Click the app icon on your Miro board.
  2. In the Create tab choose whether to import a diagram or cards.
  3. Select a .json file. Diagrams require nodes and edges while the cards option expects an object with a cards array.
  4. Once processed, widgets are placed on the board using the selected mode. Cards are automatically arranged in a grid with a calculated number of columns. Pass columns when invoking the importer to override this value.
  5. An example card structure is shown below.

Card JSON Format

Each card entry must specify a title. All other properties are optional:

  • description: Markdown or plain text body
  • tags: array of tag names to assign. These are mapped to the widget's tagIds field when cards are created or updated
  • style: card appearance (theme and background)
  • fields: custom preview fields shown on the card
  • taskStatus: Kanban status such as to-do

Omitting the fields property leaves the card without preview items.

ELK Layout

The layout step leverages the ELK algorithm to compute positions for all nodes. You can provide layout hints in each node's metadata to influence spacing or layering. The engine runs automatically when a graph is uploaded. For an overview of available layout algorithms see docs/LAYOUT_OPTIONS.md. The ELK engine is dynamically imported from the jsDelivr CDN so it is excluded from the application bundle.

Template‑Based Shapes

Shape templates live in templates/shapeTemplates.json. Each template defines the shape type, size and base styles. These templates also act as style presets, exposing the buttons on the Style tab. When a node specifies a template value in its metadata the corresponding template is applied. Edit this file or add new entries to customise the available shapes. Connector appearance is configured in templates/connectorTemplates.json which controls line colour, caps and font. The templates now include Decision and StartEnd shapes useful for flowcharts. To add your own templates create new entries in these JSON files and reference them by name in your graph metadata. The app reloads templates on startup so changes are picked up automatically. Additional details and a sample dataset are provided in docs/TEMPLATES.md.

When Use existing widgets is enabled the importer caches all basic shapes on the board and matches them by their text content. The cache prevents duplicates during placement and is cleared once processing finishes.

Identification

Widgets no longer rely on metadata. Shapes and groups are matched purely by their text content. When updating a diagram the importer searches for a shape whose content matches the node label. Cards continue to encode their identifier in the description using the ID: prefix.

Sample Graph

{
    "nodes": [
        { "id": "n1", "label": "Customer", "type": "Role" },
        { "id": "n2", "label": "Service", "type": "BusinessService" }
    ],
    "edges": [{ "from": "n1", "to": "n2", "label": "uses" }]
}

Nested Layouts

Hierarchical data where children are contained within parent shapes can be visualised using the Nested layout option in the Diagram tab. Positions and container sizes are computed entirely by the ELK engine for consistent spacing. Nodes are sorted alphabetically by default or via a custom metadata key.

Accessibility

The import panel is keyboard accessible. The drop area includes an ARIA label and hidden instructions so screen readers announce how to operate it. Focus the area with the Tab key and press Enter to open the file picker. The mode selection radios are grouped with a descriptive label.

Additional Tools

The sidebar exposes extra tabs to manipulate existing widgets:

  • Resize allows copying a widget size and applying it to others. You can also type width and height manually. When a size is copied the same button becomes a Reset Copy action so you can quickly revert. The tool displays conversions between board units, millimetres and inches based on the ratio 96 units = 1 inch.
  • Style sets common style properties like fill colour or border width on all selected items. The tab shows the current fill colour swatch and updates when the selection changes. A slider lightens or darkens the colour while keeping the text readable.
  • Grid arranges widgets into a grid with options for sorting and grouping the result.
  • Frames renames or locks selected frames via helper utilities.
  • Search finds text across the board and can replace all matches.

Testing & Coverage

  • Unit tests use Vitest.
  • Run tests: npm run test
  • Coverage report (HTML + lcov): npm run coverage then open coverage/index.html.
  • Client tests that touch the DOM use jsdom; add // @vitest-environment jsdom at the top of those files.
  • Focus initial coverage on utilities and hooks that don’t require the live Miro SDK (e.g., color/ratio helpers, template resolution, notifications, logger, UI utils).

Search Tools

Utility helpers searchBoardContent and replaceBoardContent can query or update widgets by text. They support filtering by widget type, tag ID, fill colour, assignee, creator and last modifier. Searches may be case sensitive, whole-word or regular expression based and can be limited to the current selection. The search tab exposes checkboxes for these modes alongside Next to jump through results and Replace for single substitutions. During replacements the board viewport focuses on each matched item so you can review changes. See the Search tab walkthrough for the complete UI flow.

Setup

πŸ› οΈ Tools and Technologies

Styling with the Miro Design System

The CSS for this project imports @mirohq/design-system-themes/light.css in src/assets/style.css to match the Miro UI. Components are sourced from @mirohq/design-system. Avoid custom CSS when a component or token already exists. Wrapper components in src/ui/components abstract the design-system primitives so upgrades happen in one place.

Form Design Guidelines

When creating forms use the wrapper components so your inputs and buttons match the rest of the UI. These guidelines help keep layouts consistent:

  • Use InputField to pair labels with their controls. Provide the input component via the as prop and pass component props through options.
  • Button and InputField wrap the design-system components so events and sizing tokens behave consistently.
  • Group related fields using FormGroup to maintain spacing and a clear vertical rhythm.
  • Arrange elements with the 12‑column grid classes (cs*/ce*) so forms remain responsive.
  • Use values from @mirohq/design-tokens for margins and padding instead of hard‑coded numbers.
  • Layout wrappers such as Panel or Section expose a padding prop. Pass a token from @mirohq/design-tokens so spacing stays consistent.
  • Avoid passing custom className or style props to these wrappers; spacing decisions belong inside the component.
  • Keep wrapper nesting shallow; avoid unnecessary layers.
  • When customisation is needed prefer extending design-system tokens over creating bespoke CSS classes.
  • Stick to the provided Button component and choose the primary variant for the main action. Place secondary actions on the right using the buttons wrapper as seen in the tabs.
  • Keep labels short and descriptive. When extra context is required add a Paragraph element next to the fields.
  • Use real heading tags with visible text so screen readers announce sections.
  • For drag‑and‑drop zones include an ARIA label and hidden instructions so screen readers describe the workflow.

βœ… Prerequisites

  • Node.js 20.x

πŸƒπŸ½β€β™‚οΈ Run the app locally

  1. Run npm install to install dependencies. The package-lock.json file ensures everyone installs the same versions.
  2. Run npm run dev to start the development server. Your URL should be similar to this example:
 http://localhost:3000
  1. Open the app manifest editor by clicking Edit in Manifest.
    In the app manifest editor, configure the app as follows, and then click save:
# See https://developers.miro.com/docs/app-manifest on how to use this
appName: JSON Diagram
sdkVersion: SDK_V2
sdkUri: http://localhost:3000
scopes:
    - boards:read
    - boards:write
  1. Go back to your app home page, and under the Permissions section, you will see a blue button that says Install app and get OAuth token. Click that button. Then click on Add as shown in the video below. In the video we install a different app, but the process is the same regardless of the app.

    ⚠️ We recommend to install your app on a developer team while you are developing or testing apps.⚠️ https://github.com/miroapp/app-examples/assets/10428517/1e6862de-8617-46ef-b265-97ff1cbfe8bf

  2. Go to your developer team, and open your boards.
  3. Click on the plus icon from the bottom section of your left sidebar. If you hover over it, it will say More apps.
  4. Search for your app JSON Diagram or whatever you chose to name it. Click on your app to use it, as shown in the video below. In the video we search for a different app, but the process is the same regardless of the app. https://github.com/horeaporutiu/app-examples-template/assets/10428517/b23d9c4c-e785-43f9-a72e-fa5d82c7b019

Testing

Run the test suite:

npm test

The root AGENTS.md lists the commands to run before committing. Be sure to install dependencies first:

npm install

Then validate the codebase with:

npm run typecheck --silent
npm test --silent
npm run lint --silent
npm run format --silent

The Husky hooks live under the repository's .husky/ folder. Hooks are installed automatically on npm install via the prepare script so each commit is validated. The pre-commit hook runs type checking, tests, ESLint and Prettier. Execute the Vitest suite yourself before committing. Aim for at least 90Β % line and branch coverage and keep cyclomatic complexity under eight (see docs/ARCHITECTURE.md). Sonar rules such as using readonly class fields, optional chaining, semantic HTML tags and stable React keys. Run these checks before committing so code conforms to the repository guidelines.

CI merges coverage from all test shards. The build doesn't fail based on coverage numbers, so developers must keep both codebases above 90Β % coverage

With package-lock.json checked in you can run npm audit after each install to scan dependencies for vulnerabilities. Include the lock file in commits so everyone uses the exact dependency versions when installing.

Logging

All runtime messages are emitted through a shared logger defined in src/logger.ts. Set the LOG_LEVEL environment variable to trace, debug, info, warn, error or silent to control verbosity. It defaults to info.

Example:

LOG_LEVEL=debug npm run dev

Commit message checks

Commit messages must follow the Conventional Commits specification. A commit-msg hook runs commitlint automatically (installed via npm install). Verify the latest commit manually by running:

npm run commitlint -- --edit $(git rev-parse --verify HEAD)

The CI pipeline also enforces commitlint via \.github/workflows/commitlint.yml. All Node jobs run from the repository root so caching and dependency installs share the same lockfile.

πŸ—‚οΈ Folder structure

.
β”œβ”€β”€ docs/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ assets/
β”‚   β”œβ”€β”€ board/
β”‚   β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ core/
β”‚   β”œβ”€β”€ stories/
β”‚   β”œβ”€β”€ ui/
β”‚   └── web/
└── templates/

πŸ“š Additional Design Docs

Storybook

Run the component explorer to preview the UI library. Storybook exposes interactive examples for each component and includes a toolbar toggle for the design-system light and dark themes. Add stories for any new UI element so reviewers can verify visuals.

npm run storybook

Generate a static Storybook site for publishing with:

npm run build-storybook

Local CI Build

Run the helper script to reproduce the GitHub Actions pipeline locally. It executes lint checks, type verification, unit tests, and the production build in sequence (Storybook build optional). Semantic release is intentionally skipped.

Pull requests trigger the unified ci.yml workflow to run linting, type checks, unit tests and the production build for the React client. Pushes to main additionally invoke repo-sonar.yml, repo-codeql.yml and repo-release.yml for coverage, static analysis and release tasks.

npm run ci:local

Changelog

Release notes are generated by semantic-release and appended to CHANGELOG.md in the repository root. Manual updates are no longer required.

πŸ«±πŸ»β€πŸ«²πŸ½ Contributing

Please read CONTRIBUTING.md for contribution guidelines and the development workflow.

πŸͺͺ License

This software is released into the public domain under The Unlicense. See the LICENSE file for details.

About

Quick Tools imports graphs or cards from JSON or Excel files and builds diagrams on a Miro board. The application uses the Eclipse Layout Kernel (ELK) to arrange nodes and edges automatically. Shapes are generated from templates and each element can carry metadata that controls its appearance and placement.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors 6