Skip to content

Activity Search Phase 1#1875

Open
joswig wants to merge 18 commits into
developfrom
dev/activity_search
Open

Activity Search Phase 1#1875
joswig wants to merge 18 commits into
developfrom
dev/activity_search

Conversation

@joswig
Copy link
Copy Markdown
Collaborator

@joswig joswig commented Feb 16, 2026

Summary

New /search page for finding activity directives across all plans, plus shared-component improvements that came out of building it.

image

Search page

Filters (all bookmarkable via URL query params):

  • Mission Model

  • Activity Type (multi-select; narrowed by selected model)

  • Activity Name

  • Argument Name (typeahead from the selected model's parameter schemas; narrows further with a selected Type)

  • Argument Value (tooltip notes mission-model defaults are not applied. Also – typing 5 matches XYZ: 5 and XYZ: [1, 2, 5]; arrays/structs accepted as JSON)

  • Tag

  • Preset (model-filtered)

  • Created By

  • Last Modified By

  • Created After / Created Before

  • Last Modified Before / After

  • Start Offset min/max

  • Plan Name

  • Plan Owner

  • Plan Tag

  • Scheduling Goal

  • Scheduler-created only
    Results:

  • Server-side pagination, 50/page, with aggregate count

  • Server-side sort translated from AG Grid column state

  • Sticky-footer Search/Clear

  • 500ms-delayed spinner overlay during search

  • Inline banner for subscription errors

  • Per-dropdown loading state

Columns (default-visible unless noted):

  • Open in plan (pinned-left icon, full-cell click)
  • Activity Name, Activity Type, Activity ID (hidden)
  • Plan Name, Plan Owner, Plan ID (hidden), Model, Model ID
  • Tags, Applied Preset
  • Start Offset, Absolute Start Time, Arguments (hidden)
  • Created By, Created At (hidden), Modified By, Last Modified
  • Scheduling Goal, Sched. Goal ID (hidden)
  • Column picker with show/hide all + reset (action column is structural, exempt)
  • Visibility, order, width, sort, pinning persisted to localStorage

Selection & cross-plan copy:

  • Click / cmd-click / shift-click selects rows
  • Right-click menu: "Copy N Activities" puts the selection on the clipboard
  • "Open in plan" — per-row icon button (always visible, pinned left) and a right-click menu item when exactly one row is selected
  • Paste in the target plan via the existing in-plan paste context menu. Cross-plan timing re-grounds correctly (see fixes below but needs review/discussion)

Shared changes

DataGrid:

  • New persistColumnStateKey + transformColumnState props centralize column-state localStorage save/clear
  • Forwarded through BulkActionDataGrid and SingleActionDataGrid
  • WSP and SearchResults consume it
  • WSP keeps its name-column processing via transformColumnState

SearchableDropdown:

  • Menu width uses canvas measureText with font read off a hidden DOM ref (replaces the maxOptionChars * 8 heuristic that overshot for proportional fonts)
  • Items flow through RowVirtualizerFixed as a slot prop so menus refresh while open
  • New loading prop
  • Internal toggle button got type="button" so Enter inside a sibling input no longer toggles the menu

RowVirtualizerFixed:

  • items prop replaces count; slot exposes item
  • TimelineItemList + mock updated

Bug fixes & polish

  • Cross-plan paste now respects the user's right-click paste-at-time even when source activities' absolute times fall outside the target plan window (previously snapped to plan start). Needs review/discussion.
  • DataGrid: switched the selected-row class toggle to querySelectorAll so pinned-left and center containers stay in sync (fixes two-tone selected row with pinned columns — affects every table with pinned columns, not just search)

Test plan

  • Filter combinations produce expected results
  • Pagination traverses all pages
  • Each sortable column sorts via server
  • URL state round-trips across refresh
  • Column-picker state persists across reload
  • Error banner appears on subscription failure

TODO

  • e2e tests
  • Tooltip for argument name width bugfix
  • Multi-select activity type filter
  • Multi-select + cross-plan copy flow
  • Model / Model ID / Absolute Start Time / Scheduling Goal columns
  • Activity ID sort bug fix
  • Cross-plan paste-at-time bug fix
  • New filters: Last Modified By, Created date range, Plan Tag, Scheduling Goal

Future Work

Future directions for this work could involve:

  • Search on activity instances (spans), requires sorting out which simulation dataset to query for each plan.
  • Making use of the activity filter builder paradigm to enable more complex search expressions
  • Searching for plans that contain various activities
  • Searching for activities similar to the one currently selected in a plan
  • Command palette menu integration (once WIP Command Palette 🎨 #1824 is completed) for cross-app activity search without needing to start on /search page
  • Potentially adding a db table/view that would actually give us queryable directive arguments. This has likely been considered in the past but not sure what technical barriers exist.
  • Instantiate cross-plan activity search within a plan panel
  • Constraint violation search - find activities involved in constraint violations
  • Temporal search with absolute times via new computed Hasura field (or two phase query) to resolve absolute times
  • Aggregate views to offer summaries of activity type distribution across plans, parameter value distribution for a selected type/argument, etc

@AaronPlave
Copy link
Copy Markdown
Contributor

AaronPlave commented Feb 18, 2026

This feels very useful, so much potential here

@AaronPlave AaronPlave force-pushed the dev/activity_search branch from 9e5e9c4 to 1849440 Compare April 21, 2026 15:52
@AaronPlave AaronPlave force-pushed the dev/activity_search branch from b91a810 to 34a44a1 Compare April 27, 2026 17:38
@AaronPlave AaronPlave self-assigned this Apr 28, 2026
@AaronPlave AaronPlave changed the title activity search form Activity Search Phase 1 Apr 28, 2026
@AaronPlave AaronPlave marked this pull request as ready for review April 28, 2026 16:20
@AaronPlave AaronPlave requested a review from a team as a code owner April 28, 2026 16:20
joswig and others added 17 commits May 14, 2026 12:52
- Server-side pagination (offset + aggregate count) with first/prev/next/last controls
- Expanded filters: plan name/owner, created_by, last-modified date range, scheduling-goal origin
- Argument name dropdown driven by the selected model's activity type parameter schemas;
  narrows further when an activity type is selected
- Server-side sort: AG Grid column state translated to nested Hasura order_by
- All filter state encoded in URL query params (bookmarkable / shareable searches),
  initialized on load with deferred model-id resolution while subscription primes
- Result table: tag chips, JSON arguments column, formatted timestamps via
  getShortISOForDate, plus toggleable Created At / Plan ID / Activity ID columns
- Column picker (ActivityTableMenu) with show/hide all + reset; column state
  persisted via localStorage. Forward columnVisible / columnsReset events through
  SingleActionDataGrid so the picker can react
- Search button always enabled; auto-search-on-load still gated on a non-empty filter
Adds persistColumnStateKey + transformColumnState props on DataGrid (forwarded
through BulkAction/SingleActionDataGrid). WorkspaceFileBrowser drops its
duplicated save/clear logic and rides its name-column processing through
transformColumnState.
Replace maxOptionChars*8 width estimate with canvas measureText, reading the
font off a hidden DOM ref so it tracks CSS. Pass items through
RowVirtualizerFixed as a slot prop (fixes stale content when array changes
in place). Add loading prop. TimelineItemList + mock updated for new
virtualizer API.
Mission Model uses SearchableDropdown. Collapse pending-model state into a
single selectedModelId (selectedModel derived). Inline subscription-error
banner. Per-dropdown loading. Start Offset min/max filters. Argument Value
defaults tooltip. Search always enabled, above Clear, sticky footer.
500ms-delayed spinner overlay over results; no-op local sort comparators
avoid the flash before server-sorted data lands. SearchResults adopts the
new persistColumnStateKey for column-state persistence.
UI / UX
- Multi-select Activity Type filter (`_in` clause); arg-name dropdown handles multi
- New filters: Last Modified By, Created After/Before, Plan Tag, Scheduling Goal
- New columns: Model, Model ID, Absolute Start Time, Scheduling Goal
- Column order regrouped: action → identity → plan/model → tagging → timing → audit → provenance
- Open-in-plan: Svelte component cell, full-cell click, pinned-left icon column
- Right-click context menu: "Copy N Activit(ies)" and "Open in plan" (single-select)
- Click-drag column resize (no shift-key required)
- Open-in-plan exempt from column picker and the "hide all" sweep

Behavior fixes
- Cross-plan paste respects the right-click paste-at-time even when the source
  activities' absolute times fall outside the target plan window
- Arg value matching: JSON.parse + singleton-array sugar so typing `5` finds
  `XYZ: 5` and `XYZ: [1, 2, 5]`; numeric/bool branch covers all four shapes
- Drop the `directive_id: id` gql alias — fixes Hasura sort error on Activity ID
- DataGrid: querySelectorAll so the selected-row class stays in sync between
  center and pinned-left containers (fixes the two-tone selected row bug)

Types / internals
- ActivityDirectiveSearchResult now extends ActivityDirectiveDB instead of
  redefining shared fields; corrects applied_preset shape along the way
- SEARCH_ACTIVITIES extends plan with mission_model, adds source_scheduling_goal,
  anchor_id, anchored_to_start, metadata for the clipboard mapping
- Use ColumnPinnedType / SortDirection imports for the two literal ColDef fields
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants