Skip to content

Conversation

@AlexRubik
Copy link
Contributor

@AlexRubik AlexRubik commented Oct 30, 2025

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-27619

📔 Objective

mvp for assign tasks component which is part of the new applications review flow

📸 Screenshots

27619.mov

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

AlexRubik and others added 21 commits October 28, 2025 17:28
Add reactive observable that filters applicationData for unreviewed apps
(reviewedDate === null). Observable automatically updates when report
state changes through the pipeline.

- Add newApplications$ observable with distinctUntilChanged
- Filters rawReportData$.data.applicationData
- Uses shareReplay for multi-subscriber efficiency

Related to PM-27284
Implement method to save application review status and critical flags.
Updates all applications where reviewedDate === null to set current date,
and marks selected applications as critical.

- Add saveApplicationReviewStatus$() method
- Add _updateReviewStatusAndCriticalFlags() helper
- Uses existing encryption and API update patterns
- Single API call for both review status and critical flags
- Follows same pattern as saveCriticalApplications$()

Related to PM-27284
Expose orchestrator's newApplications$ observable and save method
through RiskInsightsDataService facade. Maintains clean separation
between orchestrator (business logic) and components (UI).

- Expose newApplications$ observable
- Expose saveApplicationReviewStatus() delegation method
- Maintains facade pattern consistency

Related to PM-27284
Update AllActivitiesService to subscribe to orchestrator's newApplications$
observable instead of receiving data through summary updates.

- Subscribe to dataService.newApplications$ in constructor
- Add setNewApplications() helper method
- Remove newApplications update from setAllAppsReportSummary()
- New applications now update reactively when review status changes

Related to PM-27284
Update NewApplicationsDialogComponent to call the data service's
saveApplicationReviewStatus method when marking applications as critical.

- Inject RiskInsightsDataService
- Replace placeholder onMarkAsCritical() with real implementation
- Handle success/error cases with appropriate toast notifications
- Close dialog on successful save
- Show different messages based on whether apps were marked critical

Related to PM-27284
Add internationalization strings for the new applications review dialog
success and error messages.

- applicationReviewSaved: Success toast title
- applicationsMarkedAsCritical: Success message when apps marked critical
- newApplicationsReviewed: Success message when apps reviewed only
- errorSavingReviewStatus: Error toast title
- pleaseTryAgain: Error toast message

Related to PM-27284
Critical fix for production code quality and memory leak prevention.
Adds takeUntil pattern to all subscriptions to comply with ADR-0003
(Observable Data Services) requirements.

**Subscription Cleanup (ADR-0003 Compliance):**
- Add takeUntil pattern to AllActivitiesService subscriptions
- Add _destroy$ Subject and destroy() method
- Prevents memory leaks by properly unsubscribing from observables
- Follows Observable Data Services ADR requirements

Changes:
- Import Subject and takeUntil from rxjs
- Add private _destroy$ Subject for cleanup coordination
- Apply takeUntil(this._destroy$) to all 3 subscriptions:
  - enrichedReportData$ subscription
  - criticalReportResults$ subscription
  - newApplications$ subscription
- Add destroy() method for proper resource cleanup

This ensures proper resource cleanup and follows Bitwarden's
architectural decision records for observable management.

Related to PM-27284
…ivitiesService

Fixes critical memory leak by replacing manual subscription cleanup
with Angular's automatic DestroyRef-based cleanup pattern.

**Changes:**
- Replace `takeUntil(this._destroy$)` with `takeUntilDestroyed()` for all 3 subscriptions
- Remove unused `_destroy$` Subject and manual `destroy()` method
- Update imports to use `@angular/core/rxjs-interop`

**Why:**
- Manual `destroy()` method was never called anywhere in codebase
- Subscriptions accumulated without cleanup, causing memory leaks
- `takeUntilDestroyed()` uses Angular's DestroyRef for automatic cleanup
- Aligns with ADR-0003 and .claude/CLAUDE.md requirements

**Impact:**
- Automatic subscription cleanup when service context is destroyed
- Prevents memory leaks during hot module reloads and route changes
- Reduces code complexity (no manual lifecycle management needed)

Related to PM-27284
Removes redundant newApplications field from summary type and uses
derived newApplications$ observable from orchestrator instead.

**Changes:**
- Remove newApplications from OrganizationReportSummary type definition
- Remove dummy data array from RiskInsightsReportService.getApplicationsSummary()
- Remove newApplications subscription from AllActivitiesService
- Update AllActivityComponent to subscribe directly to dataService.newApplications$

**Why:**
- Eliminates data redundancy (stored vs derived)
- newApplications$ already computes from applicationData.reviewedDate === null
- Single source of truth: applicationData is the source
- Simplifies encrypted payload (less data in summary)
- Better separation: stored data (counts) vs computed data (lists)

**Impact:**
- No functional changes - UI continues to display new applications correctly
- Cleaner architecture with computed observable pattern
Addresses critical PR review issues in NewApplicationsDialogComponent:

**Type Safety:**
- Replace unsafe type casting `(this as any).dialogRef` with proper DialogRef injection
- Inject DialogRef<boolean | undefined> using Angular's inject() function
- Ensures type safety and prevents runtime errors from missing dialogRef

**Error Handling:**
- Add LogService to dialog component
- Log errors with "[NewApplicationsDialog]" for debugging
- Maintain user-facing error toast while adding server-side logging

**Impact:**
- Eliminates TypeScript safety bypasses
- Improves production debugging capabilities
- Follows Angular dependency injection best practices
Create standalone view component for task assignment UI that can be
embedded within dialogs or other containers.

- Add AssignTasksViewComponent with signal-based inputs/outputs
- Use input.required<number>() for selectedApplicationsCount
- Use output<void>() for tasksAssigned and back events
- Implement task calculation using SecurityTasksApiService
- Add onAssignTasks() method with loading state and error handling
- Include task summary card UI matching password-change-metric style
- Add proper subscription cleanup with takeUntilDestroyed (ADR-0003)
- Buttons included in component template (not dialog footer)
- Component retrieves organizationId from route params

Related to PM-27619
…ialog

Add view state const object and properties to support toggling between
application selection and embedded assign tasks component.

- Add DialogView const object with SelectApplications and AssignTasks states (ADR-0025)
- Add DialogView type for type safety
- Add currentView property to track active view
- Import AssignTasksViewComponent for embedded use
- Add isCalculatingTasks loading state
- Inject AllActivitiesService and SecurityTasksApiService for task checking
- Implement OnInit with organizationId retrieval from route params
- Add proper subscription cleanup with takeUntilDestroyed (ADR-0003)
- Expose DialogView constants to template

Related to PM-27619
Implement logic to embed AssignTasksViewComponent within dialog and
handle communication via event bindings.

- Update onMarkAsCritical to check for tasks before closing dialog
- Add checkForTasksToAssign() method using SecurityTasksApiService
- Conditionally transition to AssignTasks view when tasks are available
- Add onTasksAssigned() handler to close dialog after successful assignment
- Add onBack() handler to navigate back to SelectApplications view
- Add loading state guard to prevent double-click on Mark as Critical button
- Only show success toast and close dialog if no tasks to assign

Related to PM-27619
Update dialog template to conditionally render embedded
AssignTasksViewComponent using @if directive.

- Add conditional rendering for SelectApplications and AssignTasks views
- Update dialog title dynamically based on currentView
- Embed dirt-assign-tasks-view component in AssignTasks view
- Pass selectedApplicationsCount via input binding
- Listen to tasksAssigned and back output events
- Show footer buttons only for SelectApplications view
- Add loading and disabled states to Mark as Critical button
- Change Cancel button to not auto-close (user must navigate)

Related to PM-27619
Add localized strings for embedded assign tasks view component.
- Pass organizationId via dialog data to prevent async race conditions
- Pass organizationId as input to AssignTasksViewComponent (embedded components can't access route params)
- Add DefaultAdminTaskService to component providers to fix NullInjectorError
- Remove unnecessary route subscription from embedded component
- Follow password-change-metric.component.ts pattern for consistency
- Add detailed comments explaining architectural decisions and bug fixes
@AlexRubik AlexRubik self-assigned this Oct 30, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Oct 30, 2025

Logo
Checkmarx One – Scan Summary & Details9ed9cdc3-d491-4e8c-bdf1-b1ac37e20a37

New Issues (1)

Checkmarx found the following issues in this Pull Request

Severity Issue Source File / Package Checkmarx Insight
MEDIUM Missing_HSTS_Header /libs/common/src/services/api.service.ts: 198
detailsThe web-application does not define an HSTS header, leaving it vulnerable to attack.
ID: 6sbMocbf6FBC03W0xbXQgzbeSJk%3D
Attack Vector

…portSummary type guard

Removes redundant newApplications field validation from the
OrganizationReportSummary type guard and related test cases.

**Changes:**
- Remove "newApplications" from allowed keys in isOrganizationReportSummary()
- Remove newApplications array validation logic
- Remove newApplications validation from validateOrganizationReportSummary()
- Remove 2 test cases for newApplications validation
- Remove newApplications field from 8 test data objects

**Rationale:**
The newApplications field was removed from OrganizationReportSummary type
definition because it's derived data that can be calculated from
applicationData (filtering where reviewedDate === null). The data is now
accessed via the reactive newApplications$ observable instead of being
stored redundantly in the summary object.

**Impact:**
- No functional changes - UI continues to display new applications via observable
- Type guard now correctly validates the actual OrganizationReportSummary structure
- Eliminates data redundancy and maintains single source of truth
- All 43 tests passing
@codecov
Copy link

codecov bot commented Oct 30, 2025

Codecov Report

❌ Patch coverage is 0.61728% with 161 lines in your changes missing coverage. Please review.
✅ Project coverage is 40.44%. Comparing base (8e1a6a3) to head (32dd082).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...review-dialog/new-applications-dialog.component.ts 0.00% 76 Missing ⚠️
...vices/domain/risk-insights-orchestrator.service.ts 2.38% 41 Missing ⚠️
...eview-dialog/review-applications-view.component.ts 0.00% 23 Missing ⚠️
...ation-review-dialog/assign-tasks-view.component.ts 0.00% 11 Missing ⚠️
...ss-intelligence/activity/all-activity.component.ts 0.00% 7 Missing ⚠️
...sights/services/view/risk-insights-data.service.ts 0.00% 1 Missing ⚠️
.../access-intelligence/access-intelligence.module.ts 0.00% 1 Missing ⚠️
...nce/all-applications/all-applications.component.ts 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #17125      +/-   ##
==========================================
- Coverage   40.48%   40.44%   -0.05%     
==========================================
  Files        3516     3519       +3     
  Lines      100416   100551     +135     
  Branches    15040    15053      +13     
==========================================
+ Hits        40657    40664       +7     
- Misses      58046    58174     +128     
  Partials     1713     1713              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Remove illustration/preview section (mailbox icon and prompt text)
- Show unique member count instead of calculated task count
- Use reportSummary.totalCriticalAtRiskMemberCount from AllActivitiesService
- Remove unused SecurityTasksApiService dependency
- Follow same pattern as all-activity.component.ts for consistency
@AlexRubik AlexRubik changed the title Dirt/pm 27619/assign tasks dialog [PM-27619] assign tasks component Oct 30, 2025
@AlexRubik AlexRubik marked this pull request as ready for review October 30, 2025 17:46
@AlexRubik AlexRubik requested a review from a team as a code owner October 30, 2025 17:46
@bitwarden bitwarden deleted a comment from claude bot Oct 31, 2025
@claude
Copy link

claude bot commented Oct 31, 2025

Code Review: PM-27619 Assign Tasks Component


Summary of Changes Since Last Review

The PR has progressed significantly with commit 1dd92f8f52 addressing previous Claude comments. Key improvements include:

  • Fixed: Set manipulation logic now uses native Set.delete() method (new-applications-dialog.component.ts:137-147)
  • Fixed: Improved distinctUntilChanged comparison logic for applications array (risk-insights-orchestrator.service.ts:114-123)
  • Removed: Dead/commented code cleanup
  • Refactored dialog into multi-view component structure with embedded views
  • Added comprehensive task assignment flow with video demonstrations
  • Enhanced UI with search, bulk select, and improved UX

Critical Issues Found

1. ❌ Missing Unit Tests (risk-insights-orchestrator.service.ts, all dialog components)

Severity: High
Location: All new components in application-review-dialog/

The PR adds 162 lines of untested code (per Codecov report: 0.61728% patch coverage). Specifically:

  • new-applications-dialog.component.ts: 76 lines missing coverage
  • risk-insights-orchestrator.service.ts: 41 lines missing coverage
  • review-applications-view.component.ts: 23 lines missing coverage
  • assign-tasks-view.component.ts: 11 lines missing coverage

Impact: Complex state management logic, multi-step workflows, and RxJS operations are completely untested. This is particularly concerning for:

  • Dialog state transitions (SelectApplications ↔ AssignTasks)
  • Error handling in handleAssignTasks() (new-applications-dialog.component.ts:184-251)
  • Application data merging logic in _updateApplicationData() (risk-insights-orchestrator.service.ts:815-849)

Recommendation: Add unit tests covering:

  • Component state transitions and user interactions
  • Error scenarios in the assign tasks flow
  • Edge cases in selection toggling (empty sets, all selected, partial selection)
  • Service method behavior in _updateApplicationData()

2. ⚠️ Async Race Condition Risk (all-activity.component.ts:132)

Location: all-activity.component.ts:132-148

async onReviewNewApplications() {
  const organizationId = this.activatedRoute.snapshot.paramMap.get("organizationId");
  
  if (!organizationId) {
    return;  // ❌ Silent failure - no user feedback
  }
  
  const dialogRef = NewApplicationsDialogComponent.open(this.dialogService, {
    newApplications: this.newApplications,  // ⚠️ Could be stale if observable emits during this method
    organizationId: organizationId as OrganizationId,
  });
  
  await lastValueFrom(dialogRef.closed);
}

Issues:

  1. Silent failure: When organizationId is missing, the method returns without notifying the user or logging the error
  2. Stale data risk: this.newApplications is populated via subscription (line 82-88). If the observable emits while this method executes, the dialog receives stale data
  3. Type assertion: Casting organizationId to OrganizationId bypasses type safety

Recommendations:

async onReviewNewApplications() {
  const organizationId = this.activatedRoute.snapshot.paramMap.get("organizationId");
  
  if (!organizationId) {
    this.logService.error("[AllActivityComponent] Missing organizationId");
    this.toastService.showToast({
      variant: "error",
      title: this.i18nService.t("error"),
      message: this.i18nService.t("organizationIdMissing"),
    });
    return;
  }
  
  // Get latest data from observable instead of relying on component property
  const newApplications = await firstValueFrom(this.dataService.newApplications$);
  
  const dialogRef = NewApplicationsDialogComponent.open(this.dialogService, {
    newApplications,
    organizationId: organizationId as OrganizationId,
  });
  
  await lastValueFrom(dialogRef.closed);
}

3. 🤔 Inconsistent Array Comparison Logic (risk-insights-orchestrator.service.ts:114-123)

Location: risk-insights-orchestrator.service.ts:114-123

distinctUntilChanged((prev, curr) => {
  if (prev.length !== curr.length) {
    return false;
  }
  return prev.every(
    (app, i) =>
      app.applicationName === curr[i].applicationName &&
      app.atRiskPasswordCount === curr[i].atRiskPasswordCount,  // Only checks 2 fields
  );
})

Issue: The comparison only checks applicationName and atRiskPasswordCount, but ApplicationHealthReportDetail contains many more fields:

  • passwordCount
  • atRiskMemberCount
  • atRiskMemberDetails[]
  • etc.

Impact: If other fields change (e.g., passwordCount, atRiskMemberCount), the observable won't emit, potentially showing stale data in the UI.

Recommendation: Either:

  1. Document why only these two fields matter for change detection
  2. Or expand comparison to include other relevant fields:
distinctUntilChanged((prev, curr) => {
  if (prev.length !== curr.length) return false;
  return prev.every((app, i) =>
    app.applicationName === curr[i].applicationName &&
    app.atRiskPasswordCount === curr[i].atRiskPasswordCount &&
    app.passwordCount === curr[i].passwordCount &&
    app.atRiskMemberCount === curr[i].atRiskMemberCount
  );
})

4. ⚠️ Nullable Coercion in Update Logic (risk-insights-orchestrator.service.ts:835-836)

Location: risk-insights-orchestrator.service.ts:835-836

return {
  applicationName: app.applicationName,
  isCritical: foundApp?.isCritical || app.isCritical,  // ⚠️ Problematic for falsy values
  reviewedDate: foundApp?.reviewedDate || app.reviewedDate,  // ⚠️ Same issue
};

Issue: Using || operator means:

  • If foundApp.isCritical is explicitly false, it falls back to app.isCritical (wrong!)
  • If foundApp.reviewedDate is null or undefined, it falls back to app.reviewedDate (may be intended, but unclear)

Example scenario:

// User unchecks "critical" for an app
foundApp = { applicationName: "App1", isCritical: false, reviewedDate: new Date() }
app = { applicationName: "App1", isCritical: true, reviewedDate: null }

// Result: isCritical becomes TRUE (wrong! should be FALSE)

Recommendation: Use nullish coalescing to preserve explicit false values:

return {
  applicationName: app.applicationName,
  isCritical: foundApp?.isCritical ?? app.isCritical,
  reviewedDate: foundApp?.reviewedDate ?? app.reviewedDate,
};

Suggested Improvements

5. 🎨 Code Duplication in Template (new-applications-dialog.component.html:43-96)

Location: new-applications-dialog.component.html

Button definitions are nearly identical between the two view states. Consider extracting to a shared variable:

// In component
protected readonly footerButtons = computed(() => {
  const view = this.currentView();
  if (view === DialogView.SelectApplications) {
    return {
      primary: { label: 'markAsCritical', action: () => this.handleMarkAsCritical() },
      secondary: { label: 'cancel', action: () => this.handleCancel() }
    };
  }
  return {
    primary: { label: 'assignTasks', action: () => this.handleAssignTasks() },
    secondary: { label: 'back', action: () => this.onBack() }
  };
});

6. 🎨 Component Responsibility Violation (assign-tasks-view.component.ts:39)

Location: assign-tasks-view.component.ts:39

providers: [AccessIntelligenceSecurityTasksService, DefaultAdminTaskService],

Issue: This presentational component provides its own service instances, violating single responsibility principle. The component comment acknowledges this is a workaround for DI issues.

Why this is problematic:

  • Service state is isolated to this component instance
  • Makes testing harder (must mock providers at component level)
  • Violates Angular best practices (services should be provided at module/root level)

Recommendation:

  • Investigate the root cause of the NullInjectorError
  • Provide services at the appropriate level (likely the AccessIntelligenceModule)
  • If component-level providers are truly needed, document the architectural decision

7. 📝 TODO Comment (new-applications-dialog.component.ts:210)

Location: new-applications-dialog.component.ts:210-211

// Manual enrich for type matching
// TODO Consolidate in model updates

This manual enrichment is a code smell suggesting type inconsistencies. Consider:

  • Creating a helper function if this pattern is reused
  • Or consolidating types as the TODO suggests
  • Link to a tracking ticket if this is deferred work

8. ⚠️ Inconsistent Method Declaration Style (all-activity.component.ts:132-156)

Location: all-activity.component.ts:132-156

The commit changed from arrow functions to method declarations inconsistently:

// Changed TO method declaration
async onReviewNewApplications() { }
async onViewAtRiskMembers() { }
async onViewAtRiskApplications() { }

// But elsewhere in file, still uses arrow functions (lines exist elsewhere)

Why this matters: Arrow functions in class fields have different this binding. If some methods use arrow functions and others don't, it creates confusion about which pattern to follow.

Recommendation: Be consistent - either use arrow functions throughout (for template event handlers) or use method declarations. The codebase seems to prefer arrow functions for template-bound methods.


9. 🎨 Magic Number in Template (new-applications-dialog.component.html:36)

Location: new-applications-dialog.component.html:36

[totalApplicationsCount]="this.dialogParams.newApplications.length"

This recalculates length on every change detection cycle. Consider:

protected readonly totalApplicationsCount = computed(() => this.dialogParams.newApplications.length);

10. 📝 Missing Accessibility Labels (review-applications-view.component.html:17,48-51)

Location: review-applications-view.component.html

Good: You have [attr.aria-label] on buttons.
Missing: No aria-describedby or visual text explaining what the star icon means before users interact with the table.

Recommendation: Add a visually-hidden description or aria-describedby linking to the helper text at line 19-21.


Good Practices Observed

  • ADR-0025 compliance: Using const objects instead of enums (DialogView, NewApplicationsDialogResultType)
  • Signal adoption: Appropriate use of Angular Signals for component state
  • OnPush change detection: Main dialog component uses OnPush strategy
  • Internationalization: All UI strings use i18n pipe
  • RxJS best practices: Uses takeUntilDestroyed() for subscription management
  • Error handling: Comprehensive try-catch with user-facing toast notifications
  • Type safety: Good use of TypeScript types for dialog data
  • Accessibility: aria-labels on interactive elements

Action Items for Author

Must Address (Blocking Issues):

  1. Add unit tests for all new components (codecov shows 161 lines missing coverage)
  2. Fix nullable coercion bug in _updateApplicationData() (use ?? instead of ||)
  3. Handle missing organizationId error with user feedback instead of silent return

Should Address (Quality Issues):
4. Review and document distinctUntilChanged field selection logic
5. Resolve component-level service provider workaround
6. Fetch latest newApplications data from observable instead of stale component property

Nice to Have (Improvements):
7. Extract duplicate button logic in template
8. Resolve TODO comment or link to tracking ticket
9. Add computed property for totalApplicationsCount
10. Enhance accessibility with aria-describedby


Questions for Discussion

  1. Video files: As @Banrion noted, the dark theme video (3.5MB) is significantly larger than the light theme video (1.8MB). Was this intentional, or should both be compressed equally?

  2. Service providers: The assign-tasks-view.component provides its own service instances. Is there a plan to resolve this architectural issue?

  3. Test coverage: The PR has <1% patch coverage. What's the testing strategy for this feature? Integration tests? E2E?


Review Context

Previous Issues Tracked:

  • ✅ Set manipulation inefficiency - FIXED in commit 1dd92f8f52
  • ✅ Commented dead code - FIXED (removed)
  • ✅ distinctUntilChanged shallow comparison - PARTIALLY FIXED (now checks specific fields, but see Issue Overlay Popup #3 above)

Commits Since Last Review: 20 commits, most notably:

  • 1dd92f8f52 - Address claude comments
  • 831cf5349c - Add columns, description, search, and bulk select
  • b9c9737601 - Refactor assign tasks dialog
  • eb74aa243a - Add multi-view state management

View job run

@maxkpower maxkpower force-pushed the dirt/pm-27619/assign-tasks-dialog branch from 65a651a to 831cf53 Compare November 3, 2025 01:42
Copy link
Contributor

Choose a reason for hiding this comment

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

🤔 The size difference in these two video files surprise me. Is one compressed or built upon the other somehow?

Copy link
Contributor

Choose a reason for hiding this comment

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

Great catch, one was attached as .mov to the ticket so I converted with ffmpeg. Will check / optimise

},
);

return forkJoin([updateApplicationsCall, updateSummaryCall]).pipe(
Copy link
Contributor

Choose a reason for hiding this comment

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

📝 Update both application and summary with metrics in review status saving

// Updates the existing application data to include critical applications
// Does not remove critical applications not in the set
private _mergeApplicationData(
private _updateApplicationData(
Copy link
Contributor

Choose a reason for hiding this comment

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

📝 Updated to accept new object and update those values specifically. This does not handle removing elements from the array if that were needed, but it does add applications if they didn't exist in the array already.

);
}

getApplications() {
Copy link
Contributor

Choose a reason for hiding this comment

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

📝 Not required. Can be removed during further code cleanup, but not required for accepting

@Banrion Banrion enabled auto-merge (squash) November 3, 2025 15:16
@Banrion Banrion merged commit c6d7596 into main Nov 3, 2025
64 of 65 checks passed
@Banrion Banrion deleted the dirt/pm-27619/assign-tasks-dialog branch November 3, 2025 15:25
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.

5 participants