[ACS-7366] fix infinite re-rendering (#3739)

This commit is contained in:
Mykyta Maliarchuk
2024-03-28 13:01:05 +01:00
committed by GitHub
parent e283b50ef0
commit b4dc7be2ad
6 changed files with 38 additions and 22 deletions

View File

@@ -60,7 +60,7 @@
<div class="aca-manage-rules__container" *ngIf="isMainRuleSetNotEmpty || isInheritedRuleSetsNotEmpty; else emptyContent"> <div class="aca-manage-rules__container" *ngIf="isMainRuleSetNotEmpty || isInheritedRuleSetsNotEmpty; else emptyContent">
<aca-rule-list <aca-rule-list
[mainRuleSet]="mainRuleSet$ | async" [mainRuleSet$]="mainRuleSet$"
[folderId]="nodeId" [folderId]="nodeId"
[inheritedRuleSets]="inheritedRuleSets$ | async" [inheritedRuleSets]="inheritedRuleSets$ | async"
[hasMoreRuleSets]="hasMoreRuleSets$ | async" [hasMoreRuleSets]="hasMoreRuleSets$ | async"

View File

@@ -211,7 +211,8 @@ export class ManageRulesSmartComponent implements OnInit, OnDestroy {
} }
async onRuleEnabledToggle(rule: Rule, isEnabled: boolean) { async onRuleEnabledToggle(rule: Rule, isEnabled: boolean) {
await this.folderRulesService.updateRule(this.nodeId, rule.id, { ...rule, isEnabled }); const updatedRule = await this.folderRulesService.updateRule(this.nodeId, rule.id, { ...rule, isEnabled });
this.folderRuleSetsService.addOrUpdateRuleInMainRuleSet(updatedRule);
} }
async onInheritanceToggleChange(event: MatSlideToggleChange) { async onInheritanceToggleChange(event: MatSlideToggleChange) {

View File

@@ -80,7 +80,7 @@
<ng-template #emptyLinkedRuleSet> <ng-template #emptyLinkedRuleSet>
<div class="aca-rule-list__item__all-linked-rules-are-disabled"> <div class="aca-rule-list__item__all-linked-rules-are-disabled">
{{ 'ACA_FOLDER_RULES.RULE_LIST.ALL_LINKED_RULES_ARE_DISABLED' | translate }} {{ 'ACA_FOLDER_RULES.RULE_LIST.ALL_LINKED_RULES_ARE_DISABLED' | translate }}
<button mat-stroked-button [routerLink]="['/nodes', mainRuleSet.owningFolder.id, 'rules']"> <button *ngIf="mainRuleSet?.owningFolder?.id" mat-stroked-button [routerLink]="['/nodes', mainRuleSet.owningFolder.id, 'rules']">
{{ 'ACA_FOLDER_RULES.MANAGE_RULES.TOOLBAR.ACTIONS.SEE_IN_FOLDER' | translate }} {{ 'ACA_FOLDER_RULES.MANAGE_RULES.TOOLBAR.ACTIONS.SEE_IN_FOLDER' | translate }}
</button> </button>
</div> </div>

View File

@@ -29,6 +29,7 @@ import { ownedRuleSetMock, ruleSetsMock, ruleSetWithLinkMock } from '../../mock/
import { DebugElement } from '@angular/core'; import { DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { owningFolderIdMock } from '../../mock/node.mock'; import { owningFolderIdMock } from '../../mock/node.mock';
import { of } from 'rxjs';
describe('RuleListUiComponent', () => { describe('RuleListUiComponent', () => {
let fixture: ComponentFixture<RuleListUiComponent>; let fixture: ComponentFixture<RuleListUiComponent>;
@@ -49,7 +50,7 @@ describe('RuleListUiComponent', () => {
}); });
it('should show "Rules from current folder" as a title if the main rule set is owned', () => { it('should show "Rules from current folder" as a title if the main rule set is owned', () => {
component.mainRuleSet = ownedRuleSetMock; component.mainRuleSet$ = of(ownedRuleSetMock);
fixture.detectChanges(); fixture.detectChanges();
const mainRuleSetTitleElement = debugElement.query(By.css(`[data-automation-id="main-rule-set-title"]`)); const mainRuleSetTitleElement = debugElement.query(By.css(`[data-automation-id="main-rule-set-title"]`));
@@ -57,7 +58,7 @@ describe('RuleListUiComponent', () => {
}); });
it('should show "Rules from linked folder" as a title if the main rule set is linked', () => { it('should show "Rules from linked folder" as a title if the main rule set is linked', () => {
component.mainRuleSet = ruleSetWithLinkMock; component.mainRuleSet$ = of(ruleSetWithLinkMock);
fixture.detectChanges(); fixture.detectChanges();
const mainRuleSetTitleElement = debugElement.query(By.css(`[data-automation-id="main-rule-set-title"]`)); const mainRuleSetTitleElement = debugElement.query(By.css(`[data-automation-id="main-rule-set-title"]`));

View File

@@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>. * from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/ */
import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core'; import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { RuleSet } from '../../model/rule-set.model'; import { RuleSet } from '../../model/rule-set.model';
import { Rule } from '../../model/rule.model'; import { Rule } from '../../model/rule.model';
import { RuleGroupingItem } from '../../model/rule-grouping-item.model'; import { RuleGroupingItem } from '../../model/rule-grouping-item.model';
@@ -35,6 +35,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
import { RuleListGroupingUiComponent } from '../rule-list-grouping/rule-list-grouping.ui-component'; import { RuleListGroupingUiComponent } from '../rule-list-grouping/rule-list-grouping.ui-component';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { Observable, Subscription } from 'rxjs';
@Component({ @Component({
standalone: true, standalone: true,
@@ -54,9 +55,9 @@ import { MatButtonModule } from '@angular/material/button';
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,
host: { class: 'aca-rule-list' } host: { class: 'aca-rule-list' }
}) })
export class RuleListUiComponent { export class RuleListUiComponent implements OnInit, OnDestroy {
@Input() @Input()
mainRuleSet: RuleSet = null; mainRuleSet$: Observable<RuleSet>;
@Input() @Input()
folderId: string; folderId: string;
@Input() @Input()
@@ -81,31 +82,40 @@ export class RuleListUiComponent {
@Output() @Output()
ruleSetUnlinkClicked = new EventEmitter<RuleSet>(); ruleSetUnlinkClicked = new EventEmitter<RuleSet>();
mainRuleSet: RuleSet = null;
inheritedRuleSetsExpanded = true; inheritedRuleSetsExpanded = true;
mainRuleSetExpanded = true; mainRuleSetExpanded = true;
mainRuleSetGroupingItems: RuleGroupingItem[] = [];
inheritedRuleSetGroupingItems: RuleGroupingItem[] = [];
isMainRuleSetOwned = false;
isMainRuleSetLinked = false;
get isMainRuleSetOwned(): boolean { private _mainRuleSetSub: Subscription;
return FolderRuleSetsService.isOwnedRuleSet(this.mainRuleSet, this.folderId);
}
get isMainRuleSetLinked(): boolean {
return FolderRuleSetsService.isLinkedRuleSet(this.mainRuleSet, this.folderId);
}
get mainRuleSetGroupingItems(): RuleGroupingItem[] { ngOnInit() {
return this.mainRuleSet ? this.getRuleSetGroupingItems(this.mainRuleSet, !this.isMainRuleSetOwned) : []; this._mainRuleSetSub = this.mainRuleSet$.subscribe((ruleSet: RuleSet) => {
} if (ruleSet) {
this.mainRuleSet = ruleSet;
this.isMainRuleSetOwned = FolderRuleSetsService.isOwnedRuleSet(ruleSet, this.folderId);
this.isMainRuleSetLinked = FolderRuleSetsService.isLinkedRuleSet(ruleSet, this.folderId);
}
get inheritedRuleSetGroupingItems(): RuleGroupingItem[] { this.mainRuleSetGroupingItems = ruleSet ? this.getRuleSetGroupingItems(ruleSet, !this.isMainRuleSetOwned) : [];
const items = this.inheritedRuleSets.reduce((accumulator: RuleGroupingItem[], currentRuleSet: RuleSet) => { });
this.inheritedRuleSetGroupingItems = this.inheritedRuleSets.reduce((accumulator: RuleGroupingItem[], currentRuleSet: RuleSet) => {
accumulator.push(...this.getRuleSetGroupingItems(currentRuleSet, true)); accumulator.push(...this.getRuleSetGroupingItems(currentRuleSet, true));
return accumulator; return accumulator;
}, []); }, []);
if (this.ruleSetsLoading || this.hasMoreRuleSets) { if (this.ruleSetsLoading || this.hasMoreRuleSets) {
items.push({ this.inheritedRuleSetGroupingItems.push({
type: this.ruleSetsLoading ? 'loading' : 'load-more-rule-sets' type: this.ruleSetsLoading ? 'loading' : 'load-more-rule-sets'
}); });
} }
return items; }
ngOnDestroy() {
this._mainRuleSetSub.unsubscribe();
} }
getRuleSetGroupingItems(ruleSet: RuleSet, filterOutDisabledRules: boolean): RuleGroupingItem[] { getRuleSetGroupingItems(ruleSet: RuleSet, filterOutDisabledRules: boolean): RuleGroupingItem[] {

View File

@@ -210,8 +210,8 @@ export class FolderRuleSetsService {
this.mainRuleSet.rules.splice(index, 1); this.mainRuleSet.rules.splice(index, 1);
} else { } else {
this.mainRuleSet = null; this.mainRuleSet = null;
this.mainRuleSetSource.next(this.mainRuleSet);
} }
this.mainRuleSetSource.next(this.mainRuleSet);
this.folderRulesService.selectRule(this.mainRuleSet?.rules[0] ?? this.inheritedRuleSets[0]?.rules[0] ?? null); this.folderRulesService.selectRule(this.mainRuleSet?.rules[0] ?? this.inheritedRuleSets[0]?.rules[0] ?? null);
} }
} }
@@ -225,6 +225,7 @@ export class FolderRuleSetsService {
} else { } else {
this.mainRuleSet.rules.push(newRule); this.mainRuleSet.rules.push(newRule);
} }
this.mainRuleSetSource.next(this.mainRuleSet);
this.folderRulesService.selectRule(newRule); this.folderRulesService.selectRule(newRule);
} else { } else {
this.refreshMainRuleSet(newRule); this.refreshMainRuleSet(newRule);
@@ -234,6 +235,9 @@ export class FolderRuleSetsService {
refreshMainRuleSet(ruleToSelect: Rule = null) { refreshMainRuleSet(ruleToSelect: Rule = null) {
this.getMainRuleSet(this.currentFolder.id).subscribe((mainRuleSet: RuleSet) => { this.getMainRuleSet(this.currentFolder.id).subscribe((mainRuleSet: RuleSet) => {
this.mainRuleSet = { ...mainRuleSet }; this.mainRuleSet = { ...mainRuleSet };
if (!this.mainRuleSet.rules) {
this.mainRuleSet = null;
}
this.mainRuleSetSource.next(this.mainRuleSet); this.mainRuleSetSource.next(this.mainRuleSet);
if (mainRuleSet) { if (mainRuleSet) {
const ruleToSelectInRuleSet = ruleToSelect ? mainRuleSet.rules.find((rule: Rule) => rule.id === ruleToSelect.id) : mainRuleSet.rules[0]; const ruleToSelectInRuleSet = ruleToSelect ? mainRuleSet.rules.find((rule: Rule) => rule.id === ruleToSelect.id) : mainRuleSet.rules[0];