Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/real-things-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@hashintel/petrinaut": patch
---

Adds an optional product walkthrough that consumers can set
Binary file removed apps/petrinaut-website/favicon.png
Binary file not shown.
5 changes: 4 additions & 1 deletion apps/petrinaut-website/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/png" href="/favicon.png" />
<link rel="icon" href="/favicon.ico" sizes="32x32" />
<link rel="icon" type="image/png" sizes="192x192" href="/icon-192.png" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" />
<title>Petrinaut | SDCPN Demo</title>
<style>
@layer reset {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/petrinaut-website/public/favicon.ico
Binary file not shown.
Binary file added apps/petrinaut-website/public/icon-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/petrinaut-website/public/icon-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions apps/petrinaut-website/public/site.webmanifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "Petrinaut",
"short_name": "Petrinaut",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}
28 changes: 16 additions & 12 deletions apps/petrinaut-website/src/main/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Petrinaut,
type PetrinautAiChatTransport,
type PetrinautAiMessage,
WalkthroughProvider,
} from "@hashintel/petrinaut/ui";

import { useSentryFeedbackAction } from "./app/sentry-feedback-button";
Expand All @@ -15,6 +16,7 @@ import {
type SDCPNInLocalStorage,
useLocalStorageSDCPNs,
} from "./app/use-local-storage-sdcpns";
import { walkthroughSteps } from "./app/walkthrough/walkthrough-steps";

import type {
MinimalNetMetadata,
Expand Down Expand Up @@ -279,18 +281,20 @@ export const DevApp = () => {

return (
<div style={{ height: "100vh", width: "100vw" }}>
<Petrinaut
aiAssistant={aiAssistant}
handle={activeHandle.handle}
existingNets={existingNets}
createNewNet={createNewNet}
hideNetManagementControls={false}
loadPetriNet={loadPetriNet}
readonly={false}
setTitle={setTitle}
title={currentNet.title}
viewportActions={[sentryFeedbackAction]}
/>
<WalkthroughProvider steps={walkthroughSteps}>
<Petrinaut
aiAssistant={aiAssistant}
handle={activeHandle.handle}
existingNets={existingNets}
createNewNet={createNewNet}
hideNetManagementControls={false}
loadPetriNet={loadPetriNet}
readonly={false}
setTitle={setTitle}
title={currentNet.title}
viewportActions={[sentryFeedbackAction]}
/>
</WalkthroughProvider>
</div>
);
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { css } from "@hashintel/ds-helpers/css";

import logo from "./logo-mark.png";
// Videos must fill their 16:9 frame edge-to-edge. Avoid card-inside-the-card
// framing (i.e. don't include a nested chrome window around the actual UI) —
// the dialog already provides its own container.
import introVideo from "./videos/01-intro-example.mp4";
import experimentsVideo from "./videos/02-experiments-example.mp4";
import aiVideo from "./videos/03-ai-example.mp4";

import type { WalkthroughStep } from "@hashintel/petrinaut/ui";

export const walkthroughSteps: WalkthroughStep[] = [
{
id: "welcome",
title: (
<div
className={css({ display: "flex", alignItems: "center", gap: "1.5" })}
>
<img
className={css({
width: "[25px]",
height: "auto",
position: "relative",
top: "[-1.5px]",
})}
src={logo}
alt=""
/>
Welcome to Petrinaut
</div>
),
body: (
<>
<p>
<strong>Petrinaut</strong> is a workshop for building, simulating, and
analyzing Petri nets: a mathematical formalism for modelling
distributed systems.
</p>
<p>
People use it to analyze supply chains, workflows, chemical reactions,
epidemics, network protocols — anywhere multiple things happen at once
and influence each other.
</p>
</>
),
videoHref: introVideo,
videoAlt: "The Petrinaut editor with an example net on the canvas",
},
{
id: "simulate",
title: "Simulate, experiment, and query your model",
body: (
<>
<p>
With your system modelled as a Petri net, you can explore and optimise
outcomes across different scenarios — for example, the failure rate of
a manufacturing line, or the throughput of a queueing system.
</p>
<p>
<strong>Petrinaut</strong> lets you run experiments on complex
probabilistic processes and build custom metrics to inspect the
results.
</p>
</>
),
videoHref: experimentsVideo,
videoAlt: "Simulation view showing experiment results and a chart",
},
{
id: "build",
title: "Build your first model",
body: (
<>
<p>
To build your first model, use the drag-and-drop canvas or ask the AI
assistant to build one for you.
</p>
<p>
Describe what you want to simulate and the assistant edits your net
directly — adding places and transitions, writing custom firing rules,
and fixing errors as you iterate.
</p>
</>
),
videoHref: aiVideo,
videoAlt:
"Canvas alongside the AI assistant panel mid-conversation editing the net",
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export { WalkthroughContext } from "./walkthrough-context";
export type {
WalkthroughContextValue,
WalkthroughStep,
} from "./walkthrough-context";
export { WalkthroughProvider } from "./walkthrough-provider";
export { WalkthroughDialog } from "./walkthrough-dialog";
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createContext } from "react";

export type WalkthroughStep = {
id: string;
title: React.ReactNode;
body: React.ReactNode;
videoHref: string;
videoAlt: string;
};

export type WalkthroughContextValue = {
isOpen: boolean;
open: () => void;
close: () => void;
steps: WalkthroughStep[];
};

export const WalkthroughContext = createContext<WalkthroughContextValue | null>(
null,
);
Loading
Loading