[NAE-2394] - Fields looks editable when switching tabs#318
[NAE-2394] - Fields looks editable when switching tabs#318Kovy95 wants to merge 1 commit intorelease/6.4.2from
Conversation
- fix problem with fields while switching the tabs, add block fields to get data event
WalkthroughThree component files have been updated to inject a new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.spec.ts`:
- Around line 219-226: Add a regression spec that injects NAE_TAB_DATA with an
injectedTabData mock exposing tabSelected$ (Subject) and wires the component
under test using the existing constructor/super setup; emit a tabSelected$ event
in the test, stub the GET_DATA response path (the post-GET_DATA callback) to
return task data with blocked fields and set the task editable flag, then assert
the blocked fields remain when _userComparator (UserComparatorService) and
finish permission (finishPolicyService/finishPolicy) indicate success, and
assert the callback forces blocks when _userComparator or finish permission
fails; use spies/mocks on _taskDataService GET/subscribe and on
_userComparator.compare and finishPolicyService.canFinish to drive both success
and failure cases and verify the component’s blocked-field state after the
tabSelected$ emission.
In
`@projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.ts`:
- Around line 148-151: The constructor change in AbstractTaskPanelComponent
added a required _userComparator parameter before existing optional parameters,
breaking positional super(...) calls; restore source-compatibility by moving the
new UserComparatorService parameter to after the existing tail (after
injectedTabData) or obtain the comparator internally (e.g., via injector) so the
public constructor signature (the order of overflowService, _taskForceOpen,
injectedTabData) remains unchanged; update the constructor signature and any use
of _userComparator inside the class accordingly while keeping the original
parameter order for downstream subclasses.
- Around line 200-205: The callback passed to initializeTaskDataFields currently
computes taskShouldBeBlocked and calls
_taskContentService.blockFields(taskShouldBeBlocked), which wipes per-field
block flags; instead, change the logic so you only call
_taskContentService.blockFields(true) when the predicate is true (i.e., task is
missing or user undefined or !_userComparator.compareUsers(...) OR
hasNoFinishPermission()), and do nothing in the false/editable branch so
existing per-field block state from GET_DATA is preserved; update the predicate
to include hasNoFinishPermission() and only invoke blockFields when that
combined predicate is true.
🪄 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: 73424906-33e4-4999-9848-8ee5fcc4078d
📒 Files selected for processing (3)
projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.spec.tsprojects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.tsprojects/netgrif-components/src/lib/panel/task-panel/task-panel.component.ts
| protected _userComparator: UserComparatorService, | ||
| @Optional() overflowService: OverflowService, | ||
| @Optional() @Inject(NAE_TASK_FORCE_OPEN) protected _taskForceOpen: boolean, | ||
| @Optional() @Inject(NAE_TAB_DATA) injectedTabData: InjectedTabData) { | ||
| super(_taskContentService, _log, _taskViewService, _paperView, _taskEventService, _assignTaskService, | ||
| _delegateTaskService, _cancelTaskService, _finishTaskService, _taskState, _taskDataService, | ||
| _assignPolicyService, _finishPolicyService, _callChain, _taskOperations, undefined, _translate, | ||
| _currencyPipe, _changedFieldsService, _permissionService, overflowService, _taskForceOpen, injectedTabData); | ||
| _currencyPipe, _changedFieldsService, _permissionService, _userComparator, overflowService, _taskForceOpen, injectedTabData); |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Add a regression spec for the tabSelected$ reload path.
This hunk only updates the test double wiring. There is still no spec that provides NAE_TAB_DATA, emits tabSelected$, and verifies that the post-GET_DATA callback preserves blocked fields when the task stays editable and forces a block when user comparison or finish permission fails. That is the bugfix path in this PR.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.spec.ts`
around lines 219 - 226, Add a regression spec that injects NAE_TAB_DATA with an
injectedTabData mock exposing tabSelected$ (Subject) and wires the component
under test using the existing constructor/super setup; emit a tabSelected$ event
in the test, stub the GET_DATA response path (the post-GET_DATA callback) to
return task data with blocked fields and set the task editable flag, then assert
the blocked fields remain when _userComparator (UserComparatorService) and
finish permission (finishPolicyService/finishPolicy) indicate success, and
assert the callback forces blocks when _userComparator or finish permission
fails; use spies/mocks on _taskDataService GET/subscribe and on
_userComparator.compare and finishPolicyService.canFinish to drive both success
and failure cases and verify the component’s blocked-field state after the
tabSelected$ emission.
| protected _userComparator: UserComparatorService, | ||
| @Optional() overflowService: OverflowService, | ||
| @Optional() @Inject(NAE_TASK_FORCE_OPEN) protected _taskForceOpen: boolean, | ||
| @Optional() @Inject(NAE_TAB_DATA) injectedTabData: InjectedTabData) { |
There was a problem hiding this comment.
Keep AbstractTaskPanelComponent's constructor source-compatible.
AbstractTaskPanelComponent is exposed from the core package, so this required parameter breaks downstream subclasses even if the in-repo callers were updated. Because it was inserted before overflowService, _taskForceOpen, and injectedTabData, every existing positional super(...) call also shifts. Please preserve the old tail and append any new dependency after it, or resolve the comparator without changing the public constructor shape.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.ts`
around lines 148 - 151, The constructor change in AbstractTaskPanelComponent
added a required _userComparator parameter before existing optional parameters,
breaking positional super(...) calls; restore source-compatibility by moving the
new UserComparatorService parameter to after the existing tail (after
injectedTabData) or obtain the comparator internally (e.g., via injector) so the
public constructor signature (the order of overflowService, _taskForceOpen,
injectedTabData) remains unchanged; update the constructor signature and any use
of _userComparator inside the class accordingly while keeping the original
parameter order for downstream subclasses.
| this._taskDataService.initializeTaskDataFields(this._callChain.create(() => { | ||
| const taskShouldBeBlocked = !this._taskContentService.task | ||
| || this._taskContentService.task.user === undefined | ||
| || !this._userComparator.compareUsers(this._taskContentService.task.user); | ||
| this._taskContentService.blockFields(taskShouldBeBlocked); | ||
| }), true) |
There was a problem hiding this comment.
Don't clear existing block state in the editable branch.
This callback runs after initializeTaskDataFields(), so the task already contains the latest field.block values from GET_DATA. blockFields(taskShouldBeBlocked) overwrites every flag, which means the false branch clears those per-field states and also drops the permission-based block set on Line 244. Only force a global block when the predicate is true, and include hasNoFinishPermission() in that predicate.
💡 Suggested fix
this._taskDataService.initializeTaskDataFields(this._callChain.create(() => {
- const taskShouldBeBlocked = !this._taskContentService.task
- || this._taskContentService.task.user === undefined
- || !this._userComparator.compareUsers(this._taskContentService.task.user);
- this._taskContentService.blockFields(taskShouldBeBlocked);
+ const task = this._taskContentService.task;
+ const taskShouldBeBlocked = this.hasNoFinishPermission()
+ || !task
+ || task.user === undefined
+ || !this._userComparator.compareUsers(task.user);
+ if (taskShouldBeBlocked) {
+ this._taskContentService.blockFields(true);
+ }
}), true)📝 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.
| this._taskDataService.initializeTaskDataFields(this._callChain.create(() => { | |
| const taskShouldBeBlocked = !this._taskContentService.task | |
| || this._taskContentService.task.user === undefined | |
| || !this._userComparator.compareUsers(this._taskContentService.task.user); | |
| this._taskContentService.blockFields(taskShouldBeBlocked); | |
| }), true) | |
| this._taskDataService.initializeTaskDataFields(this._callChain.create(() => { | |
| const task = this._taskContentService.task; | |
| const taskShouldBeBlocked = this.hasNoFinishPermission() | |
| || !task | |
| || task.user === undefined | |
| || !this._userComparator.compareUsers(task.user); | |
| if (taskShouldBeBlocked) { | |
| this._taskContentService.blockFields(true); | |
| } | |
| }), true) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.ts`
around lines 200 - 205, The callback passed to initializeTaskDataFields
currently computes taskShouldBeBlocked and calls
_taskContentService.blockFields(taskShouldBeBlocked), which wipes per-field
block flags; instead, change the logic so you only call
_taskContentService.blockFields(true) when the predicate is true (i.e., task is
missing or user undefined or !_userComparator.compareUsers(...) OR
hasNoFinishPermission()), and do nothing in the false/editable branch so
existing per-field block state from GET_DATA is preserved; update the predicate
to include hasNoFinishPermission() and only invoke blockFields when that
combined predicate is true.
|



Description
Fixes NAE-2394
Dependencies
none
Third party dependencies
Blocking Pull requests
There are no dependencies on other PR
How Has Been This Tested?
manually
Test Configuration
<Please describe configuration for tests to run if applicable, like program parameters, host OS, VM configuration etc. You can use >
Checklist:
Summary by CodeRabbit