Skip to content

[NAE-2412] EnumerationMap, MultichoiceMap with 'caseref' component are editable on unassigned task#330

Open
SamuelPalaj wants to merge 3 commits into
release/6.5.0from
NAE-2412
Open

[NAE-2412] EnumerationMap, MultichoiceMap with 'caseref' component are editable on unassigned task#330
SamuelPalaj wants to merge 3 commits into
release/6.5.0from
NAE-2412

Conversation

@SamuelPalaj
Copy link
Copy Markdown
Contributor

@SamuelPalaj SamuelPalaj commented May 19, 2026

Description

  • added disabled property to task ref component
  • fixed behavior of task and case list components on unassigned task

Fixes NAE-2412

How Has Been This Tested?

manualy

Test Configuration

Name Tested on
OS windows 11
Runtime 20.19.0
Dependency Manager npm10.8.2
Framework version Angular 13.3
Run parameters
Other configuration

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My changes have been checked, personally or remotely, with @...
  • I have commented my code, particularly in hard-to-understand areas
  • I have resolved all conflicts with the target branch of the PR
  • I have updated and synced my code with the target branch
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing tests pass locally with my changes:
    • Lint test
    • Unit tests
    • Integration tests
  • I have checked my contribution with code analysis tools:
  • I have made corresponding changes to the documentation:
    • Developer documentation
    • User Guides
    • Migration Guides

Summary by CodeRabbit

  • New Features

    • Added disabled state input property to header and panel components
    • Disabled state now propagates to approval checkboxes, radio buttons, and action buttons in templates
    • Task list pagination components now reflect disabled state based on form control status
  • Bug Fixes

    • Removed redundant disabled input from case list paginator component

Review Change Stack

…e editable on unassigned task

- added disabled property to task ref component
- fixed behavior of task and case list components on unassigned task
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

Walkthrough

The PR extends the component hierarchy to expose a disabled input property on abstract base components and propagates this state through templates to approval controls, action buttons, and child component instances. A special case in DefaultTaskViewComponent injects optional portal data to detect disabled state from an injected form control.

Changes

Component disabled state hierarchy

