Skip to content

fix(DesignerV2): Server-side run history filtering and UX improvements#9267

Open
rllyy97 wants to merge 3 commits into
mainfrom
riley/run-history-filters
Open

fix(DesignerV2): Server-side run history filtering and UX improvements#9267
rllyy97 wants to merge 3 commits into
mainfrom
riley/run-history-filters

Conversation

@rllyy97

@rllyy97 rllyy97 commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Commit Type

  • feature - New functionality
  • fix - Bug fix
  • refactor - Code restructuring without behavior change
  • perf - Performance improvement
  • docs - Documentation update
  • test - Test-related changes
  • chore - Maintenance/tooling

Risk Level

  • Low - Minor changes, limited scope
  • Medium - Moderate changes, some user impact
  • High - Major changes, significant user/system impact

What & Why

Fixes multiple run history panel bugs and improves the filtering experience:

  1. Server-side run history filtering (Can't filter logs of custom range in Run History of Logic app consumption #9259, New Run History does not properly apply filters when there are a large number of execution records. #9261) — Status and date/time filters were applied client-side on lazily-paginated data, meaning filters only worked on already-fetched pages. Filters now build OData $filter query parameters sent to the API, returning correct results across all runs.
  2. Run with payload JSON double-encoding (JSON escaped in new experience in Run with payload #9262) — The payload body from the Monaco editor (a JSON string) was passed directly as content to the HTTP client, which then called JSON.stringify again, double-encoding the JSON. The body is now parsed before being set as content.
  3. TimePicker "To" field not working — Stored times had seconds/ms set to 59/999 which never matched the dropdown options (seconds=0, ms=0). End-of-range rounding is now applied only when building the API filter, not in stored state.
  4. UX improvements — Renamed "From"/"To" labels to "Start"/"End", added active filter tags when filter panel is collapsed, added "Waiting" status filter, changed milliseconds display format to "ms".

Impact of Change

  • Users: Run history filters now return correct results. "Run with payload" works correctly for Consumption workflows in the new experience. TimePicker fields work as expected. Waiting status runs are now filterable.
  • Developers: IRunService.getRuns() now accepts an optional RunFilterOptions parameter. useRunsInfiniteQuery accepts filters in its query key for cache separation.
  • System: OData $filter queries are sent server-side, reducing unnecessary client-side data fetching. No new dependencies.

Test Plan

  • Unit tests added/updated
  • E2E tests added/updated
  • Manual testing completed
  • Tested in: 40 existing run service unit tests pass (consumption + standard). Biome formatting clean. No TypeScript errors.

Contributors

@rllyy97

Screenshots/Videos

N/A

Riley Evans added 3 commits June 9, 2026 15:14
- Add RunFilterOptions type and pass filters to getRuns API (status, startTime)
- Build OData $filter params in both Consumption and Standard run services
- Derive displayed runs from query pages instead of stale accumulator cache
- Add active filter tags when filter panel is collapsed
- Add Waiting status filter option
- Change custom time range labels from From/To to Start/End
- Fix TimePicker 'To' field not responding by storing clean times
- Change duration display from 'Milliseconds' to 'ms'

Fixes #9259, #9261
Parse JSON body string into object before passing as content to HttpClient,
which calls JSON.stringify internally. Without this, a JSON string like
'{"name":"test"}' gets double-encoded into a string literal.
Copilot AI review requested due to automatic review settings June 9, 2026 23:33
@rllyy97 rllyy97 changed the title feat: server-side run history filtering and UX improvements fix(DesignerV2): Server-side run history filtering and UX improvements Jun 9, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🤖 AI PR Validation Report

PR Review Results

Thank you for your submission! Here's detailed feedback on your PR title and body compliance:

PR Title

  • Current: fix(DesignerV2): Server-side run history filtering and UX improvements
  • Issue: None — the title is clear, specific, and well-scoped.
  • Recommendation: No change needed.

Commit Type

  • Properly selected (fix).
  • Only one commit type is checked, which is correct.

Risk Level

  • The selected risk level (risk:medium / Medium) matches the change scope and impact reasonably well.

What & Why

  • Current: Detailed and clear summary of the functional changes.
  • Issue: None — this section gives good context and explains the motivation.
  • Recommendation: No change needed.

⚠️ Impact of Change

  • The section is informative, but it could be slightly more explicit about the UI behavior changes and the API/filtering behavior shift for developers.
  • Recommendation:
    • Users: Consider mentioning that the filter panel now shows active filter tags when collapsed and that custom time filtering has been fixed.
    • Developers: Mention that query-key changes may affect caching and that RunFilterOptions is now part of the public run service contract.
    • System: Call out that server-side filtering reduces client-side pagination work and improves correctness on large datasets.

Test Plan

  • Unit tests are added/updated in the diff, which satisfies the test-plan requirement.
  • Manual testing is also documented. E2E tests are not required because unit tests are present.

Contributors

  • Contributor credit is present (@rllyy97).
  • No additional action required.

Screenshots/Videos

  • Marked N/A, which is acceptable for a non-primarily-visual PR, though this change does include some UI improvements.
  • No failure necessary.

Summary Table

Section Status Recommendation
Title
Commit Type
Risk Level
What & Why
Impact of Change ⚠️ Add a bit more detail on user/developer/system impact if desired
Test Plan
Contributors
Screenshots/Videos

Overall: this PR passes. The advised risk level is medium, which matches the submitter’s selection; I did not find evidence to justify raising it higher. The only recommendation is to slightly expand the Impact of Change section for clarity, but this is a suggestion, not a blocker.


Last updated: Tue, 09 Jun 2026 23:43:56 GMT

@rllyy97 rllyy97 added the risk:medium Medium risk change with potential impact label Jun 9, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes multiple DesignerV2 run history issues by moving status/time filtering to server-side OData $filter queries, correcting “run with payload” request body handling to avoid JSON double-encoding, and improving the run history panel UX (labels, tags, and “Waiting” status support).

Changes:

  • Add server-side run history filtering via optional RunFilterOptions passed through IRunService.getRuns() and useRunsInfiniteQuery() query keys.
  • Fix “run with payload” by parsing JSON string bodies before passing them to the HTTP client.
  • UX improvements in the run history panel: Start/End labels, collapsed active filter tags, and “Waiting” status + icon.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
Localize/lang/strings.json Adds/updates localized strings for “ms”, “Waiting”, and Start/End labels.
libs/logic-apps-shared/src/utils/src/lib/helpers/datetime.ts Updates friendly duration formatting to use “ms” strings.
libs/logic-apps-shared/src/designer-client-services/lib/standard/run.ts Adds OData $filter support to getRuns() and parses JSON bodies in runTrigger().
libs/logic-apps-shared/src/designer-client-services/lib/run.ts Extends IRunService.getRuns() with optional RunFilterOptions.
libs/logic-apps-shared/src/designer-client-services/lib/consumption/run.ts Mirrors standard run service changes for filtering + JSON body parsing.
libs/designer-v2/src/lib/ui/panel/runHistoryPanel/statusIndicator.tsx Adds “Waiting” status display with a new icon.
libs/designer-v2/src/lib/ui/panel/runHistoryPanel/runHistoryPanel.tsx Implements filter-to-API mapping, removes client-side paging-only filtering, and adds collapsed active filter tags.
libs/designer-v2/src/lib/ui/panel/runHistoryPanel/runHistoryPanel.styles.ts Adds styling for the active filter tags row.
libs/designer-v2/src/lib/core/queries/runs.ts Adds filters to the runs query key and forwards filters into RunService().getRuns(filters).
libs/designer-v2/src/lib/common/images/status_waiting.svg Adds a new status icon asset for “Waiting”.

Comment on lines 699 to 703
<Field label={customEndLabel} style={{ flex: 1, minWidth: 0 }}>
<DatePicker
className={styles.smallInput}
size="small"
placeholder={selectDatePlaceholder}
Comment on lines +725 to +748
{!filtersExpanded && activeFilterTags.length > 0 && (
<TagGroup className={styles.activeFilterTags} role="list">
{activeFilterTags.map((tag) => (
<Tag
key={tag.key}
size="small"
shape="rounded"
appearance="brand"
dismissible
dismissIcon={{ 'aria-label': 'remove' }}
value={tag.key}
onClick={() => {
addFilterCallback({ key: tag.key, value: undefined });
if (tag.key === 'timeInterval') {
setCustomStart(null);
setCustomEnd(null);
}
}}
>
{tag.label}: {tag.value}
</Tag>
))}
</TagGroup>
)}
Comment on lines +121 to +133
private buildFilterString(filters?: RunFilterOptions): string {
const parts: string[] = [];
if (filters?.status) {
parts.push(`status eq '${filters.status}'`);
}
if (filters?.startTimeFrom) {
parts.push(`startTime ge ${filters.startTimeFrom}`);
}
if (filters?.startTimeTo) {
parts.push(`startTime le ${filters.startTimeTo}`);
}
return parts.join(' and ');
}
Comment on lines +124 to +136
private buildFilterString(filters?: RunFilterOptions): string {
const parts: string[] = [];
if (filters?.status) {
parts.push(`status eq '${filters.status}'`);
}
if (filters?.startTimeFrom) {
parts.push(`startTime ge ${filters.startTimeFrom}`);
}
if (filters?.startTimeTo) {
parts.push(`startTime le ${filters.startTimeTo}`);
}
return parts.join(' and ');
}
Comment on lines +443 to +451
// Parse JSON body string to avoid double-encoding when HttpClient calls JSON.stringify
let bodyContent = options?.body;
if (typeof bodyContent === 'string') {
try {
bodyContent = JSON.parse(bodyContent);
} catch {
// Not valid JSON, send as-is
}
}
Comment on lines +434 to +442
// Parse JSON body string to avoid double-encoding when HttpClient calls JSON.stringify
let bodyContent = options?.body;
if (typeof bodyContent === 'string') {
try {
bodyContent = JSON.parse(bodyContent);
} catch {
// Not valid JSON, send as-is
}
}
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

📊 Coverage check completed. See workflow run for details.

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

Labels

pr-validated risk:medium Medium risk change with potential impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants