Skip to content

Conversation

@knollengewaechs
Copy link
Contributor

@knollengewaechs knollengewaechs commented Nov 21, 2025

URL of deployed dev instance (used for testing):

Steps to test:

  • From anywhere, open the command palette by pressing ctrl + P
  • click on "> View dataset..." and select any dataset -> you should be directed to its view mode
  • same for "> View annotaion..."
    • the list of annotations should be sorted like in the dashboard, so the annotation that was edited most recently should appear first
  • Do so in any admin view and within DS/annotation view mode
  • when having an annotation open, you should be able to select the annotation tools and also see the corresponding shortcuts

Notes

TODOs:

  • check whether closing can be done without changing the key, e.g. with pending promises in viewDatasetEntry -> didnt find anything better
  • fix typing errors
  • fix pipeline
  • [ wont do ] when hitting "view dataset" (or annotation), reset input -> does not seem feasable because input is not easy to be manipulated from outside the libs code (from what i can tell)
  • omit dangerouslySetInnerHTML

Issues:


(Please delete unneeded items, merge only when none are left open)

  • Added changelog entry (create a $PR_NUMBER.md file in unreleased_changes or use ./tools/create-changelog-entry.py)
  • Added migration guide entry if applicable (edit the same file as for the changelog)
  • Updated documentation if applicable
  • Adapted wk-libs python client if relevant API parts change
  • Removed dev-only changes like prints and application.conf edits
  • Considered common edge cases
  • Needs datastore update after deployment

@knollengewaechs knollengewaechs self-assigned this Nov 21, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 21, 2025

📝 Walkthrough

Walkthrough

Adds an exported helper getViewDatasetURL and replaces manual dataset view URL construction across multiple frontend modules; substantially extends the viewer command palette with dynamic dataset/annotation entries, shortcuts, sanitization (DOMPurify), view-mode/layout commands, and UI tweaks.

Changes

Cohort / File(s) Summary
Dataset URL Accessor
frontend/javascripts/viewer/model/accessors/dataset_accessor.ts
Adds exported `getViewDatasetURL(dataset: APIDataset
Dashboard: actions & table
frontend/javascripts/dashboard/advanced_dataset/dataset_action_view.tsx, frontend/javascripts/dashboard/advanced_dataset/dataset_table.tsx
Replace manual /datasets/${getReadableURLPart(...)}/view constructions with getViewDatasetURL(...) for Link targets and direct navigation.
Admin dataset flows
frontend/javascripts/admin/dataset/composition_wizard/04_configure_new_dataset.tsx, frontend/javascripts/admin/dataset/dataset_add_view.tsx
Use getViewDatasetURL({ name, id }) instead of manual readable-part URL construction for “View Dataset” links and navigation.
Admin job list
frontend/javascripts/admin/job/job_list_view.tsx
Switched dataset view link generation from getReadableURLPart to getViewDatasetURL.
Viewer: dataset info tab
frontend/javascripts/viewer/view/right-border-tabs/dataset_info_tab_view.tsx
Replaced static dataset view route string with getViewDatasetURL(this.props.dataset) for the view link.
Viewer: Command Palette
frontend/javascripts/viewer/view/components/command_palette.tsx
Major additions: dynamic dataset/annotation submenus and async loaders, toast feedback for empty lists, mutable command list and paletteKey re-renders, sanitized HTML rendering via DOMPurify preserving bold tags, shortcut/highlight on commands, view-mode and layout reset entries, tool shortcut mappings, and layoutEmitter integration.
Styles
frontend/stylesheets/command_palette.less
Adds vertical scrolling and thinner scrollbar for the command palette suggestions container.
Dependencies
package.json
Adds dompurify dependency (^3.3.0) to dependencies/devDependencies.
Unreleased notes
unreleased_changes/9087.md
Documents that datasets and annotations can be opened from the command palette.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas needing extra attention:
    • frontend/javascripts/viewer/view/components/command_palette.tsx — dynamic command lifecycle, async loaders, state reset, and toast/error handling.
    • Use of sanitized HTML with DOMPurify and fallback rendering — verify allowed tags (bold) and absence of XSS risks.
    • getViewDatasetURL signature vs. existing call sites — ensure all shapes (APIDataset, APIDatasetCompact, {name,id}) behave consistently.
    • Navigation consistency where both Link components and direct window.location.href are used.

Possibly related issues

Suggested labels

enhancement, frontend, usability

Suggested reviewers

  • philippotto
  • MichaelBuessemeyer

Poem

🐇 I hopped through lines and threaded every view,

Links now point true paths, the palette learned to cue.
Shortcuts hum like carrots, HTML scrubbed and bright,
Datasets open swiftly — a rabbit's small delight.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding the ability to view annotations and datasets from the command palette, which matches the primary objectives of this PR.
Description check ✅ Passed The description is directly related to the changeset, providing testing steps, deployment links, and documentation of the feature additions implemented in the PR.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch improve-command-palette

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@knollengewaechs knollengewaechs changed the title Improve command palette View Annotations and Datasets from Command Palette Nov 21, 2025
@knollengewaechs knollengewaechs marked this pull request as ready for review November 24, 2025 15:17
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (3)
frontend/javascripts/viewer/view/components/command_palette.tsx (3)

73-75: Remove leftover debug console.log statements

The console.log("Rendering Command Palette") and console.log("h") logs look like temporary debugging output and were already flagged to be removed in a previous review. They should be dropped before merging to avoid noisy consoles in production.

-  console.log("Rendering Command Palette");
...
-    console.log("h");

Also applies to: 117-119


269-285: View mode entries and tool shortcuts integration are well structured

getViewModeEntries (including “Reset layout”) and shortCutDictForTools/getToolEntries are wired cleanly:

  • View mode commands correctly dispatch setViewModeAction and emit LayoutEvents.resetLayout.
  • Tool commands include readable shortcut labels while still dispatching setToolAction.

Once the typing for shortcut is adjusted as suggested above, this section is good to go.

Also applies to: 286-297, 299-315


31-38: Fix command typing for shortcut and highlight to unblock TypeScript/CI

The new shortcut field on commands (line 310 in getToolEntries) and use of highlight in renderCommand (line 366) conflict with the Command/CommandWithoutId typings with strict TypeScript enabled:

  • Object literal with shortcut cannot be assigned to CommandWithoutId[] type.
  • Destructuring highlight and shortcut in renderCommand accesses fields not present on Command type.

Fix by extending the local CommandWithoutId type to include optional fields and casting in renderCommand:

- type CommandWithoutId = Omit<Command, "id">;
+ type CommandWithoutId = Omit<Command, "id"> & {
+   shortcut?: string;
+ };

And in renderCommand:

- renderCommand={(command) => {
-   const { name, shortcut, highlight: maybeDirtyString } = command;
+ renderCommand={(command) => {
+   const { name, shortcut, highlight: maybeDirtyString } = command as Command & {
+     shortcut?: string;
+     highlight?: string;
+   };

This allows your local commands to carry shortcuts and access the library's highlight field without TS errors.

Also remove debug console.log statements at lines 74 and 118.

🧹 Nitpick comments (2)
frontend/javascripts/dashboard/advanced_dataset/dataset_action_view.tsx (1)

23-24: Use getViewDatasetURL consistently for “View Dataset” navigation

The new use of getViewDatasetURL(dataset) for the inline “View Dataset” link looks good and keeps URL construction centralized.

To avoid future drift, you could also switch the context‑menu “View” action to use the same helper:

-            onClick: () => {
-              window.location.href = `/datasets/${getReadableURLPart(dataset)}/view`;
-            },
+            onClick: () => {
+              window.location.href = getViewDatasetURL(dataset);
+            },

This keeps all dataset view URLs in sync.

Also applies to: 262-265, 313-320

frontend/javascripts/viewer/view/components/command_palette.tsx (1)

69-72: Reconsider manual HTML sanitization before dangerouslySetInnerHTML

cleanStringOfMostHTML plus dangerouslySetInnerHTML is a reasonable first defense, but it’s still a hand‑rolled sanitizer around user‑influenced strings (e.g. dataset/annotation names via highlight). This is brittle and easy to get wrong over time.

If you keep dangerouslySetInnerHTML, consider:

  • Using a dedicated sanitizer (e.g. DOMPurify) with a strict allowlist (only <b>).
  • Or avoiding HTML altogether by rendering plain text and letting React handle highlighting via JSX instead of raw HTML.

That would fully address the XSS warning and make the code easier to reason about.

Also applies to: 365-381

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e9816db and b0cb4ac.

📒 Files selected for processing (3)
  • frontend/javascripts/dashboard/advanced_dataset/dataset_action_view.tsx (2 hunks)
  • frontend/javascripts/viewer/model/accessors/dataset_accessor.ts (1 hunks)
  • frontend/javascripts/viewer/view/components/command_palette.tsx (7 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-21T10:54:16.468Z
Learnt from: knollengewaechs
Repo: scalableminds/webknossos PR: 8961
File: frontend/javascripts/viewer/model/actions/annotation_actions.ts:80-82
Timestamp: 2025-10-21T10:54:16.468Z
Learning: In frontend/javascripts/viewer/model/actions/annotation_actions.ts, the ShowManyBucketUpdatesWarningAction is intentionally not included in the AnnotationActionTypes union because it's a UI-only action that doesn't modify the annotation state through reducers.

Applied to files:

  • frontend/javascripts/viewer/view/components/command_palette.tsx
🧬 Code graph analysis (2)
frontend/javascripts/viewer/model/accessors/dataset_accessor.ts (1)
frontend/javascripts/types/api_types.ts (2)
  • APIDataset (243-246)
  • APIDatasetCompact (271-276)
frontend/javascripts/dashboard/advanced_dataset/dataset_action_view.tsx (1)
frontend/javascripts/viewer/model/accessors/dataset_accessor.ts (1)
  • getViewDatasetURL (753-755)
🪛 ast-grep (0.40.0)
frontend/javascripts/viewer/view/components/command_palette.tsx

[warning] 374-374: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 GitHub Actions: CI Pipeline
frontend/javascripts/viewer/view/components/command_palette.tsx

[error] 310-310: TypeScript error TS2353: Object literal may only specify known properties, and 'shortcut' does not exist in type 'CommandWithoutId'.

🪛 GitHub Check: backend-tests
frontend/javascripts/viewer/view/components/command_palette.tsx

[failure] 310-310:
Object literal may only specify known properties, and 'shortcut' does not exist in type 'CommandWithoutId'.


[failure] 366-366:
Property 'highlight' does not exist on type 'Command'.


[failure] 366-366:
Property 'shortcut' does not exist on type 'Command'.

🪛 GitHub Check: frontend-tests
frontend/javascripts/viewer/view/components/command_palette.tsx

[failure] 310-310:
Object literal may only specify known properties, and 'shortcut' does not exist in type 'CommandWithoutId'.


[failure] 366-366:
Property 'highlight' does not exist on type 'Command'.


[failure] 366-366:
Property 'shortcut' does not exist on type 'Command'.

🔇 Additional comments (2)
frontend/javascripts/viewer/model/accessors/dataset_accessor.ts (1)

743-755: New URL helper is consistent and type‑safe

getViewDatasetURL correctly reuses getReadableURLPart and matches the existing /datasets/{readable}/view pattern for both APIDataset and APIDatasetCompact. No issues from a typing or correctness perspective.

frontend/javascripts/viewer/view/components/command_palette.tsx (1)

117-145: Dynamic dataset/annotation commands and palette reset logic look sound

The dynamic commands (viewDataset, viewAnnotation) plus handleSelect/closePalette and the static command aggregation in allStaticCommands are coherent:

  • Selecting “> View Dataset...” / “> View Annotation...” expands into concrete items via getDatasetItems / getAnnotationItems.
  • Empty lists are handled with a Toast message.
  • Final selections close the palette via closePalette and reset commands on onRequestClose.

No functional issues stand out here.

Also applies to: 146-157, 164-175, 177-181, 327-341

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b0cb4ac and 62984ae.

📒 Files selected for processing (1)
  • frontend/javascripts/viewer/view/components/command_palette.tsx (7 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-21T10:54:16.468Z
Learnt from: knollengewaechs
Repo: scalableminds/webknossos PR: 8961
File: frontend/javascripts/viewer/model/actions/annotation_actions.ts:80-82
Timestamp: 2025-10-21T10:54:16.468Z
Learning: In frontend/javascripts/viewer/model/actions/annotation_actions.ts, the ShowManyBucketUpdatesWarningAction is intentionally not included in the AnnotationActionTypes union because it's a UI-only action that doesn't modify the annotation state through reducers.

Applied to files:

  • frontend/javascripts/viewer/view/components/command_palette.tsx
🪛 ast-grep (0.40.0)
frontend/javascripts/viewer/view/components/command_palette.tsx

[warning] 376-376: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 GitHub Check: frontend-tests
frontend/javascripts/viewer/view/components/command_palette.tsx

[failure] 368-368:
Property 'highlight' does not exist on type 'Command'.


[failure] 368-368:
Property 'shortcut' does not exist on type 'Command'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: backend-tests
  • GitHub Check: build-smoketest-push

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
frontend/javascripts/viewer/view/components/command_palette.tsx (1)

34-36: Fix extended command types for shortcut/highlight to satisfy TypeScript.

frontend-tests is failing because CommandWithoutId doesn’t declare shortcut, and renderCommand destructures shortcut/highlight from Command, which doesn’t include those fields in the lib typings. Extending the type locally and casting inside renderCommand keeps things type-safe while allowing the extra props.

-// duplicate fields because otherwise, optional fields of Command yield errors
-type CommandWithoutId = Omit<Command, "id">;
+// Extend react-command-palette's Command with our own optional fields.
+type ExtendedCommand = Command & {
+  shortcut?: string;
+  highlight?: string;
+};
+
+// duplicate fields because otherwise, optional fields of Command yield errors
+type CommandWithoutId = Omit<ExtendedCommand, "id">;
@@
-      renderCommand={(command) => {
-        const { name, shortcut, highlight: maybeDirtyString } = command;
+      renderCommand={(command) => {
+        const { name, shortcut = "", highlight: maybeDirtyString } =
+          command as ExtendedCommand;

This also resolves the object-literal error in getToolEntries, since shortcut becomes part of CommandWithoutId.

Also applies to: 285-297, 309-309, 365-367

🧹 Nitpick comments (2)
frontend/javascripts/viewer/view/components/command_palette.tsx (2)

71-74: Custom HTML cleaning + dangerouslySetInnerHTML is brittle; consider a safer approach.

cleanStringOfMostHTML plus dangerouslySetInnerHTML is narrowly scoped to allow only <b> tags, but regex-based HTML sanitizers are easy to get wrong and static analysis flags this as a potential XSS vector. If feasible, consider either using a small sanitizer (e.g., DOMPurify) on highlight, or parsing the <b> markers and rebuilding JSX instead of injecting raw HTML.

Also applies to: 373-377


117-145: Tighten handleSelect typing and add error handling for async dataset/annotation loads.

handleSelect is typed as Record<string, unknown>, and failures in getDatasets/getReadableAnnotations would currently bubble up and break the palette. You can leverage the lib’s Command type and surface backend failures via Toast instead.

-  const handleSelect = useCallback(async (command: Record<string, unknown>) => {
-    if (typeof command === "string") {
-      return;
-    }
-
-    if (command.name === DynamicCommands.viewDataset) {
-      const items = await getDatasetItems();
-      if (items.length > 0) {
-        setCommands(items);
-      } else {
-        Toast.info("No datasets available.");
-      }
-      return;
-    }
-
-    if (command.name === DynamicCommands.viewAnnotation) {
-      const items = await getAnnotationItems();
-      if (items.length > 0) {
-        setCommands(items);
-      } else {
-        Toast.info("No annotations available.");
-      }
-      return;
-    }
-
-    closePalette();
-  }, []);
+  const handleSelect = useCallback(
+    async (command: Command | string) => {
+      if (typeof command === "string") {
+        return;
+      }
+
+      if (command.name === DynamicCommands.viewDataset) {
+        try {
+          const items = await getDatasetItems();
+          if (items.length > 0) {
+            setCommands(items);
+          } else {
+            Toast.info("No datasets available.");
+          }
+        } catch {
+          Toast.info("Failed to load datasets.");
+        }
+        return;
+      }
+
+      if (command.name === DynamicCommands.viewAnnotation) {
+        try {
+          const items = await getAnnotationItems();
+          if (items.length > 0) {
+            setCommands(items);
+          } else {
+            Toast.info("No annotations available.");
+          }
+        } catch {
+          Toast.info("Failed to load annotations.");
+        }
+        return;
+      }
+
+      closePalette();
+    },
+    [],
+  );

This makes the callback type-accurate and avoids uncaught errors when the dataset/annotation requests fail.

Also applies to: 145-155, 163-175, 176-180

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c62998b and 320114e.

📒 Files selected for processing (1)
  • frontend/javascripts/viewer/view/components/command_palette.tsx (7 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-21T10:54:16.468Z
Learnt from: knollengewaechs
Repo: scalableminds/webknossos PR: 8961
File: frontend/javascripts/viewer/model/actions/annotation_actions.ts:80-82
Timestamp: 2025-10-21T10:54:16.468Z
Learning: In frontend/javascripts/viewer/model/actions/annotation_actions.ts, the ShowManyBucketUpdatesWarningAction is intentionally not included in the AnnotationActionTypes union because it's a UI-only action that doesn't modify the annotation state through reducers.

Applied to files:

  • frontend/javascripts/viewer/view/components/command_palette.tsx
📚 Learning: 2025-09-04T10:01:56.727Z
Learnt from: knollengewaechs
Repo: scalableminds/webknossos PR: 8895
File: frontend/javascripts/viewer/view/action_bar_view.tsx:0-0
Timestamp: 2025-09-04T10:01:56.727Z
Learning: In frontend/javascripts/viewer/view/action_bar_view.tsx, knollengewaechs prefers not to use onKeyUpCapture for preventing modal close on modifier keys because: 1) holding ctrl while opening modal will still close on keyup, 2) normal case of opening modal then pressing ctrl doesn't cause issues with just onKeyDownCapture.

Applied to files:

  • frontend/javascripts/viewer/view/components/command_palette.tsx
🧬 Code graph analysis (1)
frontend/javascripts/viewer/view/components/command_palette.tsx (4)
frontend/javascripts/admin/rest_api.ts (2)
  • getDatasets (995-1024)
  • getReadableAnnotations (472-479)
frontend/javascripts/viewer/model/accessors/dataset_accessor.ts (1)
  • getViewDatasetURL (753-757)
frontend/javascripts/viewer/constants.ts (1)
  • ViewModeValues (4-4)
frontend/javascripts/viewer/model/actions/settings_actions.ts (1)
  • setViewModeAction (115-119)
🪛 ast-grep (0.40.0)
frontend/javascripts/viewer/view/components/command_palette.tsx

[warning] 373-373: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 GitHub Check: frontend-tests
frontend/javascripts/viewer/view/components/command_palette.tsx

[failure] 309-309:
Object literal may only specify known properties, and 'shortcut' does not exist in type 'CommandWithoutId'.


[failure] 365-365:
Property 'highlight' does not exist on type 'Command'.


[failure] 365-365:
Property 'shortcut' does not exist on type 'Command'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-smoketest-push
  • GitHub Check: backend-tests
🔇 Additional comments (2)
frontend/javascripts/viewer/view/components/command_palette.tsx (2)

268-283: View-mode and tool commands + shortcuts look good; keep them aligned with actual keybindings.

getViewModeEntries and shortCutDictForTools make the palette much more discoverable and give users a clear mapping from tools to "Ctrl + K, …" combos. Just ensure these strings stay in sync with whatever actually binds those shortcuts so the palette doesn’t drift out of date.

Also applies to: 285-297, 298-314


326-339: Palette state and paletteKey handling are consistent with the dynamic submenu UX.

Using allStaticCommands as the baseline plus commands state, a paletteKey-driven remount, closeOnSelect={false}, and onRequestClose={() => setCommands(allStaticCommands)} matches the intended behaviour (expand datasets/annotations in-place, but reset to the static set whenever the palette is closed). Given the palette blocks interaction with the rest of the UI, this should keep the visible commands in sync with the viewer state on each open.

Also applies to: 341-349, 353-364

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
frontend/javascripts/viewer/view/components/command_palette.tsx (2)

367-384: Cast command to extended type to fix TypeScript errors.

The renderCommand callback receives a Command type from react-command-palette, which doesn't include shortcut or highlight properties, causing build failures.

Apply this diff to cast the command to your extended type:

       renderCommand={(command) => {
-        const { shortcut, highlight: maybeDirtyString, name } = command;
+        const { shortcut, highlight: maybeDirtyString, name } =
+          command as Command & { shortcut?: string; highlight?: string };
         const cleanString = cleanStringOfMostHTML(maybeDirtyString);

As per the static analysis hints. This mirrors the fix needed for the type definition at line 34.


34-34: Fix TypeScript build errors by extending the Command type.

The CommandWithoutId type doesn't include the shortcut and highlight properties you're using throughout the file, causing build failures at lines 312 and 368.

Apply this diff to extend the type:

-// duplicate fields because otherwise, optional fields of Command yield errors
-type CommandWithoutId = Omit<Command, "id">;
+// Extend Command type to include optional shortcut and highlight fields
+type CommandWithoutId = Omit<Command, "id"> & {
+  shortcut?: string;
+  highlight?: string;
+};

As per the static analysis hints.

🧹 Nitpick comments (1)
frontend/javascripts/viewer/view/components/command_palette.tsx (1)

329-339: Consider memoizing allStaticCommands for performance.

The allStaticCommands array is recreated on every render, which calls multiple getter functions. While the performance impact is likely minor, memoizing it could avoid unnecessary work.

-  const allStaticCommands = [
+  const allStaticCommands = useMemo(() => [
     viewDatasetsItem,
     viewAnnotationItems,
     ...getNavigationEntries(),
     ...getThemeEntries(),
     ...getToolEntries(),
     ...getViewModeEntries(),
     ...mapMenuActionsToCommands(menuActions),
     ...getTabsAndSettingsMenuItems(),
     ...getSuperUserItems(),
-  ];
+  ], [
+    activeUser,
+    isInTracingView,
+    isViewMode,
+    userConfig,
+    restrictions,
+    menuActions,
+  ]);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3994e16 and 6597d50.

📒 Files selected for processing (2)
  • frontend/javascripts/viewer/view/components/command_palette.tsx (7 hunks)
  • frontend/stylesheets/command_palette.less (2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-21T10:54:16.468Z
Learnt from: knollengewaechs
Repo: scalableminds/webknossos PR: 8961
File: frontend/javascripts/viewer/model/actions/annotation_actions.ts:80-82
Timestamp: 2025-10-21T10:54:16.468Z
Learning: In frontend/javascripts/viewer/model/actions/annotation_actions.ts, the ShowManyBucketUpdatesWarningAction is intentionally not included in the AnnotationActionTypes union because it's a UI-only action that doesn't modify the annotation state through reducers.

Applied to files:

  • frontend/javascripts/viewer/view/components/command_palette.tsx
📚 Learning: 2025-09-04T10:01:56.727Z
Learnt from: knollengewaechs
Repo: scalableminds/webknossos PR: 8895
File: frontend/javascripts/viewer/view/action_bar_view.tsx:0-0
Timestamp: 2025-09-04T10:01:56.727Z
Learning: In frontend/javascripts/viewer/view/action_bar_view.tsx, knollengewaechs prefers not to use onKeyUpCapture for preventing modal close on modifier keys because: 1) holding ctrl while opening modal will still close on keyup, 2) normal case of opening modal then pressing ctrl doesn't cause issues with just onKeyDownCapture.

Applied to files:

  • frontend/javascripts/viewer/view/components/command_palette.tsx
🧬 Code graph analysis (1)
frontend/javascripts/viewer/view/components/command_palette.tsx (4)
frontend/javascripts/admin/rest_api.ts (2)
  • getDatasets (995-1024)
  • getReadableAnnotations (472-479)
frontend/javascripts/viewer/model/accessors/dataset_accessor.ts (1)
  • getViewDatasetURL (753-757)
frontend/javascripts/viewer/constants.ts (1)
  • ViewModeValues (4-4)
frontend/javascripts/viewer/model/actions/settings_actions.ts (1)
  • setViewModeAction (115-119)
🪛 ast-grep (0.40.0)
frontend/javascripts/viewer/view/components/command_palette.tsx

[warning] 376-376: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 GitHub Check: frontend-tests
frontend/javascripts/viewer/view/components/command_palette.tsx

[failure] 312-312:
Object literal may only specify known properties, and 'shortcut' does not exist in type 'CommandWithoutId'.


[failure] 368-368:
Property 'highlight' does not exist on type 'Command'.


[failure] 368-368:
Property 'shortcut' does not exist on type 'Command'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-smoketest-push
  • GitHub Check: backend-tests
🔇 Additional comments (2)
frontend/stylesheets/command_palette.less (1)

103-110: LGTM! Proper scrolling support for expanded suggestions.

The additions of overflow-y: scroll; and scrollbar-width: thin; correctly enable vertical scrolling in the suggestions container while maintaining the fixed 315px max-height. The CSS cascade is sound—overflow-y: scroll; properly overrides the y-axis behavior from the earlier overflow: hidden; shorthand, keeping the x-axis hidden to prevent horizontal scroll. This aligns well with the PR's goal of dynamically populating the palette with datasets and annotations, which can exceed the container height.

frontend/javascripts/viewer/view/components/command_palette.tsx (1)

288-299: Nice addition!

The shortcut dictionary provides helpful keyboard shortcut hints for users, improving discoverability of tool switching commands.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
frontend/javascripts/viewer/view/components/command_palette.tsx (1)

34-36: Fix TypeScript typings for extended command fields (shortcut / highlight)

Current typing causes the frontend TS build to fail:

  • CommandWithoutId = Omit<Command, "id"> doesn’t declare shortcut, yet several commands specify shortcut.
  • renderCommand destructures shortcut and highlight from the incoming command, which is typed as Command by react-command-palette and doesn’t expose those properties.

Define an extended command type and assert before destructuring so both object literals and renderCommand compile cleanly.

Suggested diff:

@@
-// duplicate fields because otherwise, optional fields of Command yield errors
-type CommandWithoutId = Omit<Command, "id">;
+type ExtendedCommand = Command & {
+  // Extra optional fields used in our UI but not declared on `react-command-palette`'s Command.
+  shortcut?: string;
+  highlight?: string;
+};
+
+type CommandWithoutId = Omit<ExtendedCommand, "id">;
@@
   const shortCutDictForTools: Record<string, string> = {
@@
       commands.push({
         name: `Switch to ${tool.readableName}`,
         command: () => Store.dispatch(setToolAction(tool)),
-        shortcut: shortCutDictForTools[tool.id] || "",
+        shortcut: shortCutDictForTools[tool.id] || "",
         color: commandEntryColor,
       });
@@
-      renderCommand={(command) => {
-        const { shortcut, highlight: maybeDirtyString, name } = command;
+      renderCommand={(command) => {
+        const { name, shortcut = "", highlight: maybeDirtyString } =
+          command as ExtendedCommand;
         const cleanString = cleanStringOfMostHTML(maybeDirtyString);
@@
-            <span>{shortcut}</span>
+            <span>{shortcut}</span>

After this change, rerun yarn typecheck / yarn test-frontend to confirm the TS errors about shortcut/highlight are gone.

#!/bin/bash
yarn typecheck

Also applies to: 298-323, 378-392

🧹 Nitpick comments (1)
frontend/javascripts/viewer/view/components/command_palette.tsx (1)

118-149: Dynamic dataset/annotation commands: behaviour and UX look solid; consider optional limits

The async handling for > View Dataset… and > View Annotation… looks good:

  • Errors are surfaced via Toast.error, empty results via Toast.info.
  • Annotations are sorted by modified descending, matching the dashboard behaviour.
  • Dataset/annotation items navigate directly via getViewDatasetURL(dataset) and /annotations/${annotation.id}, which aligns with the rest of the UI.

One optional refinement: getDatasets() without a limit might become heavy in very large installations. If you start seeing performance issues, consider passing a reasonable limit (e.g., 100–200) to getDatasets and/or adding simple client-side filtering, but that’s not required for correctness now.

Also applies to: 154-193

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6597d50 and ca638cf.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (2)
  • frontend/javascripts/viewer/view/components/command_palette.tsx (7 hunks)
  • package.json (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-21T10:54:16.468Z
Learnt from: knollengewaechs
Repo: scalableminds/webknossos PR: 8961
File: frontend/javascripts/viewer/model/actions/annotation_actions.ts:80-82
Timestamp: 2025-10-21T10:54:16.468Z
Learning: In frontend/javascripts/viewer/model/actions/annotation_actions.ts, the ShowManyBucketUpdatesWarningAction is intentionally not included in the AnnotationActionTypes union because it's a UI-only action that doesn't modify the annotation state through reducers.

Applied to files:

  • frontend/javascripts/viewer/view/components/command_palette.tsx
📚 Learning: 2025-09-04T10:01:56.727Z
Learnt from: knollengewaechs
Repo: scalableminds/webknossos PR: 8895
File: frontend/javascripts/viewer/view/action_bar_view.tsx:0-0
Timestamp: 2025-09-04T10:01:56.727Z
Learning: In frontend/javascripts/viewer/view/action_bar_view.tsx, knollengewaechs prefers not to use onKeyUpCapture for preventing modal close on modifier keys because: 1) holding ctrl while opening modal will still close on keyup, 2) normal case of opening modal then pressing ctrl doesn't cause issues with just onKeyDownCapture.

Applied to files:

  • frontend/javascripts/viewer/view/components/command_palette.tsx
🧬 Code graph analysis (1)
frontend/javascripts/viewer/view/components/command_palette.tsx (4)
frontend/javascripts/admin/rest_api.ts (2)
  • getDatasets (995-1024)
  • getReadableAnnotations (472-479)
frontend/javascripts/viewer/model/accessors/dataset_accessor.ts (1)
  • getViewDatasetURL (753-757)
frontend/javascripts/viewer/constants.ts (1)
  • ViewModeValues (4-4)
frontend/javascripts/viewer/model/actions/settings_actions.ts (1)
  • setViewModeAction (115-119)
🪛 ast-grep (0.40.0)
frontend/javascripts/viewer/view/components/command_palette.tsx

[warning] 386-386: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 GitHub Check: frontend-tests
frontend/javascripts/viewer/view/components/command_palette.tsx

[failure] 322-322:
Object literal may only specify known properties, and 'shortcut' does not exist in type 'CommandWithoutId'.


[failure] 378-378:
Property 'highlight' does not exist on type 'Command'.


[failure] 378-378:
Property 'shortcut' does not exist on type 'Command'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-smoketest-push
  • GitHub Check: backend-tests
🔇 Additional comments (3)
package.json (1)

124-155: DOMPurify as a runtime dependency looks appropriate

Using DOMPurify from the viewer at runtime justifies adding it under dependencies (and only there). No issues spotted here.

If you want to double‑check compatibility, verify that dompurify@^3.3.0 is supported by your bundler/TS setup (e.g., yarn add dompurify@^3.3.0 in a throwaway branch and run yarn typecheck).

frontend/javascripts/viewer/view/components/command_palette.tsx (2)

281-297: View‑mode/layout commands and palette lifecycle wiring look consistent

The added view-mode entries (ViewModeValues + setViewModeAction) and “Reset layout” (layoutEmitter.emit(LayoutEvents.resetLayout)) integrate cleanly with the existing viewer state.

The palette lifecycle wiring (commands + commandsWithIds, paletteKey-based remount, closeOnSelect={false}, onRequestClose={() => setCommands(allStaticCommands)}) matches the dynamic-lists example from react-command-palette and should behave as intended (static commands on open, dynamic lists only after explicit selection).

No changes needed here from my side.

Also applies to: 339-357, 358-367, 372-377


71-75: Now let me check the web search results about DOMPurify 3.3.0 support for ALLOWED_ATTR:

DOMPurify 3.3.0 documentation ALLOWED_ATTR

And let me also check the official DOMPurify repository or changelog:

DOMPurify version 3.3.0 release notes ALLOWED_ATTR support

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ca638cf and 396a931.

📒 Files selected for processing (1)
  • frontend/javascripts/viewer/view/components/command_palette.tsx (7 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-21T10:54:16.468Z
Learnt from: knollengewaechs
Repo: scalableminds/webknossos PR: 8961
File: frontend/javascripts/viewer/model/actions/annotation_actions.ts:80-82
Timestamp: 2025-10-21T10:54:16.468Z
Learning: In frontend/javascripts/viewer/model/actions/annotation_actions.ts, the ShowManyBucketUpdatesWarningAction is intentionally not included in the AnnotationActionTypes union because it's a UI-only action that doesn't modify the annotation state through reducers.

Applied to files:

  • frontend/javascripts/viewer/view/components/command_palette.tsx
📚 Learning: 2025-09-04T10:01:56.727Z
Learnt from: knollengewaechs
Repo: scalableminds/webknossos PR: 8895
File: frontend/javascripts/viewer/view/action_bar_view.tsx:0-0
Timestamp: 2025-09-04T10:01:56.727Z
Learning: In frontend/javascripts/viewer/view/action_bar_view.tsx, knollengewaechs prefers not to use onKeyUpCapture for preventing modal close on modifier keys because: 1) holding ctrl while opening modal will still close on keyup, 2) normal case of opening modal then pressing ctrl doesn't cause issues with just onKeyDownCapture.

Applied to files:

  • frontend/javascripts/viewer/view/components/command_palette.tsx
🪛 ast-grep (0.40.0)
frontend/javascripts/viewer/view/components/command_palette.tsx

[warning] 394-394: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 GitHub Check: frontend-tests
frontend/javascripts/viewer/view/components/command_palette.tsx

[failure] 386-386:
Property 'highlight' does not exist on type 'Command'.


[failure] 386-386:
Property 'shortcut' does not exist on type 'Command'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-smoketest-push
  • GitHub Check: backend-tests
🔇 Additional comments (3)
frontend/javascripts/viewer/view/components/command_palette.tsx (3)

31-41: Command modeling and tool shortcut wiring look solid

Defining a local Command/CommandWithoutId shape with optional shortcut/highlight and using shortCutDictForTools to populate shortcut into getToolEntries, then aggregating everything via allStaticCommands, is clear and maintainable. The structure should make it easy to extend with more commands or shortcuts later without surprises.

Also applies to: 306-317, 330-330, 347-357


79-82: DOMPurify sanitization makes dangerouslySetInnerHTML acceptable here

Using cleanStringOfMostHTML with DOMPurify.sanitize and ALLOWED_TAGS: ["b"] before passing content into dangerouslySetInnerHTML is a reasonable mitigation against XSS in this context. The static warning about dangerouslySetInnerHTML can be considered addressed, since only sanitized markup with a single safe tag is rendered, and the fallback to plain {name} handles the non-highlighted case cleanly.

Also applies to: 393-399


386-401: Verify the proposed TypeScript fix by running the actual TypeScript compiler on the codebase after applying the change.

The review comment proposes casting the command parameter in the renderCommand callback to resolve TypeScript errors. However, based on examination of the codebase:

  1. Current code state: The file defines its own local Command type (lines 33–40) that includes shortcut? and highlight? as optional fields.

  2. Objects passed: The commandsWithIds (lines 366–370) constructs objects with { id: index, ...command } where command is CommandWithoutId, giving them all required properties including shortcut and highlight.

  3. Parameter typing issue: The renderCommand callback parameter at line 385 is not explicitly typed, so TypeScript infers its type from the ReactCommandPalette prop definition. If react-command-palette exports a Command type that doesn't include these optional fields, then destructuring them would indeed cause type errors.

  4. Proposed fix: Casting to CommandWithoutId & { highlight?: string } as shown in the diff would make the type explicit and safe.

However, I could not definitively verify:

  • Whether TypeScript errors actually exist (the "frontend-tests" mentioned are not located in the repository)
  • The exact exported Command type from @types/react-command-palette (node_modules not available in sandbox)

The fix appears reasonable for type safety, but confirmation requires running tsc or the actual test pipeline to verify the errors are resolved.

onRequestClose={() => setCommands(allStaticCommands)}
closeOnSelect={false}
renderCommand={(command) => {
const { shortcut, highlight: maybeDirtyString, name } = command;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@philippotto do you have any idea why this fails and how to fix it? no matter if use the import form command_palette.d.ts or whether I redefine the type in the module, this error occurs. Furthermore, it only occurs in the pipeline, not locally when running yarn typecheck.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

image

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
frontend/javascripts/viewer/view/components/command_palette.tsx (2)

363-365: Optional: Reset commands when closing to prevent stuck dynamic list (repeat suggestion).

closePalette() bumps the key to remount ReactCommandPalette but doesn't reset commands back to allStaticCommands. If a future change adds dynamic items that don't navigate (currently all items use window.location.href which reloads the page), users could get stuck viewing only the dynamic list on subsequent opens.

For correctness and future-proofing, consider adding setCommands(allStaticCommands) before bumping the key, as previously suggested.

 const closePalette = () => {
+  setCommands(allStaticCommands);
   setPaletteKey((prevKey) => prevKey + 1);
 };

387-387: TypeScript error: Cast command to extended type before destructuring.

The frontend-tests pipeline fails because renderCommand receives a Command type from the library (react-command-palette) which lacks shortcut and highlight properties. The code attempts to destructure these properties without casting, causing TypeScript errors.

Apply this fix:

-      renderCommand={(command) => {
-        const { shortcut, highlight: maybeDirtyString, name } = command;
+      renderCommand={(command) => {
+        const { shortcut, highlight: maybeDirtyString, name } = command as Command;

Note: This was flagged in a previous review and marked as addressed, but the fix is not present in the current code.

🧹 Nitpick comments (3)
frontend/stylesheets/command_palette.less (1)

103-110: Scrolling behavior correctly added; consider consolidating overflow properties.

The addition of overflow-y: auto (Line 108) correctly overrides the y-axis behavior of overflow: hidden (Line 104), enabling vertical scrolling with scrollbar-width: thin. This change is appropriate for supporting an expanded suggestions list with datasets and annotations.

For clarity, consider replacing overflow: hidden with overflow-x: hidden to make the intent explicit, reducing cognitive load when reading the ruleset.

.command-palette-suggestionsContainerOpen {
-  overflow: hidden;
+  overflow-x: hidden;
   border: 1px solid var(--color-bg);
   max-height: 315px;
   margin-top: 10px;
   overflow-y: auto;
   scrollbar-width: thin;
}
frontend/javascripts/viewer/view/components/command_palette.tsx (2)

33-41: Consider addressing the TODO comment about the Command type definition.

The custom Command type redefines properties from the library to add shortcut and highlight. While this works, the TODO suggests exploring alternatives. However, given that the library doesn't export an extensible type and TypeScript doesn't allow easy augmentation of third-party types without module augmentation, this approach is pragmatic.

If you want to keep this pattern, consider removing the TODO and adding a brief comment explaining why the redefinition is necessary (e.g., "Extends react-command-palette's Command type with optional fields").


163-173: Consider using React Router navigation instead of full page reload.

The dataset navigation uses window.location.href = getViewDatasetURL(dataset) which triggers a full page reload. If the app uses React Router, consider using navigate() or history.push() to maintain SPA benefits (faster navigation, preserved state).

Same applies to annotation navigation at line 189.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 396a931 and 59d89c9.

📒 Files selected for processing (2)
  • frontend/javascripts/viewer/view/components/command_palette.tsx (7 hunks)
  • frontend/stylesheets/command_palette.less (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-04T10:01:56.727Z
Learnt from: knollengewaechs
Repo: scalableminds/webknossos PR: 8895
File: frontend/javascripts/viewer/view/action_bar_view.tsx:0-0
Timestamp: 2025-09-04T10:01:56.727Z
Learning: In frontend/javascripts/viewer/view/action_bar_view.tsx, knollengewaechs prefers not to use onKeyUpCapture for preventing modal close on modifier keys because: 1) holding ctrl while opening modal will still close on keyup, 2) normal case of opening modal then pressing ctrl doesn't cause issues with just onKeyDownCapture.

Applied to files:

  • frontend/javascripts/viewer/view/components/command_palette.tsx
🪛 ast-grep (0.40.0)
frontend/javascripts/viewer/view/components/command_palette.tsx

[warning] 395-395: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🪛 GitHub Check: frontend-tests
frontend/javascripts/viewer/view/components/command_palette.tsx

[failure] 387-387:
Property 'highlight' does not exist on type 'Command'.


[failure] 387-387:
Property 'shortcut' does not exist on type 'Command'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-smoketest-push
  • GitHub Check: backend-tests
🔇 Additional comments (5)
frontend/javascripts/viewer/view/components/command_palette.tsx (5)

79-82: LGTM! Proper HTML sanitization.

The use of DOMPurify with a strict allowlist (ALLOWED_TAGS: ["b"]) is the correct approach for sanitizing the highlighted text while preserving bold formatting. This effectively mitigates XSS risks.


182-195: LGTM! Annotation sorting and error handling.

The annotations are correctly sorted by modified date in descending order (most recent first), and error handling with Toast notifications provides good user feedback.


290-305: LGTM! View mode switching and layout reset.

The view mode entries are correctly guarded for tracing view, and the layout reset integration using layoutEmitter is appropriate.


367-371: LGTM! Proper command transformation with IDs.

The useMemo ensures commands are efficiently transformed with IDs only when the commands array changes.


394-396: LGTM! Safe use of dangerouslySetInnerHTML with DOMPurify.

The HTML content is sanitized with DOMPurify before rendering, with a strict allowlist of only <b> tags. This effectively prevents XSS while preserving the highlighted text formatting. The static analysis warning can be safely ignored in this case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants