Skip to content

Bug-3672: ProjectGroupPicker on select issue for non dashboard#53

Merged
cyrossignol merged 3 commits into
masterfrom
bugfix-3672-project-picker-close-issue
May 22, 2026
Merged

Bug-3672: ProjectGroupPicker on select issue for non dashboard#53
cyrossignol merged 3 commits into
masterfrom
bugfix-3672-project-picker-close-issue

Conversation

@shweta2101
Copy link
Copy Markdown
Contributor

@shweta2101 shweta2101 commented May 20, 2026

Task

https://dev.azure.com/TDEI-UW/TDEI/_workitems/edit/3672/

Root Cause

On non-dashboard pages such as Create Workspace, the ProjectGroupPicker component was wrapped inside a <label> element.

When a user clicked a project group option:

  1. The picker correctly executed its selection logic and closed the dropdown.
  2. Because the picker lived inside a <label>, the browser immediately redirected focus back to the associated input.
  3. That focus event triggered the picker’s open logic again.

Additional issues were also identified while fixing this flow:

  1. ProjectGroupPicker was persisting project group selection globally via session storage, even on non-dashboard pages.
  2. The picker could temporarily reset the dashboard selection to the first loaded project group while paginated results were still loading.
  3. On Export Workspace to the TDEI, the picker showed the infinite-scroll hint even when a complete options list was already supplied.
  4. On Export Workspace to the TDEI, the ServicePicker was not reliably updating after project group selection because:
    • the export page was using a plain workspace object instead of reactive form state
    • the service picker did not reconcile stale selected service ids after reloading services for a new project group

Changes Implemented

1. Added explicit input id support to ProjectGroupPicker

Updated the component so an id prop can be passed through to the internal <input>.

Changes
  • Added id?: string to component props
  • Bound :id="props.id" on the internal input

2. Replaced nested label usage with explicit label association

Refactored pages that wrapped ProjectGroupPicker inside <label>.

Files Updated

  • pages/workspace/create/blank.vue
  • pages/workspace/create/file.vue
  • pages/workspace/create/tdei.vue
  • pages/workspace/[id]/export/tdei.vue

3. Scoped project group persistence to Dashboard only

Updated ProjectGroupPicker so remembered selection is opt-in instead of always enabled.

Changes
  • Added rememberSelection?: boolean to ProjectGroupPicker
  • Enabled remember-selection only on pages/dashboard.vue
  • Prevented create/export pages from reading or writing the dashboard’s remembered project group

4. Fixed dashboard project group reset during initial load

Adjusted picker fallback behavior so a valid existing selection is not replaced just because it is not present in the first fetched page of results.

5. Corrected header text for static options mode

Updated the picker header logic for cases where a full project group list is passed in directly.

6. Fixed service picker refresh on Export to TDEI

Updated the export flow so service selection stays in sync with the selected project group.

Changes
  • Made export-page workspace state reactive in pages/workspace/[id]/export/tdei.vue
  • Added :key="workspace.tdeiProjectGroupId" to ServicePicker on the export page so the component fully refreshes when project group changes
  • Updated components/ServicePicker.vue so stale tdeiServiceId values are replaced when they do not exist in the refreshed service list
  • If no services exist for the selected project group, the service selection is cleared

Additional Files Updated

  • components/ProjectGroupPicker.vue
  • components/ServicePicker.vue
  • pages/dashboard.vue

Test Cases Covered

  1. Functional Behavior
  • Selecting a project group on Create Blank Workspace closes the dropdown immediately.
  • Selecting a project group on Create Workspace from File closes the dropdown immediately.
  • Selecting a project group on Create Workspace from TDEI closes the dropdown immediately.
  • Selecting a project group on Export to TDEI closes the dropdown immediately.
  • Selecting a project group on the Dashboard continues to work as before.
  • On Export to TDEI, changing project group refreshes the Service picker options.
  • On Export to TDEI, if the previously selected service is not valid for the new project group, the picker selects the first valid service.
  • On Export to TDEI, if the new project group has no services, the service selection is cleared.
  • On Export to TDEI, the picker header shows “Showing all N project groups” when a full list is supplied.
  1. Regression Coverage
  • The selected project group value still updates through v-model.
  • The displayed project group name still populates in the input after selection.
  • Keyboard and focus-driven open behavior in ProjectGroupPicker remains unchanged.
  • Dataset loading behavior is unaffected because the projectGroupId binding and downstream watchers were not changed.
  • Dashboard continues to remember its own selected project group.
  • Non-dashboard pages no longer overwrite or reuse the remembered dashboard project group.
  • Dashboard no longer temporarily resets to the first project group during initial paginated load.

Changes

ProjectGroupPicker Component

  • Added optional id prop to support explicit label association via for="id" binding.
  • Introduced rememberSelection prop (default: false) to make session-storage persistence opt-in.
  • Bound :id="props.id" on the internal input wrapper.
  • Added showScrollHint computed and updated dropdown rendering/styling to use it.
  • Made selection persistence (initial load and on selection) conditional on rememberSelection.
  • Adjusted initial display and fallback logic in onMounted and the projectGroups watcher to respect rememberSelection.
  • Corrected header text behavior when a full static options list is supplied (shows “Showing all N project groups”).
  • Prop signature updated: defineProps<{ id?: string; disabled?: boolean; options?: TdeiProjectGroupItem[]; rememberSelection?: boolean }>().

ServicePicker Component

  • refreshServices() now verifies the currently selected model still exists in the newly loaded services.
  • If the selected service is missing, the component sets model to the first available service id or null when none exist (avoids stale selections).
  • This replaces the prior behavior that only initialized model when falsy.

Dashboard Page

  • Enabled selection persistence for the dashboard by passing remember-selection to project-group-picker.
  • Fixed dashboard selection reset during initial paginated load by adjusting picker fallback behavior.
  • Reformatted the component invocation for readability.

Workspace Creation Pages (blank.vue, file.vue, tdei.vue)

  • Replaced nested-label usage with explicit label-for-id associations to prevent labels returning focus to the picker's input.
  • Each page now uses a dedicated container (<div class="mb-3">) with:
    • <label for="...">
    • project-group-picker with corresponding id prop
    • Removed direct label wrapping of the picker.

TDEI Export Page (pages/workspace/[id]/export/tdei.vue)

  • Restructured template to use an explicit <label for="export_tdei_project_group"> and project-group-picker id="export_tdei_project_group", removing the previous nested-label pattern.
  • Wrapped fetched workspace result in a reactive workspace object (via reactive(...)) so export-page workspace state is reactive.
  • Reconciled export flow to ensure ServicePicker refreshes correctly after project group changes: avoid unnecessary remounts (commit removes a previous :key="workspace.tdeiProjectGroupId"), preserve picker internal state, reconcile stale selected service ids, and clear selection when no services exist.

Files touched

  • components/ProjectGroupPicker.vue
  • components/ServicePicker.vue
  • pages/dashboard.vue
  • pages/workspace/create/blank.vue
  • pages/workspace/create/file.vue
  • pages/workspace/create/tdei.vue
  • pages/workspace/[id]/export/tdei.vue

Impact

  • Fixes the bug where ProjectGroupPicker reopened immediately after selection on non-dashboard pages by making persistence opt-in and removing nested label focus behavior.
  • Ensures dashboard-only persistence scope.
  • Prevents stale service selections and unnecessary remounts in the export flow.
  • Improves accessibility and corrects header text for static option lists.

Tests / Coverage

  • Manual/test cases noted: immediate close behavior on create/export pages, dashboard persistence scoping, ServicePicker refresh and fallback, header text for static options, and regressions for v-model, input display, and keyboard/focus behavior.

Review Change Stack

Expose an optional id prop on ProjectGroupPicker and bind it to the internal input. Update usages across dashboard and workspace create/export pages to pass unique ids and restructure markup so labels use for="..." (replacing implicit label-wrapping with explicit labels and container divs). This improves accessibility by ensuring labels are correctly associated with the picker inputs; no functional behavior changes.
Introduce a rememberSelection prop to ProjectGroupPicker (default false) to control persisting and showing cached project-group names. Update scroll hint logic (showScrollHint computed) and related class bindings. Only persist/load cached names when rememberSelection is enabled and refine selection initialization when options are passed. Fix ServicePicker selection logic to keep the current service if it still exists, otherwise pick the first or null. Wire remember-selection in dashboard, add a :key to the service-picker in the TDEI exporter, and make the fetched workspace reactive to ensure proper updates.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 49d7c09d-7dc6-4d7d-8f6e-a8c680dd0cf7

📥 Commits

Reviewing files that changed from the base of the PR and between dc9132e and cfa0bc3.

📒 Files selected for processing (1)
  • pages/workspace/[id]/export/tdei.vue
💤 Files with no reviewable changes (1)
  • pages/workspace/[id]/export/tdei.vue

📝 Walkthrough

Walkthrough

ProjectGroupPicker adds optional id and rememberSelection props, a new showScrollHint computed, and conditional session persistence. ServicePicker validates selections on refresh. Dashboard and workspace pages update picker markup to use explicit label for/id associations.

Changes

ProjectGroupPicker Enhancement and Page Integration

Layer / File(s) Summary
ProjectGroupPicker props and template binding
components/ProjectGroupPicker.vue
Props extended with optional id and rememberSelection (default false); root input now binds :id="props.id".
ProjectGroupPicker scroll-hint computed and UI
components/ProjectGroupPicker.vue
Added showScrollHint computed; template branches and dropdown wrapper classes now use showScrollHint instead of hasMore.
ProjectGroupPicker rememberSelection conditional persistence
components/ProjectGroupPicker.vue
Session-storage persistence during API-loaded group fetching, UI selection, watcher init, and onMounted fallback now only occur when props.rememberSelection is true.
ServicePicker model validation on refresh
components/ServicePicker.vue
refreshServices() now checks whether the current model.value exists in the refreshed services; if missing, assigns the first service id or null.
Dashboard project-group-picker persistence
pages/dashboard.vue
Dashboard project-group-picker now includes remember-selection and is reformatted to multiline markup.
Page template accessibility refactoring
pages/workspace/[id]/export/tdei.vue, pages/workspace/create/blank.vue, pages/workspace/create/file.vue, pages/workspace/create/tdei.vue
Refactor project-group-picker markup to use explicit label for / picker id associations and dedicated wrapper divs; TDEI export wraps fetched workspace data with reactive().

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • jeffmaki
  • cyrossignol

Poem

🐰 I tuck a choice into session's fold,

ids for labels, tidy and bold—
scroll hints whisper, services check in,
pick once, persist (or not) — where to begin?
hops of code, a small celebratory grin.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main objective: fixing a ProjectGroupPicker reopening issue on non-dashboard pages through accessibility improvements and persistence scoping.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

@shweta2101 shweta2101 requested a review from cyrossignol May 20, 2026 15:28
Copy link
Copy Markdown
Collaborator

@cyrossignol cyrossignol left a comment

Choose a reason for hiding this comment

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

Looks pretty good. Thanks for addressing some issues from the rebase of the roles branch. Just one question...

Comment thread pages/workspace/[id]/export/tdei.vue Outdated
Remove the :key="workspace.tdeiProjectGroupId" binding from the service-picker in pages/workspace/[id]/export/tdei.vue. This prevents unnecessary component remounts when the project group id changes, preserving the picker's internal state and avoiding re-initialization or UI flicker.
@cyrossignol cyrossignol merged commit d41aec5 into master May 22, 2026
1 of 2 checks passed
@cyrossignol cyrossignol deleted the bugfix-3672-project-picker-close-issue branch May 22, 2026 01:03
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