Layer / File(s) Summary
Abstract component disabled inputs
projects/netgrif-components-core/src/lib/header/abstract-header.component.ts, projects/netgrif-components-core/src/lib/header/header-modes/abstract-header-mode.component.ts, projects/netgrif-components-core/src/lib/panel/case-panel/abstract-case-panel.component.ts, projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.ts, projects/netgrif-components-core/src/lib/panel/task-panel-list/default-task-panel-list/abstract-default-task-list.component.ts, projects/netgrif-components-core/src/lib/view/case-view/components/default-case-list/abstract-default-case-list.component.ts, projects/netgrif-components-core/src/lib/view/case-view/components/case-list-paginator/abstract-case-list-paginator.component.ts
Each abstract header, panel, and list component declares a disabled input property; the case-list-paginator abstract removes its disabled input. Core imports updated to include EventEmitter. AbstractDefaultTaskListComponent class declaration and constructor methods reformatted.
Header disabled state wiring
projects/netgrif-components/src/lib/header/header.component.html, projects/netgrif-components/src/lib/header/header-modes/edit-mode/edit-mode.component.html, projects/netgrif-components/src/lib/header/header-modes/search-mode/search-mode.component.html, projects/netgrif-components/src/lib/header/header-modes/sort-mode/sort-mode.component.html, projects/netgrif-components/src/lib/navigation/group-navigation-component-resolver/default-components/refs/default-case-ref-list-view/default-case-ref-list-view.component.html
Header template passes [disabled]="disabled" to all three mode components; each mode component binds disabled state to its multichoice approval checkbox template. DefaultCaseRefListView passes disabled to header component.
Task view portal data disabled detection
projects/netgrif-components/src/lib/navigation/group-navigation-component-resolver/default-components/refs/default-task-view/default-task-view.component.ts, projects/netgrif-components/src/lib/navigation/group-navigation-component-resolver/default-components/refs/default-task-view/default-task-view.component.html
DefaultTaskViewComponent imports DI helpers and portal-data types, injects optional DATA_FIELD_PORTAL_DATA in constructor, and exposes a disabled() method that reads disabled state from the injected form control. Template passes [disabled]="disabled()" to task pagination component.
Panel disabled propagation to actions and children
projects/netgrif-components/src/lib/panel/case-panel/case-panel.component.html, projects/netgrif-components/src/lib/panel/task-panel/task-panel.component.html, projects/netgrif-components/src/lib/panel/task-panel-list-pagination/task-list-pagination.component.html, projects/netgrif-components/src/lib/view/case-view/components/case-list-paginator/case-list-paginator.component.html, projects/netgrif-components/src/lib/view/case-view/components/case-list/case-list.component.html
CasePanel binds disabled to multichoice and enumeration approval controls; TaskPanel header "more" button and action buttons (assign, delegate, reassign, cancel, finish) bind disabled state; TaskListPagination and CaseList templates pass disabled to child panel components. CaseListPaginator template formatting adjusted.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 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 PR title specifically references NAE-2412 and accurately describes the main issue being fixed: preventing EnumerationMap and MultichoiceMap with caseref components from being editable on unassigned tasks.
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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@projects/netgrif-components-core/src/lib/panel/task-panel-list/default-task-panel-list/abstract-default-task-list.component.ts`:
- Around line 106-122: Guard access to this.route and avoid the nested
subscription: only subscribe if this.route is present (e.g. check this.route !=
null), then replace the inner .subscribe on this._tasks$ with a pipe operator
(use switchMap or map + take(1)) so the tasks stream is consumed once (and add
takeUntil(this._unsubscribe$) on the outer chain to prevent leaks). When
resolving the panel ref, store const panelRef =
this._taskPanelRefs.get(this._redirectTaskId) and null-check it before calling
panelRef.open() or setting panelRef.expanded to avoid crashes if the ref isn't
registered yet; keep using this._unsubscribe$ for teardown.

In
`@projects/netgrif-components/src/lib/header/header-modes/edit-mode/edit-mode.component.html`:
- Around line 2-4: The enumeration control (mat-icon) invokes setValue() even
when the component is disabled; update the click handling to respect the
disabled flag so enumeration approvals aren't editable when disabled. Locate the
mat-icon with (click)="setValue();$event.stopPropagation();" and change its
handler to guard on the disabled property (for example: (click)="disabled ?
$event.stopPropagation() : (setValue(); $event.stopPropagation())") or
alternatively restrict rendering with *ngIf="approval && typeApproval ===
'enumeration' && !disabled" so setValue() is never called when disabled.

In
`@projects/netgrif-components/src/lib/navigation/group-navigation-component-resolver/default-components/refs/default-task-view/default-task-view.component.ts`:
- Around line 60-62: The disabled() method currently returns a possibly
undefined value due to optional chaining; update it so it always returns a
boolean by coercing the optional expression to boolean (e.g. using !! or
Boolean(...) or the nullish coalescing operator with false) when reading
this._dataFieldPortalData?.dataField?.formControlRef.disabled; keep the same
method name disabled and the same properties (_dataFieldPortalData, dataField,
formControlRef) but ensure the final returned value is a boolean.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e510ad99-2e9f-49c2-a2ae-98609372171b

📥 Commits

Reviewing files that changed from the base of the PR and between 5b46f21 and 4d1a638.

📒 Files selected for processing (19)
  • projects/netgrif-components-core/src/lib/header/abstract-header.component.ts
  • projects/netgrif-components-core/src/lib/header/header-modes/abstract-header-mode.component.ts
  • projects/netgrif-components-core/src/lib/panel/case-panel/abstract-case-panel.component.ts
  • projects/netgrif-components-core/src/lib/panel/task-panel-list/default-task-panel-list/abstract-default-task-list.component.ts
  • projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.ts
  • projects/netgrif-components-core/src/lib/view/case-view/components/case-list-paginator/abstract-case-list-paginator.component.ts
  • projects/netgrif-components-core/src/lib/view/case-view/components/default-case-list/abstract-default-case-list.component.ts
  • projects/netgrif-components/src/lib/header/header-modes/edit-mode/edit-mode.component.html
  • projects/netgrif-components/src/lib/header/header-modes/search-mode/search-mode.component.html
  • projects/netgrif-components/src/lib/header/header-modes/sort-mode/sort-mode.component.html
  • projects/netgrif-components/src/lib/header/header.component.html
  • projects/netgrif-components/src/lib/navigation/group-navigation-component-resolver/default-components/refs/default-case-ref-list-view/default-case-ref-list-view.component.html
  • projects/netgrif-components/src/lib/navigation/group-navigation-component-resolver/default-components/refs/default-task-view/default-task-view.component.html
  • projects/netgrif-components/src/lib/navigation/group-navigation-component-resolver/default-components/refs/default-task-view/default-task-view.component.ts
  • projects/netgrif-components/src/lib/panel/case-panel/case-panel.component.html
  • projects/netgrif-components/src/lib/panel/task-panel-list-pagination/task-list-pagination.component.html
  • projects/netgrif-components/src/lib/panel/task-panel/task-panel.component.html
  • projects/netgrif-components/src/lib/view/case-view/components/case-list-paginator/case-list-paginator.component.html
  • projects/netgrif-components/src/lib/view/case-view/components/case-list/case-list.component.html
💤 Files with no reviewable changes (1)
  • projects/netgrif-components-core/src/lib/view/case-view/components/case-list-paginator/abstract-case-list-paginator.component.ts

Comment on lines +106 to 122
this.route.queryParams
.pipe(filter(pm => !!pm["taskId"]))
.subscribe(pm => {
this._redirectTaskId = pm["taskId"];
this._tasks$.pipe().subscribe(tasks => {
const task = tasks.find(
t => t.task.stringId === this._redirectTaskId
);
if (!!task && !task.initiallyExpanded) {
this._taskPanelRefs.get(this._redirectTaskId).open();
this._taskPanelRefs.get(
this._redirectTaskId
).expanded = true;
this._unsubscribe$.next();
}
});
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

find projects -name "abstract-default-task-list.component.ts" -type f

Repository: netgrif/components

Length of output: 189


🏁 Script executed:

wc -l "projects/netgrif-components-core/src/lib/panel/task-panel-list/default-task-panel-list/abstract-default-task-list.component.ts"

Repository: netgrif/components

Length of output: 193


🏁 Script executed:

cat -n "projects/netgrif-components-core/src/lib/panel/task-panel-list/default-task-panel-list/abstract-default-task-list.component.ts"

Repository: netgrif/components

Length of output: 5474


Harden onRedirect() against crashes and leaking subscriptions.

Line 106 directly accesses an optional route without a guard. Line 110 creates a nested _tasks$ subscription without teardown, causing subscription leaks on route changes. Line 115 dereferences _taskPanelRefs.get() without null-checking, which crashes if the panel ref hasn't been registered yet.

Suggested fix
-import {filter} from 'rxjs/operators';
+import {filter, take, takeUntil} from 'rxjs/operators';
...
     public onRedirect() {
+        if (!this.route) {
+            return;
+        }
         this.route.queryParams
-            .pipe(filter(pm => !!pm["taskId"]))
+            .pipe(
+                filter(pm => !!pm['taskId']),
+                takeUntil(this._unsubscribe$)
+            )
             .subscribe(pm => {
-                this._redirectTaskId = pm["taskId"];
-                this._tasks$.pipe().subscribe(tasks => {
+                this._redirectTaskId = pm['taskId'];
+                this._tasks$.pipe(take(1), takeUntil(this._unsubscribe$)).subscribe(tasks => {
                     const task = tasks.find(
                         t => t.task.stringId === this._redirectTaskId
                     );
-                    if (!!task && !task.initiallyExpanded) {
-                        this._taskPanelRefs.get(this._redirectTaskId).open();
-                        this._taskPanelRefs.get(
-                            this._redirectTaskId
-                        ).expanded = true;
+                    const panelRef = this._taskPanelRefs.get(this._redirectTaskId);
+                    if (!!task && !task.initiallyExpanded && !!panelRef) {
+                        panelRef.open();
+                        panelRef.expanded = true;
                         this._unsubscribe$.next();
                     }
                 });
             });
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@projects/netgrif-components-core/src/lib/panel/task-panel-list/default-task-panel-list/abstract-default-task-list.component.ts`
around lines 106 - 122, Guard access to this.route and avoid the nested
subscription: only subscribe if this.route is present (e.g. check this.route !=
null), then replace the inner .subscribe on this._tasks$ with a pipe operator
(use switchMap or map + take(1)) so the tasks stream is consumed once (and add
takeUntil(this._unsubscribe$) on the outer chain to prevent leaks). When
resolving the panel ref, store const panelRef =
this._taskPanelRefs.get(this._redirectTaskId) and null-check it before calling
panelRef.open() or setting panelRef.expanded to avoid crashes if the ref isn't
registered yet; keep using this._unsubscribe$ for teardown.

Comment on lines 2 to 4
<mat-checkbox *ngIf="approval && typeApproval === 'multichoice'" [formControl]="approvalFormControl" [indeterminate]="indeterminate"
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding"></mat-checkbox>
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding" [disabled]="disabled"></mat-checkbox>
<mat-icon *ngIf="approval && typeApproval === 'enumeration'" color="warn" (click)="setValue();$event.stopPropagation();" class="checkbox-padding cursor-fix">close</mat-icon>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

fd "edit-mode.component.html" projects/netgrif-components

Repository: netgrif/components

Length of output: 153


🏁 Script executed:

cat -n projects/netgrif-components/src/lib/header/header-modes/edit-mode/edit-mode.component.html

Repository: netgrif/components

Length of output: 2369


🏁 Script executed:

fd "edit-mode.component.ts" projects/netgrif-components

Repository: netgrif/components

Length of output: 151


🏁 Script executed:

cat -n projects/netgrif-components/src/lib/header/header-modes/edit-mode/edit-mode.component.ts

Repository: netgrif/components

Length of output: 824


🏁 Script executed:

fd "AbstractEditModeComponent" projects/netgrif-components --type f

Repository: netgrif/components

Length of output: 44


🏁 Script executed:

rg "class AbstractEditModeComponent" --type ts -A 30

