Skip to content

Commit

Permalink
fix(material/form-builder): Fixed a bug causing ChoicesOriginRef not …
Browse files Browse the repository at this point in the history
…to be updated when a Choices Origin is edited.
  • Loading branch information
Marco Tozzi authored and robzan8 committed Oct 5, 2023
1 parent aa86918 commit d3d4428
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 7 deletions.
31 changes: 30 additions & 1 deletion projects/material/form-builder/src/form-builder-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ import {

export interface AjfFormBuilderNodeTypeEntry {
label: string;
nodeType: {node: AjfNodeType, field?: AjfFieldType};
nodeType: {node: AjfNodeType; field?: AjfFieldType};
isSlide?: boolean;
}

Expand Down Expand Up @@ -601,12 +601,14 @@ export class AjfFormBuilderService {

saveChoicesOrigin(params: {label: string; name: string; choices: any[]}): void {
const choicesOrigin = this._editedChoicesOrigin.getValue();
const choicesOriginPreviousName: string | undefined = choicesOrigin?.name;
if (choicesOrigin != null) {
choicesOrigin.label = params.label;
choicesOrigin.name = params.name;
if (isChoicesFixedOrigin(choicesOrigin)) {
choicesOrigin.choices = params.choices;
}
this._updateChoicesOriginRefInNodes(choicesOriginPreviousName, params.name);
this._choicesOriginsUpdates.next(choicesOrigins => {
const idx = choicesOrigins.indexOf(choicesOrigin);
if (idx > -1) {
Expand All @@ -628,6 +630,33 @@ export class AjfFormBuilderService {
this._stringIdentifierUpdates.next(() => [...identifier]);
}

/**
* Searches the form nodes for field nodes with choicesOriginRef corresponding
* to an edited choicesOrigin and updates it with the new name.
* @param previous_name The choicesOrigin previous name
* @param new_name The choicesOrigin new name
*/
private _updateChoicesOriginRefInNodes(previous_name?: string, new_name?: string): void {
if (!previous_name || !new_name) return;
const currentForm: AjfForm | null = this._form.value;
if (!currentForm) return;
const updatedNodes: AjfNode[] = [];
const currentSlides: (AjfSlide | AjfRepeatingSlide)[] = currentForm.nodes;
for (let slide of currentSlides) {
if (!slide.nodes || !slide.nodes.length) continue;
for (let node of slide.nodes) {
const nodeObj = node as {[key: string]: any};
if (nodeObj['choicesOriginRef'] && nodeObj['choicesOriginRef'] === previous_name) {
nodeObj['choicesOriginRef'] = new_name;
updatedNodes.push(nodeObj as AjfNode);
}
}
}
this._nodesUpdates.next((_nodes: AjfNode[]): AjfNode[] => {
return currentForm.nodes.slice(0);
});
}

private _buildFormBuilderNodesTree(nodes: AjfNode[]): (AjfFormBuilderNode | null)[] {
this._updateNodesList(0, nodes);
const rootNodes = nodes.filter(
Expand Down
24 changes: 19 additions & 5 deletions projects/material/form-builder/src/node-properties.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
<div [style.display]="(enabled|async) ? 'none' : 'block'" class="ajf-disabled-overlay"></div>
<div class="ajf-header">
<h3>{{'Properties'|transloco}}</h3>
<mat-icon (click)="save()">save</mat-icon>
<mat-icon (click)="cancel()">cancel</mat-icon>
</div>
<ng-container *ngIf="nodeEntry|async as ne">
<div class="ajf-header">
<h3>{{'Properties'|transloco}}</h3>
<button
*ngIf="isFieldWithChoices(ne.node) && (hasChoicesOriginRef()|async) === false; else readysavebtn"
mat-icon-button
color="warn"
[matTooltip]="'Please select a Choice Origin for this field'"
>
<mat-icon>save</mat-icon>
</button>
<ng-template #readysavebtn
><button mat-icon-button (click)="save()">
<mat-icon>save</mat-icon>
</button></ng-template
>
<button mat-icon-button (click)="cancel()">
<mat-icon>cancel</mat-icon>
</button>
</div>
<ng-container *ngIf="propertiesForm|async as pf">
<form [formGroup]="pf!" novalidate>
<div class="ajf-prop">
Expand Down
12 changes: 11 additions & 1 deletion projects/material/form-builder/src/node-properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
} from '@angular/forms';
import {MatDialog, MatDialogRef} from '@angular/material/dialog';
import {Observable, Subscription} from 'rxjs';
import {distinctUntilChanged, filter, map, shareReplay, withLatestFrom} from 'rxjs/operators';
import {distinctUntilChanged, filter, map, shareReplay, take, withLatestFrom} from 'rxjs/operators';

import {AjfFbConditionEditorDialog} from './condition-editor-dialog';
import {AjfFormBuilderNodeEntry, AjfFormBuilderService} from './form-builder-service';
Expand Down Expand Up @@ -406,6 +406,16 @@ export class AjfFbNodeProperties implements OnDestroy {
return isField(node) && isFieldWithChoices(node);
}

hasChoicesOriginRef(): Observable<boolean> {
return this._propertiesForm.pipe(
map(fg => {
const value = fg.get('choicesOriginRef')?.value != null;
return value;
}),
take(1),
);
}

isRangeField(node: AjfNode): node is AjfRangeField {
return isField(node) && isRangeField(node);
}
Expand Down

0 comments on commit d3d4428

Please sign in to comment.