Skip to content

The Membrane Dashboard

The dashboard is a customizable interface for viewing data and executing repetitive workflows. With the dashboard, you can quickly build utilitarian UIs on top of your Membrane programs.

In the video above, we add blocks to the dashboard representing a GitHub user, repo, and issue. Those particular views are defined in membrane/github, but you can create and compose your own views to solve your needs.

We’ll get to creating views, but let’s start with the basics of using the dashboard.

Using the dashboard

Opening

To open the dashboard, click DASHBOARD in the top left of your editor.

Open Dashboard button

Installing

If you haven’t already, install the membrane/dashboard package. This program will track the blocks you add to the dashboard and their position. Now you’re ready to add stuff!

Adding blocks

To add a block to your dashboard, simply drag ‘n drop a gref onto the dashboard.

If the gref’s node type does not yet have a custom view, select “CREATE CUSTOM VIEW” to make one. Or explore the node’s fields, actions, and events by clicking “SHOW EXPLORER.”

No custom view for block

We cover creating and generating custom views below, but first let’s discuss organizing and navigating around the dashboard.

Moving around

To use the dashboard fluidly, run through this checklist:

  • Move a block by dragging and dropping. The dashboard grid is intentionally coarse. Blocks are sized and positioned in 128px increments.
  • Resize a block by dragging from its bottom right corner.
  • Pan by scrolling with your mouse or trackpad. Press shift to scroll horizontally. Alternatively, middle click (scroll wheel) with your mouse and drag the dashboard background to pan.
  • Fullscreen. Toggle by clicking the fullscreen icon button in the top right corner of the dashboard.
  • Picker mode. Press space or click the dashboard background to zoom out, then click a block to focus it or press space/click again to zoom in on your mouse position. You can also hold ctrl|command and scroll to activate picker mode.
  • Stacked mode. Selecting a gref embedded in another view will activate a breadcrumb-like horizontally stacked view, allowing exploration of nested data. Drag a gref from a stack column to persist as its own block. Click outside of the columns or press escape to exit stacked mode. Hold shift to see all elements with an explorable gref, shift+click to open stacked mode, and shift+rightclick for more options (copy gref, copy value, etc).
  • Explore mode. Click “EXPLORE” in the top left corner of the dashboard, or right-click on the dashboard background and select “Explore Graph” to explore your program graph. Explore mode works like stack mode, allowing you to view nested nodes and peel/drag one off to place it on your board.
  • Inspect elements by holding cmd+shift and hovering to see the corresponding code in views.tsx. Click the element while holding cmd+shift to move your cursor to the relevant code in views.tsx.

Here’s a demo of each movement described above:

Managing boards

Boards are dashboard pages for organizing your blocks. Just as spreadsheets have sheets, the dashboard has boards. You might have a board for customer support and another for ad hoc Stripe actions, for example.

When the dashboard is open, you’ll see the name of the current board in the top middle of the dashboard. Click on it to view, switch, and create new boards:

Boards and blocks are persisted in the dashboard program’s state. See membrane/dashboard‘s readme to learn more about how boards and blocks are implemented.

Creating views

In this section, we’ll explain how to create dashboard views by hand.

Custom views correspond to node types in a program. So if your program has a User type, you could create a custom User view that displays select fields (like name and email) and exposes an action (e.g. disable). Whenever you drop a gref of type User onto the dashboard, it will use the User view you created for that block.

views.tsx

First, create a views.tsx file in any Membrane program (views.jsx works, too). To create a view for a type, export a function (or arrow function——dealer’s choice) by the same name from views.tsx. E.g. for a User type, we export a User view:

export function User({ self, compact }) {
if (compact) {
return <row>{self.email}</row>
}
return (
<col>
<row>
<text style={{ fontSize: "large" }}>{self.name}</text>
</row>
<row>
<text>{self.email}</text>
</row>
<row>
<button action={self.disable}>Disable account</button>
</row>
</col>
)
}

View functions receive an object parameter with a self property, which is a reference to the node. So this User view would have access to all fields, actions, and events on the User type. Views also receive a compact prop, which defaults to true when rendering collections and can be passed manually to embeds.

The dashboard uses a Membrane-specific flavor of JSX. For full coverage of valid elements and styles, read our JSX reference.

Generating views

While you can always write views by hand, it’s usually more practical to generate a view in a matter of seconds. Just ask Brane to generate a view for a particular type, or for many types in a program.

Once Brane spits out your view(s), use the generated code as a starting point or ask Brane to iterate. Or rely on inline editor completions as a middle ground between crafting by hand and full generation.

How the dashboard works

As you may have noticed, dashboard is itself a Membrane program, membrane/dashboard, that works in tandem with system code.

The program has actions to put, move, remove, and rename blocks. It uses state to store blocks you’ve added with some data and metadata for each block. It also stores boards in program state. You can read through the program readme to learn more.

The canvas-like dashboard UI is implemented using JSX and Rust compiled to WASM. If you inspect the page via browser devtools, you’ll see an HTML <canvas> wherein we run the compiled Rust code. We use a frontend Rust framework called egui along with a flexbox layout crate taffy. The full cycle is JSX to JSON to Rust to WASM.

The code you write or generate in views.tsx uses custom Membrane JSX. See our reference page to see which elements and props are available.