Skip to content

[NAE-2394] - Fields looks editable when switching tabs#318

Open
Kovy95 wants to merge 1 commit intorelease/6.4.2from
NAE-2394
Open

[NAE-2394] - Fields looks editable when switching tabs#318
Kovy95 wants to merge 1 commit intorelease/6.4.2from
NAE-2394

Conversation

@Kovy95
Copy link
Copy Markdown
Contributor

@Kovy95 Kovy95 commented Mar 26, 2026

Description

  • fix problem with fields while switching the tabs, add block fields to get data event

Fixes NAE-2394

Dependencies

none

Third party dependencies

  • No new dependencies were introduced

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 >

Name Tested on
OS LinuxMint 22
Runtime Node 20.18.0
Dependency Manager NPM 10.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

  • Bug Fixes
    • Task panel now properly blocks fields during reload based on user comparison, ensuring correct access control when task data is refreshed.

- fix problem with fields while switching the tabs, add block fields to get data event
@Kovy95 Kovy95 self-assigned this Mar 26, 2026
@Kovy95 Kovy95 added bug Something isn't working breaking change Fix or feature that would cause existing functionality doesn't work as expected bugfix critical Extra Small labels Mar 26, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

Walkthrough

Three component files have been updated to inject a new UserComparatorService dependency and implement user comparison logic during task panel reload. The abstract component now conditionally blocks task fields based on user comparison results before initializing task data.

Changes

Cohort / File(s) Summary
Service Injection
projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.ts, projects/netgrif-components/src/lib/panel/task-panel/task-panel.component.ts
Added UserComparatorService as a new protected constructor dependency in both the abstract and concrete task panel components; updated super() calls to pass the service as an argument.
Test Component Update
projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.spec.ts
Added UserComparatorService import and updated test component constructor to inject the new dependency; realigned subsequent parameter positions in the super() call.
Reload Flow Logic
projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.ts
Modified the tab reload flow to wrap initialization in a call chain, computing taskShouldBeBlocked via user comparison, and conditionally blocking fields before proceeding with task data initialization.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • [NAE-2217] Single Task View #303: Directly modifies AbstractTaskPanelComponent constructor and dependency injection pattern, indicating related service integration work.
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title directly corresponds to the main change: preventing fields from appearing editable when switching tabs by blocking them based on user comparison logic.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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 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

📥 Commits

Reviewing files that changed from the base of the PR and between 28679ae and 851d55c.

📒 Files selected for processing (3)
  • projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.spec.ts
  • projects/netgrif-components-core/src/lib/panel/task-panel/abstract-task-panel.component.ts
  • projects/netgrif-components/src/lib/panel/task-panel/task-panel.component.ts

Comment on lines +219 to +226
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);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ 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.

Comment on lines +148 to 151
protected _userComparator: UserComparatorService,
@Optional() overflowService: OverflowService,
@Optional() @Inject(NAE_TASK_FORCE_OPEN) protected _taskForceOpen: boolean,
@Optional() @Inject(NAE_TAB_DATA) injectedTabData: InjectedTabData) {
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

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.

Comment on lines +200 to +205
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)
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

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.

Suggested change
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.

@sonarqubecloud
Copy link
Copy Markdown

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

Labels

breaking change Fix or feature that would cause existing functionality doesn't work as expected bug Something isn't working bugfix critical Extra Small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants