fix(DesignerV2): Server-side run history filtering and UX improvements#9267
Open
rllyy97 wants to merge 3 commits into
Open
fix(DesignerV2): Server-side run history filtering and UX improvements#9267rllyy97 wants to merge 3 commits into
rllyy97 wants to merge 3 commits into
Conversation
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.
Contributor
🤖 AI PR Validation ReportPR Review ResultsThank you for your submission! Here's detailed feedback on your PR title and body compliance:✅ PR Title
✅ Commit Type
✅ Risk Level
✅ What & Why
|
| 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
Contributor
There was a problem hiding this comment.
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
RunFilterOptionspassed throughIRunService.getRuns()anduseRunsInfiniteQuery()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 | ||
| } | ||
| } |
Contributor
|
📊 Coverage check completed. See workflow run for details. |
Eric-B-Wu
approved these changes
Jun 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Commit Type
Risk Level
What & Why
Fixes multiple run history panel bugs and improves the filtering experience:
$filterquery parameters sent to the API, returning correct results across all runs.contentto the HTTP client, which then calledJSON.stringifyagain, double-encoding the JSON. The body is now parsed before being set ascontent.Impact of Change
IRunService.getRuns()now accepts an optionalRunFilterOptionsparameter.useRunsInfiniteQueryaccepts filters in its query key for cache separation.$filterqueries are sent server-side, reducing unnecessary client-side data fetching. No new dependencies.Test Plan
Contributors
@rllyy97
Screenshots/Videos
N/A