Repository: netgrif/components

Length of output: 4545


🏁 Script executed:

rg "class AbstractHeaderModeComponent" --type ts -A 50 | head -80

Repository: netgrif/components

Length of output: 1995


🏁 Script executed:

rg "typeApproval.*enumeration" projects/netgrif-components --type ts

Repository: netgrif/components

Length of output: 44


🏁 Script executed:

rg "enumeration" projects/netgrif-components/src/lib/header --type ts -B 2 -A 2

Repository: netgrif/components

Length of output: 44


🏁 Script executed:

git log --oneline projects/netgrif-components/src/lib/header/header-modes/edit-mode/edit-mode.component.html | head -5

Repository: netgrif/components

Length of output: 171


🏁 Script executed:

git show 4d1a638d9 --stat | head -20

Repository: netgrif/components

Length of output: 1059


🏁 Script executed:

git show 4d1a638d9 -- projects/netgrif-components/src/lib/header/header-modes/edit-mode/edit-mode.component.html | head -50

Repository: netgrif/components

Length of output: 2838


Apply disabled behavior to the enumeration approval control.

Line 4 allows setValue() to execute while disabled, making enumeration approvals editable on unassigned tasks. The multichoice checkbox correctly implements [disabled]="disabled", but the enumeration control lacks equivalent protection.

Suggested fix
-    <mat-icon *ngIf="approval && typeApproval === 'enumeration'" color="warn" (click)="setValue();$event.stopPropagation();" class="checkbox-padding cursor-fix">close</mat-icon>
+    <button *ngIf="approval && typeApproval === 'enumeration'"
+            mat-icon-button
+            type="button"
+            class="checkbox-padding cursor-fix"
+            [disabled]="disabled"
+            (click)="!disabled && setValue(); $event.stopPropagation();">
+        <mat-icon color="warn">close</mat-icon>
+    </button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<mat-checkbox *ngIf="approval && typeApproval === 'multichoice'" [formControl]="approvalFormControl" [indeterminate]="indeterminate"
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding"></mat-checkbox>
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding" [disabled]="disabled"></mat-checkbox>
<mat-icon *ngIf="approval && typeApproval === 'enumeration'" color="warn" (click)="setValue();$event.stopPropagation();" class="checkbox-padding cursor-fix">close</mat-icon>
<mat-checkbox *ngIf="approval && typeApproval === 'multichoice'" [formControl]="approvalFormControl" [indeterminate]="indeterminate"
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding" [disabled]="disabled"></mat-checkbox>
<button *ngIf="approval && typeApproval === 'enumeration'"
mat-icon-button
type="button"
class="checkbox-padding cursor-fix"
[disabled]="disabled"
(click)="!disabled && setValue(); $event.stopPropagation();">
<mat-icon color="warn">close</mat-icon>
</button>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@projects/netgrif-components/src/lib/header/header-modes/edit-mode/edit-mode.component.html`
around lines 2 - 4, The enumeration control (mat-icon) invokes setValue() even
when the component is disabled; update the click handling to respect the
disabled flag so enumeration approvals aren't editable when disabled. Locate the
mat-icon with (click)="setValue();$event.stopPropagation();" and change its
handler to guard on the disabled property (for example: (click)="disabled ?
$event.stopPropagation() : (setValue(); $event.stopPropagation())") or
alternatively restrict rendering with *ngIf="approval && typeApproval ===
'enumeration' && !disabled" so setValue() is never called when disabled.

Comment on lines +60 to +62
public disabled(): boolean {
return this._dataFieldPortalData?.dataField?.formControlRef.disabled;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Type mismatch in disabled() return value.

The method declares return type boolean but the optional chaining can return undefined when any part of the chain (_dataFieldPortalData, dataField, formControlRef) is nullish. While Angular templates treat undefined as falsy, this violates the type contract.

🔧 Proposed fix to ensure boolean return type
 public disabled(): boolean {
-    return this._dataFieldPortalData?.dataField?.formControlRef.disabled;
+    return this._dataFieldPortalData?.dataField?.formControlRef.disabled ?? false;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public disabled(): boolean {
return this._dataFieldPortalData?.dataField?.formControlRef.disabled;
}
public disabled(): boolean {
return this._dataFieldPortalData?.dataField?.formControlRef.disabled ?? false;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@projects/netgrif-components/src/lib/navigation/group-navigation-component-resolver/default-components/refs/default-task-view/default-task-view.component.ts`
around lines 60 - 62, The disabled() method currently returns a possibly
undefined value due to optional chaining; update it so it always returns a
boolean by coercing the optional expression to boolean (e.g. using !! or
Boolean(...) or the nullish coalescing operator with false) when reading
this._dataFieldPortalData?.dataField?.formControlRef.disabled; keep the same
method name disabled and the same properties (_dataFieldPortalData, dataField,
formControlRef) but ensure the final returned value is a boolean.

@sonarqubecloud
Copy link
Copy Markdown



@Input() public case_: Case;
@Input() public approval: boolean;
Copy link
Copy Markdown
Contributor

@Kovy95 Kovy95 May 20, 2026

Choose a reason for hiding this comment

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

can we rename all "approval" properties to "showSelection"? it is more intuitive (my bad naming from previous implementation)

change type boolean to ENUM with 3 values - Editable, Visible, Hidden, default value hidden

@Input() showCasePanelIcon = true;
@Input() showDeleteMenu = false;
@Input() textEllipsis = false;
@Input() public disabled: boolean = false;
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.

this is replaced with enu, in previous comment

@Input() public indeterminate: boolean;
@Input() public approvalFormControl: FormControl;
@Input() public typeApproval: string;
@Input() public disabled: boolean = false;
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.

rename approval and rework to enum, and remove this disabled property

@Input() showSearchButton = true;
@Input() showTableSection = true;
@Input() public approval: boolean;
@Input() public disabled: boolean = false;
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.

rename approval and rework to enum, and remove this disabled property

<div fxLayout="row" fxFlex="100" fxLayoutAlign="start center" class="netgrif-input netgrif-header-input netgrif-input-fix netgrif-zero-field-wrapper">
<mat-checkbox *ngIf="approval && typeApproval === 'multichoice'" [formControl]="approvalFormControl" [indeterminate]="indeterminate"
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding"></mat-checkbox>
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding" [disabled]="disabled"></mat-checkbox>
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.

turn of the ripple if you change this to button

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants