Fix field display not-updating on display logic

This commit is contained in:
y.yerli 2025-01-09 12:41:28 +03:00
parent 36a2f16fd5
commit 46b06deff2
17 changed files with 43 additions and 30 deletions

View file

@ -183,7 +183,7 @@ export interface Field {
attributes?: FieldAttributeMap;
items?: Record[];
readonly?: boolean;
display?: DisplayType;
display?: WritableSignal<DisplayType>;
defaultDisplay?: string;
default?: string;
defaultValueModes?: ViewMode[];
@ -218,7 +218,7 @@ export class BaseField implements Field {
loading?: WritableSignal<boolean> = signal(false);
dynamicLabelKey?: string;
readonly?: boolean;
display?: DisplayType;
display?: WritableSignal<DisplayType>;
defaultDisplay?: string;
default?: string;
defaultValueModes?: ViewMode[];
@ -249,6 +249,7 @@ export class BaseField implements Field {
constructor() {
this.valueSubject = new BehaviorSubject<FieldValue>({} as FieldValue);
this.valueChanges$ = this.valueSubject.asObservable();
this.display = signal('default');
}
get value(): string {

View file

@ -24,11 +24,12 @@
* the words "Supercharged by SuiteCRM".
*/
import {Directive, Input, OnDestroy, OnInit} from '@angular/core';
import {Directive, Input, OnDestroy, OnInit, signal} from '@angular/core';
import {Subscription} from 'rxjs';
import {BreakpointObserver, Breakpoints, BreakpointState} from '@angular/cdk/layout';
import {FieldGridColumn, FieldGridRow, LabelDisplay} from './field-grid.model';
import {ScreenSizeMap} from '../../common/services/ui/resize.model';
import {DisplayType} from "../../common/record/field.model";
@Directive()
@ -204,7 +205,7 @@ export abstract class BaseFieldGridComponent implements OnInit, OnDestroy {
protected fillRow(row: FieldGridRow): void {
const len = row.cols.length;
for (let i = len; i < this.colNumber; i++) {
row.cols.push({field: {type: '', display: 'none'}});
row.cols.push({field: {type: '', display: signal<DisplayType>('none')}});
}
}

View file

@ -36,14 +36,14 @@
[ngClass]="colAlignItems ? colAlignItems : ''"
class="d-flex"
>
<div *ngIf="col.field && col.field.display !== 'none'"
<div *ngIf="col.field && col.field?.display() !== 'none'"
[class.pr-3]="labelDisplay === 'inline'" >
<label *ngIf="col.field.label" [ngClass]="labelClass">{{col.field.label}}</label>
<scrm-label *ngIf="!col.field.label && col.field.labelKey"
[labelKey]="col.field.labelKey"
[ngClass]="labelClass"></scrm-label>
</div>
<div *ngIf="col.field && col.field.display !== 'none'"
<div *ngIf="col.field && col.field?.display()!== 'none'"
[class.flex-grow-1]="labelDisplay === 'inline'">
<scrm-field [field]="col.field"
[klass]="inputClass"

View file

@ -33,7 +33,7 @@
[ngClass]="colClass"
class="field-layout-col">
<ng-container *ngIf="col.field && col.field.display !== 'none'">
<ng-container *ngIf="col.field && col.field.display() !== 'none'">
<div class="field-layout-field-group-wrapper form-group row">
<div class="{{col?.headerColumnClass}} field-layout-field-label-wrapper col-form-label label-container">
<strong>
@ -94,7 +94,7 @@
<ng-content select="[field-grid-special]"></ng-content>
</ng-container>
<div *ngIf="col.field && col.field?.display !== 'none' && i < fieldGrid.length - 1"
<div *ngIf="col.field && col.field?.display() !== 'none' && i < fieldGrid.length - 1"
class="field-separation mt-2">
</div>
</div>

View file

@ -243,8 +243,8 @@ export class ListFilterStore implements StateStore {
if (!isEmpty(fieldFilter?.operator) && field.display === 'none') {
field.display = 'default';
if (!isEmpty(fieldFilter?.operator) && field.display() === 'none') {
field.display.set('default');
}
this.fields.push(field);
@ -269,7 +269,7 @@ export class ListFilterStore implements StateStore {
const name = field.name;
if (field.display === 'none' || field.source === 'groupField') {
if (field?.display() === 'none' || field.source === 'groupField') {
return;
}

View file

@ -298,7 +298,7 @@ export class SavedFilterRecordStore extends RecordStore {
label: fieldMeta.label,
vardefBased: fieldMeta?.vardefBased ?? false,
readonly: fieldMeta?.readonly ?? false,
display: fieldMeta?.display ?? '',
display: fieldMeta?.display ?? 'default',
type,
fieldDefinition: {}
} as ViewFieldDefinition;

View file

@ -33,7 +33,6 @@ import {Record} from '../../../../common/record/record.model';
import {ViewContext} from '../../../../common/views/view.model';
import {take} from 'rxjs/operators';
import {HistoryTimelineStoreFactory} from './history-timeline.store.factory';
import {sign} from "mathjs";
export type ActivityTypes = 'calls' | 'tasks' | 'meetings' | 'history' | 'audit' | 'notes' | string;
@ -145,17 +144,20 @@ export class HistoryTimelineAdapter {
title: {
type: 'varchar',
value: record.attributes.name,
loading: signal(false)
loading: signal(false),
display: signal('default')
},
user: {
type: 'varchar',
value: record.attributes.assigned_user_name.user_name,
loading: signal(false)
loading: signal(false),
display: signal('default')
},
date: {
type: 'datetime',
value: record.attributes.date_end,
loading: signal(false)
loading: signal(false),
display: signal('default')
},
record
} as HistoryTimelineEntry;
@ -165,7 +167,8 @@ export class HistoryTimelineAdapter {
timelineEntry.description = {
type: 'html',
value: record.attributes.description,
loading: signal(false)
loading: signal(false),
display: signal('default')
};
}
return timelineEntry;

View file

@ -74,7 +74,7 @@ export class BaseComposite extends BaseFieldComponent implements OnInit, OnDestr
const fields: Field[] = [];
this.field.definition.layout.forEach(name => {
if (!this.field.attributes[name] || this.field.attributes[name].display === 'none') {
if (!this.field.attributes[name] || this.field.attributes[name]?.display() === 'none') {
return;
}
fields.push(this.field.attributes[name]);

View file

@ -58,7 +58,7 @@ export class FieldLogicDisplayManager extends BaseActionManager<FieldLogicDispla
});
if (!validModeLogic || !validModeLogic.length) {
field.display = toDisplay;
field.display.set(toDisplay);
return;
}
@ -93,7 +93,7 @@ export class FieldLogicDisplayManager extends BaseActionManager<FieldLogicDispla
toDisplay = 'show';
}
field.display = toDisplay;
field.display.set(toDisplay);
}

View file

@ -108,7 +108,7 @@ export class DisplayTypeBackendAction extends FieldLogicActionHandler {
return;
}
display = targetDisplay
data.field.display = display as DisplayType;
data.field.display.set(display as DisplayType);
}, (error) => {
field.loading.set(false)

View file

@ -82,7 +82,7 @@ export class FieldLogicDisplayTypeAction extends FieldLogicActionHandler {
display = targetDisplay;
}
data.field.display = display as DisplayType;
data.field.display.set(display as DisplayType);
const resetOn: string = (action.params && action.params.resetOn) || 'none';

View file

@ -32,6 +32,7 @@ import {ViewMode} from '../../../common/views/view.model';
import {FieldLogicActionData, FieldLogicActionHandler} from '../field-logic.action';
import {RequiredValidator} from '../../../services/record/validation/validators/required.validator';
import {ActiveFieldsChecker} from "../../../services/condition-operators/active-fields-checker.service";
import {ViewFieldDefinition} from "../../../common/metadata/metadata.model";
@Injectable({
providedIn: 'root'
@ -72,7 +73,13 @@ export class RequiredAction extends FieldLogicActionHandler {
let validators = [...data.field.validators || []];
if (isActive) {
required = true;
validators = validators.concat(this.requiredValidator.getValidator(field, record));
const viewField: ViewFieldDefinition = {
...field,
display: field?.display()
}
validators = validators.concat(this.requiredValidator.getValidator(viewField, record));
}
data.field.formControl.updateValueAndValidity({onlySelf: true, emitEvent: true});

View file

@ -25,7 +25,7 @@
* the words "Supercharged by SuiteCRM".
*/
-->
<ng-container *ngIf="field && field.display !== 'none'">
<ng-container *ngIf="field && field?.display() !== 'none'">
<scrm-dynamic-field *ngIf="type !== 'line-items'"
[componentType]="componentType"
[field]="field"

View file

@ -101,7 +101,7 @@ export class GroupFieldComponent extends BaseFieldComponent implements AfterView
const fields: Field[] = [];
this.field.definition.layout.forEach(name => {
if (!this.record.fields[name] || this.record.fields[name].display === 'none') {
if (!this.record.fields[name] || this.record.fields[name]?.display() === 'none') {
return;
}

View file

@ -24,7 +24,7 @@
* the words "Supercharged by SuiteCRM".
*/
import {Injectable} from '@angular/core';
import {Injectable, signal} from '@angular/core';
import {ValidationManager} from '../validation/validation.manager';
import {DataTypeFormatter} from '../../formatters/data-type.formatter.service';
import {isFalse, isTrue} from '../../../common/utils/value-utils';
@ -185,8 +185,8 @@ export class FieldBuilder {
field.name = viewField.name || definition.name || '';
field.vardefBased = viewField?.vardefBased ?? definition?.vardefBased ?? false;
field.readonly = isTrue(viewField.readonly) || isTrue(definition.readonly) || false;
field.display = (viewField.display || definition.display || 'default') as DisplayType;
field.defaultDisplay = field.display;
field.display = signal((viewField.display || definition.display || 'default') as DisplayType);
field.defaultDisplay = field?.display();
if (field.defaultDisplay === 'default') {
field.defaultDisplay = 'show';
}

View file

@ -69,7 +69,8 @@ export class FieldManager {
definition: {
type
},
loading: signal(false)
loading: signal(false),
display: signal('default')
} as Field;
}

View file

@ -103,7 +103,7 @@ export class RecordConvertService {
vardefBased: true,
label: vardef.vname ?? '',
type: vardef.type ?? '',
display: vardef.display ?? '',
display: vardef.display ?? 'default',
fieldDefinition: vardef,
metadata: vardef.metadata ?? {} as FieldMetadata,
logic: vardef.logic ?? {} as FieldLogicMap