Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
} from "../data-fields/models/data-field-portal-data-injection-token";
import {MultichoiceField} from "../data-fields/multichoice-field/models/multichoice-field";
import {EnumerationField} from "../data-fields/enumeration-field/models/enumeration-field";
import {SelectionBehavior} from '../panel/configuration/selection-behavior';

@Component({
selector: 'ncc-abstract-header',
Expand All @@ -35,7 +36,7 @@ export abstract class AbstractHeaderComponent implements OnInit, OnDestroy {
@Input() showSortButton = true;
@Input() showSearchButton = true;
@Input() showTableSection = true;
@Input() public approval: boolean;
@Input() public showSelection: SelectionBehavior = SelectionBehavior.HIDDEN;

public headerService: AbstractHeaderService;
protected _headerSearch: HeaderSearchService;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Component, Input} from '@angular/core';
import {FormControl} from '@angular/forms';
import { SelectionBehavior } from "../../panel/configuration/selection-behavior";

@Component({
selector: 'ncc-abstract-header-mode',
Expand All @@ -8,15 +9,23 @@ import {FormControl} from '@angular/forms';
export abstract class AbstractHeaderModeComponent {

@Input() public overflowWidth: string;
@Input() public approval: boolean;
@Input() public indeterminate: boolean;
@Input() public approvalFormControl: FormControl;
@Input() public typeApproval: string;
@Input() public showSelection: SelectionBehavior = SelectionBehavior.HIDDEN;

constructor() {
}

getMinWidth() {
return this.overflowWidth;
}

public isInSelectionMode(): boolean {
return this.showSelection !== SelectionBehavior.HIDDEN;
}

public isSelectionDisabled(): boolean {
return this.showSelection !== SelectionBehavior.EDITABLE;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component, Input, Optional} from '@angular/core';
import {Component,Input,Optional} from '@angular/core';
import {Observable} from 'rxjs';
import {Case} from '../../resources/interface/case';
import {toMoment} from '../../resources/types/nae-date-type';
Expand All @@ -21,6 +21,7 @@ import {CurrencyPipe} from '@angular/common';
import {PermissionService} from '../../authorization/permission/permission.service';
import {PermissionType} from '../../process/permissions';
import {FormControl} from '@angular/forms';
import {SelectionBehavior} from '../configuration/selection-behavior';

@Component({
selector: 'ncc-abstract-case-panel',
Expand All @@ -30,14 +31,14 @@ export abstract class AbstractCasePanelComponent extends AbstractPanelWithImmedi


@Input() public case_: Case;
@Input() public approval: boolean;
@Input() public selectedHeaders$: Observable<Array<HeaderColumn>>;
@Input() responsiveBody = true;
@Input() first: boolean;
@Input() last: boolean;
@Input() showCasePanelIcon = true;
@Input() showDeleteMenu = false;
@Input() textEllipsis = false;
@Input() public showSelection: SelectionBehavior = SelectionBehavior.HIDDEN;
protected _approvalFormControl: FormControl;

protected constructor(protected _caseResourceService: CaseResourceService,
Expand All @@ -48,7 +49,7 @@ export abstract class AbstractCasePanelComponent extends AbstractPanelWithImmedi
protected _userService: UserService,
protected _currencyPipe: CurrencyPipe,
protected _permissionService: PermissionService,
@Optional() protected _overflowService: OverflowService,) {
@Optional() protected _overflowService: OverflowService) {
super(_translateService, _currencyPipe, _overflowService);
this._approvalFormControl = new FormControl();
}
Expand Down Expand Up @@ -113,4 +114,12 @@ export abstract class AbstractCasePanelComponent extends AbstractPanelWithImmedi
public getMinWidth() {
return (this._overflowService && this._overflowService.overflowMode) ? `${this._overflowService.columnWidth}px` : '0';
}

public isInSelectionMode(): boolean {
return this.showSelection !== SelectionBehavior.HIDDEN;
}

public isSelectionDisabled(): boolean {
return this.showSelection !== SelectionBehavior.EDITABLE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export enum SelectionBehavior {
EDITABLE,
VISIBLE,
HIDDEN
}
Comment on lines +1 to +5
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider using string enum values.

Numeric enums reverse-map and serialize as integers, which makes logs and any persisted/config representation harder to read (e.g., 0 vs "EDITABLE"). Since this enum is part of the public API and likely to appear in template-facing inputs, string values are easier to debug and safer to refactor (no accidental positional dependency).

♻️ Proposed change
 export enum SelectionBehavior {
-    EDITABLE,
-    VISIBLE,
-    HIDDEN
+    EDITABLE = 'EDITABLE',
+    VISIBLE = 'VISIBLE',
+    HIDDEN = 'HIDDEN'
 }
📝 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
export enum SelectionBehavior {
EDITABLE,
VISIBLE,
HIDDEN
}
export enum SelectionBehavior {
EDITABLE = 'EDITABLE',
VISIBLE = 'VISIBLE',
HIDDEN = 'HIDDEN'
}
🤖 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/configuration/selection-behavior.ts`
around lines 1 - 5, Replace the numeric enum with a string-based enum for
SelectionBehavior so values serialize and log as readable names; update the enum
declaration SelectionBehavior { EDITABLE = "EDITABLE", VISIBLE = "VISIBLE",
HIDDEN = "HIDDEN" } and then adjust any places that compare or persist these
values (references to SelectionBehavior, usages in templates, inputs,
serialization/deserialization code) to expect and handle string values instead
of numeric indexes to avoid reverse-mapping surprises.

Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export * from './task-panel/models/task-panel-context';

/* ENUM */
export * from './configuration/config-params';
export * from './configuration/selection-behavior';
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {MatExpansionPanel} from '@angular/material/expansion';
import {ActivatedRoute} from '@angular/router';
import {filter} from 'rxjs/operators';
import {filter, takeUntil} from 'rxjs/operators';
import {TabbedVirtualScrollComponent} from '../../abstract/tabbed-virtual-scroll.component';
import {AfterViewInit, Component, EventEmitter, Inject, Input, OnDestroy, Optional, Output} from '@angular/core';
import {Observable, Subject, Subscription} from 'rxjs';
Expand All @@ -12,13 +12,11 @@ import {LoggerService} from '../../../logger/services/logger.service';
import {NAE_TAB_DATA} from '../../../tabs/tab-data-injection-token/tab-data-injection-token';
import {InjectedTabData} from '../../../tabs/interfaces';


@Component({
selector: 'ncc-abstract-default-task-list',
template: ''
})
export abstract class AbstractDefaultTaskListComponent extends TabbedVirtualScrollComponent implements AfterViewInit, OnDestroy {

protected _tasks$: Observable<Array<TaskPanelData>>;
protected _redirectTaskId: string;
protected _unsubscribe$: Subject<void>;
Expand All @@ -30,6 +28,7 @@ export abstract class AbstractDefaultTaskListComponent extends TabbedVirtualScro
@Input() forceLoadDataOnOpen = false;
@Input() textEllipsis = false;
@Input() showMoreMenu: boolean = true;
@Input() public disabled: boolean = false;

@Input()
set allowMultiOpen(bool: boolean) {
Expand Down Expand Up @@ -57,15 +56,15 @@ export abstract class AbstractDefaultTaskListComponent extends TabbedVirtualScro
this._taskPanelRefs = new Map<string, MatExpansionPanel>();
this._unsubscribe$ = new Subject<void>();
if (injectedTabData !== null) {
this._unsub = injectedTabData.tabSelected$.pipe(
filter(bool => bool)
).subscribe( () => {
if (this._canReload) {
this._taskViewService.reloadCurrentPage();
} else {
this._canReload = true;
}
});
this._unsub = injectedTabData.tabSelected$
.pipe(filter(bool => bool))
.subscribe(() => {
if (this._canReload) {
this._taskViewService.reloadCurrentPage();
} else {
this._canReload = true;
}
});
}
}

Expand Down Expand Up @@ -99,16 +98,22 @@ export abstract class AbstractDefaultTaskListComponent extends TabbedVirtualScro
}

public onRedirect() {
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();
}
if (!this.route) {
return;
}
this.route.queryParams
.pipe(filter(pm => !!pm['taskId']), takeUntil(this._unsubscribe$))
.subscribe(pm => {
this._redirectTaskId = pm['taskId'];
this._tasks$.pipe(takeUntil(this._unsubscribe$)).subscribe(tasks => {
const task = tasks.find(t => t.task.stringId === this._redirectTaskId);
const panelRef = this._taskPanelRefs.get(this._redirectTaskId);
if (!!task && !task.initiallyExpanded && !!panelRef) {
panelRef.open();
panelRef.expanded = true;
this._unsubscribe$.next();
}
});
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export abstract class AbstractTaskPanelComponent extends AbstractPanelWithImmedi
@Input() actionRowJustifyContent: 'space-between' | 'flex-start' | 'flex-end' | 'center' | 'space-around' |
'initial' | 'start' | 'end' | 'left' | 'right' | 'revert' | 'inherit' | 'unset'
@Input() showMoreMenu: boolean = true;
@Input() public disabled: boolean = false;

thisContext: TaskPanelContext = {
canAssign: () => this.canAssign(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ export abstract class AbstractCaseListPaginatorComponent extends AbstractDefault
public pageSize = 20;
public pageIndex = 0;
public pageSizeOptions: number[] = [10, 20, 50, 100];
@Input() public approval: boolean;
@Input() public disabled: boolean;

constructor(protected _caseViewService: CaseViewService,
protected _log: LoggerService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {InjectedTabData} from '../../../../tabs/interfaces';
import {ActivatedRoute} from '@angular/router';
import {filter, takeUntil} from 'rxjs/operators';
import {TabbedVirtualScrollComponent} from '../../../../panel/abstract/tabbed-virtual-scroll.component';
import {SelectionBehavior} from '../../../../panel/configuration/selection-behavior';

@Component({
selector: 'ncc-abstract-default-case-list',
Expand All @@ -24,6 +25,7 @@ export abstract class AbstractDefaultCaseListComponent extends TabbedVirtualScro
@Input() textEllipsis = false;
@Input() width: string;
@Input() redirectEnabled = true;
@Input() public showSelection: SelectionBehavior = SelectionBehavior.HIDDEN;

public cases$: Observable<Array<Case>>;
public loading$: Observable<boolean>;
Expand Down Expand Up @@ -84,4 +86,8 @@ export abstract class AbstractDefaultCaseListComponent extends TabbedVirtualScro
});
});
}

public isSelectionDisabled(): boolean {
return this.showSelection !== SelectionBehavior.EDITABLE;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<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>
<mat-icon *ngIf="approval && typeApproval === 'enumeration'" color="warn" (click)="setValue();$event.stopPropagation();" class="checkbox-padding cursor-fix">close</mat-icon>
<mat-checkbox *ngIf="isInSelectionMode() && typeApproval === 'multichoice'" [formControl]="approvalFormControl" [indeterminate]="indeterminate"
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding" [disabled]="isSelectionDisabled()"></mat-checkbox>
<button *ngIf="isInSelectionMode() && typeApproval === 'enumeration'" mat-icon-button type="button" aria-label="Clear selected"
class="checkbox-padding cursor-fix" [disabled]="isSelectionDisabled()" (click)="setValue(); $event.stopPropagation();" [disableRipple]="true">
<mat-icon color="warn">close</mat-icon>
</button>
<mat-form-field *ngFor="let header of this.headerService.selectedHeaders$ | async; let i = index" fxLayout="row"
fxLayoutAlign=" center" fxFlex [ngStyle]="{'min-width': getMinWidth()}" appearance="outline"
[fxHide.lt-xl]="i >= 4 && this.headerService.responsiveHeaders && !this.headerService.overflowMode"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<div fxFlex="100" fxLayout="row" fxLayoutAlign=" center">
<mat-checkbox *ngIf="approval && typeApproval === 'multichoice'" [formControl]="approvalFormControl" [indeterminate]="indeterminate"
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding"></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="isInSelectionMode() && typeApproval === 'multichoice'" [formControl]="approvalFormControl" [indeterminate]="indeterminate"
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding" [disabled]="isSelectionDisabled()"></mat-checkbox>
<button *ngIf="isInSelectionMode() && typeApproval === 'enumeration'" mat-icon-button type="button" aria-label="Clear selected"
class="checkbox-padding cursor-fix" [disabled]="isSelectionDisabled()" (click)="setValue(); $event.stopPropagation();" [disableRipple]="true">
<mat-icon color="warn">close</mat-icon>
</button>
<div *ngFor="let header of this.headerService.selectedHeaders$ | async; let i = index"
[fxHide.lt-xl]="i >= 4 && this.headerService.responsiveHeaders && !this.headerService.overflowMode"
[fxHide.lt-lg]="i >= 3 && this.headerService.responsiveHeaders && !this.headerService.overflowMode"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<div matSort (matSortChange)="sortHeaderChanged($event)" fxFlex="100" fxLayout="row" fxLayoutAlign=" center">
<mat-checkbox *ngIf="approval && typeApproval === 'multichoice'" [formControl]="approvalFormControl" [indeterminate]="indeterminate"
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding"></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="isInSelectionMode() && typeApproval === 'multichoice'" [formControl]="approvalFormControl" [indeterminate]="indeterminate"
(click)="$event.stopPropagation();" color='primary' class="checkbox-padding" [disabled]="isSelectionDisabled()"></mat-checkbox>
<button *ngIf="isInSelectionMode() && typeApproval === 'enumeration'" mat-icon-button type="button" aria-label="Clear selected"
class="checkbox-padding cursor-fix" [disabled]="isSelectionDisabled()" (click)="setValue(); $event.stopPropagation();" [disableRipple]="true">
<mat-icon color="warn">close</mat-icon>
</button>
<div [ngStyle]="{'min-width': getMinWidth()}" *ngFor="let header of headerService.headerState.selectedHeaders$ | async; let i = index" fxFlex
[fxHide.lt-xl]="i >= 4 && this.headerService.responsiveHeaders && !this.headerService.overflowMode"
[fxHide.lt-lg]="i >= 3 && this.headerService.responsiveHeaders && !this.headerService.overflowMode"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,26 @@
[overflowWidth]="getMinWidth()"
[approvalFormControl]="approvalFormControl"
[indeterminate]="indeterminate()"
[approval]="approval"
[typeApproval]="typeApproval()"
[showSelection]="showSelection"
></nc-sort-mode>
</div>
<div *ngSwitchCase="headerModeEnum.SEARCH" fxFlex="100" fxLayout="row">
<nc-search-mode fxFlex="100" [headerService]="headerService"
[overflowWidth]="getMinWidth()"
[approvalFormControl]="approvalFormControl"
[indeterminate]="indeterminate()"
[approval]="approval"
[typeApproval]="typeApproval()"
[showSelection]="showSelection"
></nc-search-mode>
</div>
<div *ngSwitchCase="headerModeEnum.EDIT" fxFlex="100" fxLayout="row">
<nc-edit-mode fxFlex="100" [headerService]="headerService"
[overflowWidth]="getMinWidth()"
[approvalFormControl]="approvalFormControl"
[indeterminate]="indeterminate()"
[approval]="approval"
[typeApproval]="typeApproval()"
[showSelection]="showSelection"
></nc-edit-mode>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

<div class="full-height transform-div custom-scrollbar" [ngClass]="{'overflow-div': getOverflowStatus()}" fxLayout="column" fxLayoutAlign="start stretch">
<div class="full-height transform-div max-width-fix" fxLayout="column" fxLayoutAlign="start stretch">
<nc-header #header [type]="headerType" [responsiveHeaders]="true" class="case-header-padding" [ngStyle]="{'width': getWidth()}" [approval]="isApproval()"></nc-header>
<nc-header #header [type]="headerType" [responsiveHeaders]="true" class="case-header-padding" [ngStyle]="{'width': getWidth()}" [showSelection]="resolveSelectionBehavior()"></nc-header>

<nc-case-list-paginator [selectedHeaders$]="selectedHeaders$" [showDeleteMenu]="false" [width]="getWidth()" [approval]="isApproval()" [disabled]="disabled()"
<nc-case-list-paginator [selectedHeaders$]="selectedHeaders$" [showDeleteMenu]="false" [width]="getWidth()" [showSelection]="resolveSelectionBehavior()"
(caseClick)="handleCaseClick($event)" [responsiveBody]="true" fxFlex [textEllipsis]="true"></nc-case-list-paginator>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,16 @@ import {
SavedFilterMetadata,
SearchMode,
SearchService,
SelectionBehavior,
SimpleFilter,
TaskSetDataRequestFields,
ViewIdService
} from '@netgrif/components-core';
import {HeaderComponent} from '../../../../../header/header.component'
import {HeaderComponent} from '../../../../../header/header.component';
import {DefaultTabbedTaskViewComponent} from '../../tabbed/default-tabbed-task-view/default-tabbed-task-view.component';
import {
InjectedTabbedTaskViewDataWithNavigationItemTaskData
} from "../../model/injected-tabbed-task-view-data-with-navigation-item-task-data";
} from '../../model/injected-tabbed-task-view-data-with-navigation-item-task-data';

const localAllowedNetsFactory = (factory: AllowedNetsServiceFactory) => {
return factory.createWithAllNets();
Expand Down Expand Up @@ -87,7 +88,7 @@ export class DefaultCaseRefListViewComponent extends AbstractCaseViewComponent i
return;
}
if (this._baseFilter.filter instanceof Filter) {
this.initFilter = this._baseFilter.filter
this.initFilter = this._baseFilter.filter;
} else {
this._baseFilter.filter.subscribe(observableFilter => {
this.initFilter = observableFilter;
Expand All @@ -99,16 +100,30 @@ export class DefaultCaseRefListViewComponent extends AbstractCaseViewComponent i
this.initializeHeader(this.caseHeaderComponent);
}

public isApproval() {
return this._dataFieldPortalData?.dataField instanceof MultichoiceField || this._dataFieldPortalData?.dataField instanceof EnumerationField;
}

public handleCaseClick(clickedCase: Case): void {
if (this._injectedTabData !== null) {
this.openTab(clickedCase);
}
}

public resolveSelectionBehavior(): SelectionBehavior {
if (!this.isApproval()) {
return SelectionBehavior.HIDDEN;
}

if (this.disabled()) {
return SelectionBehavior.VISIBLE;
}
return SelectionBehavior.EDITABLE;
}

public isApproval() {
return (
this._dataFieldPortalData?.dataField instanceof MultichoiceField ||
this._dataFieldPortalData?.dataField instanceof EnumerationField
);
}

public disabled(): boolean {
return this._dataFieldPortalData?.dataField?.formControlRef.disabled;
}
Expand Down
Loading
Loading