Skip to content

H-6327: Integrate Sentry feedback button into ViewportControls#8537

Open
kube wants to merge 14 commits intomainfrom
cf/petrinaut-sentry-integrated-button-in-ui
Open

H-6327: Integrate Sentry feedback button into ViewportControls#8537
kube wants to merge 14 commits intomainfrom
cf/petrinaut-sentry-integrated-button-in-ui

Conversation

@kube
Copy link
Collaborator

@kube kube commented Mar 12, 2026

🌟 What is the purpose of this PR?

The Sentry "Give feedback" button was floating on top of the UI and hiding elements underneath it. This PR moves it into the ViewportControls panel by introducing a viewportActions prop on the Petrinaut component, allowing consumers to inject custom action buttons.

🔗 Related links

🔍 What does this change?

  • Adds a ViewportAction type (key, icon, label, tooltip, onClick, style, className, ref) exported from @hashintel/petrinaut
  • Adds an optional viewportActions?: ViewportAction[] prop to PetrinautProps, threaded through to ViewportControls
  • ViewportControls renders each action as an IconButton after the built-in buttons
  • Sets autoInject: false on Sentry's feedbackIntegration to remove the floating button
  • Adds a useSentryFeedbackAction() hook in the website that returns a ViewportAction using Sentry's getFeedback().attachTo() API with a React 19 ref cleanup pattern
  • Purple-styled button with MdBugReport icon

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

❓ How to test this?

  1. Checkout the branch
  2. Run yarn dev in apps/petrinaut-website
  3. Confirm the floating Sentry feedback button is gone
  4. Confirm a purple feedback button appears at the bottom of the viewport controls (bottom-right)
  5. Click it and confirm the Sentry feedback dialog opens

kube and others added 14 commits March 12, 2026 23:31
Move the demo-site from libs/@hashintel/petrinaut into its own
private package at apps/petrinaut-website, consuming petrinaut
as a workspace dependency instead of importing source directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… for website

- Bundle Monaco Editor into petrinaut (removed from externals), using selective
  imports (editor.api.js + typescript.contribution.js) to avoid bundling
  unnecessary language workers
- Add define for process.versions in petrinaut vite config for TypeScript internals
- Fix Monaco provider to use new Worker() directly instead of returning a promise
- Update Monaco type imports to use editor.api.js path across all sync files
- Remove stale demo-site references from petrinaut eslint config
- Add eslint.config.js for @apps/petrinaut-website
- Fix import/export sorting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Vite library mode emits worker assets as separate files that consumers
can't resolve. Using ?worker&inline inlines the compiled worker code as
a string and creates a Blob URL at runtime, making workers self-contained
in the library bundle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The canvas npm package is a Node.js native addon that crashes during SSR
in Next.js. Since refractive is a client-side component library, use the
browser-native equivalents instead:
- createImageData(w, h) → new ImageData(w, h)
- createCanvas(w, h) → document.createElement("canvas")
- Remove type-only ImageData imports (it's a browser global)
- Remove canvas from dependencies and vite externals

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…config

- Add message queue in useLanguageClient so messages sent before async
  worker init are drained once the worker is ready
- Add terminated flag to both worker hooks to prevent leaking workers
  if the component unmounts before the dynamic import resolves
- Reject pending init promise on teardown in useSimulationWorker
- Switch worker.onmessage/onerror to addEventListener for eslint compliance
- Extract createSimulationWorker into its own module for clean test mocking
- Update test suite to use async mocks via vi.mock instead of vi.stubGlobal
- Set sideEffects: ["*.css"] instead of false to prevent CSS tree-shaking
- Remove stale build:site task from turbo.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a `viewportActions` prop to Petrinaut that allows consumers to inject
custom action buttons into the viewport controls panel. Use this to move
the Sentry feedback trigger from a floating overlay into the controls,
with a purple button style and bug report icon.

- Add `ViewportAction` type with key, icon, label, tooltip, onClick,
  style, className, and ref fields
- Thread `viewportActions` through Petrinaut → EditorView → SDCPNView →
  ViewportControls
- Set `autoInject: false` on Sentry feedbackIntegration
- Use React 19 ref cleanup to attach/detach Sentry feedback listener

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Mar 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hash Ready Ready Preview, Comment Mar 13, 2026 0:03am
petrinaut Error Error Mar 13, 2026 0:03am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
hashdotdesign Ignored Ignored Preview Mar 13, 2026 0:03am
hashdotdesign-tokens Ignored Ignored Preview Mar 13, 2026 0:03am

@github-actions github-actions bot added area/deps Relates to third-party dependencies (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team area/apps labels Mar 12, 2026
@kube kube marked this pull request as ready for review March 12, 2026 23:49
@cursor
Copy link

cursor bot commented Mar 12, 2026

PR Summary

Medium Risk
Introduces a new viewportActions extension point that changes the public Petrinaut API and affects core editor rendering; misuse (refs/callbacks) could impact viewport controls behavior, but changes are additive and UI-scoped.

Overview
Adds an extension point for custom buttons in the editor viewport controls by introducing a new ViewportAction type and a viewportActions prop that is threaded through PetrinautEditorViewSDCPNViewViewportControls and rendered after the built-in controls.

Updates petrinaut-website to use this hook-based action to attach Sentry’s feedback widget to a new “Give feedback” viewport button (using react-icons), and disables Sentry feedback’s default auto-injected trigger via autoInject: false.

Written by Cursor Bugbot for commit 70d198a. This will update automatically on new commits. Configure here.

@augmentcode
Copy link

augmentcode bot commented Mar 12, 2026

🤖 Augment PR Summary

Summary: This PR adds an extension point for extra viewport control buttons and uses it to expose a Sentry “Give feedback” button in Petrinaut.

Changes:

  • Introduces a shared ViewportAction type and a new viewportActions prop on Petrinaut, threading it through EditorView and SDCPNView into ViewportControls.
  • Updates ViewportControls to render the provided actions as additional IconButtons after the built-in controls.
  • Adds a Petrinaut-website hook that attaches Sentry Feedback to a viewport control button (using a bug-report icon).
  • Adjusts Sentry Feedback integration config to disable auto-injection so the UI button is only rendered via the new viewport action.

🤖 Was this summary useful? React with 👍 or 👎

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 2 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

const icon = <MdBugReport size={14} />;

export function useSentryFeedbackAction(): ViewportAction {
return {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useSentryFeedbackAction() returns a new ViewportAction object (and callback ref) on every render, which can cause React to detach/reattach the ref and repeatedly run feedback.attachTo. That can lead to duplicate handlers or a subtle flicker if the host component re-renders frequently.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

setTitle={setTitle}
title={currentNet.title}
undoRedo={undoRedo}
viewportActions={[sentryFeedbackAction]}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

viewportActions={[sentryFeedbackAction]} creates a new array each render, so downstream components will always see this prop change. If the action/ref isn’t stable, this can amplify unnecessary ref detach/attach work for the Sentry feedback button.

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

};
},
};
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unstable ref callback causes repeated Sentry attach/detach cycles

Medium Severity

useSentryFeedbackAction returns a new object (with a new ref callback) on every render without any memoization. Since DevApp re-renders on every net edit or state change, React 19 will invoke the old ref's cleanup (calling unsubscribe) and then call the new ref (calling attachTo again) on each render. This causes the Sentry feedback integration to be repeatedly detached and re-attached, which could cause brief unresponsiveness of the feedback button and unnecessary overhead. The return value — or at minimum the ref callback — needs to be memoized (e.g. via useMemo/useCallback).

Additional Locations (1)
Fix in Cursor Fix in Web

@kube kube changed the title Integrate Sentry feedback button into ViewportControls H-6327: Integrate Sentry feedback button into ViewportControls Mar 12, 2026
@graphite-app graphite-app bot requested a review from a team March 13, 2026 00:08
Base automatically changed from cf/petrinaut-extract-website to main March 13, 2026 17:50
@kube kube requested a review from a team as a code owner March 13, 2026 17:50
@graphite-app graphite-app bot requested a review from a team March 13, 2026 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/apps area/deps Relates to third-party dependencies (area) area/libs Relates to first-party libraries/crates/packages (area) type/eng > frontend Owned by the @frontend team

Development

Successfully merging this pull request may close these issues.

1 participant