Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Update field logic #394

Open
wants to merge 2 commits into
base: hotfix
Choose a base branch
from
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
79 changes: 62 additions & 17 deletions core/app/common/src/lib/record/field.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
* the words "Supercharged by SuiteCRM".
*/

import {SearchCriteriaFieldFilter} from '../views/list/search-criteria.model';
import {isArray, isEqual, isObject, isString, uniq} from 'lodash-es';
import {BehaviorSubject, Observable} from 'rxjs';
import {AsyncValidatorFn, UntypedFormArray, UntypedFormControl, ValidatorFn} from '@angular/forms';
import {SearchCriteriaFieldFilter} from '../views/list/search-criteria.model';
import {Record} from './record.model';
import {FieldLogicMap} from '../actions/field-logic-action.model';
import {ObjectMap} from '../types/object-map';
import {ViewMode} from '../views/view.model';
import {deepClone} from '../utils/object-utils';

export type DisplayType = 'none' | 'show' | 'readonly' | 'inline' | 'disabled' | 'default';

Expand Down Expand Up @@ -97,7 +99,7 @@ export interface FieldDefinition {
default?: string;
modes?: ViewMode[];
relationship?: string;
relationshipMetadata?: RelationshipMetadata
relationshipMetadata?: RelationshipMetadata;

[key: string]: any;
}
Expand Down Expand Up @@ -157,6 +159,16 @@ export interface AttributeDependency {
types: string[];
}

export interface FieldValue {
value?: string;
valueList?: string[];
valueObject?: any;
}

export interface FieldValueMap {
[key: string]: FieldValue;
}

export interface Field {
type: string;
value?: string;
Expand Down Expand Up @@ -232,23 +244,38 @@ export class BaseField implements Field {
}

set value(value: string) {
const changed = value !== this.valueState;
if (!isString(value)) {
this.setValue(value);
return;
}

this.valueState = value;
const valueClean: string = value.trim();

if (changed) {
this.emitValueChanges();
if (isEqual(this.valueState, valueClean)) {
return;
}

this.valueState = valueClean;
this.emitValueChanges();
}

get valueList(): string[] {
return this.valueListState;
}

set valueList(value: string[]) {
if (!isArray(value)) {
this.setValue(value);
return;
}

this.valueListState = value;
const valueListClean: string[] = uniq(deepClone(value));

if (isEqual(this.valueListState, valueListClean)) {
return;
}

this.valueListState = valueListClean;
this.emitValueChanges();
}

Expand All @@ -257,7 +284,16 @@ export class BaseField implements Field {
}

set valueObject(value: any) {
this.valueObjectState = value;
if (!isObject(value)) {
this.setValue(value);
return;
}

if (isEqual(this.valueObjectState, value)) {
return;
}

this.valueObjectState = deepClone(value);
this.emitValueChanges();
}

Expand All @@ -266,23 +302,32 @@ export class BaseField implements Field {
}

set valueObjectArray(value: ObjectMap[]) {
if (isEqual(this.valueObjectArrayState, value)) {
return;
}

this.valueObjectArrayState = value;
this.emitValueChanges();
}

protected emitValueChanges() {
public setValue(value: string | string[] | any): void {
if (isString(value)) {
this.value = value;
} else if (isArray(value)) {
this.valueList = value;
} else if (isObject(value)) {
this.valueObject = value;
} else {
this.value = value?.toString() ?? '';
}
}

protected emitValueChanges(): void {
this.valueSubject.next({
value: this.valueState,
valueList: this.valueListState,
valueObject: this.valueObjectState
})
});
}
}

export interface FieldValue {
value?: string;
valueList?: string[];
valueObject?: any;
}


4 changes: 3 additions & 1 deletion core/app/core/src/lib/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,14 +358,15 @@ export * from './fields/enum/templates/edit/enum.component';
export * from './fields/enum/templates/edit/enum.module';
export * from './fields/field-logic/field-logic.action';
export * from './fields/field-logic/field-logic.manager';
export * from './fields/field-logic/actionable-field-logic/actionable-field-logic.action';
export * from './fields/field-logic/currency-conversion/update-base-currency.action';
export * from './fields/field-logic/currency-conversion/update-currency.action';
export * from './fields/field-logic/display-type/field-logic-display-type.action';
export * from './fields/field-logic/display-type-backend/display-type-backend.action';
export * from './fields/field-logic/email-primary-select/email-primary-select.action';
export * from './fields/field-logic/required/required.action';
export * from './fields/field-logic/update-field/update-field.action';
export * from './fields/field-logic/update-flex-relate-module/update-flex-relate-module.action';
export * from './fields/field-logic/update-value/update-value.action';
export * from './fields/field-logic/update-value-backend/update-value-backend.action';
export * from './fields/field-logic-display/field-logic-display.action';
export * from './fields/field-logic-display/field-logic-display.manager';
Expand Down Expand Up @@ -466,6 +467,7 @@ export * from './services/formatters/number/number-formatter.service';
export * from './services/formatters/phone/phone-formatter.service';
export * from './services/language/dynamic-label.service';
export * from './services/local-storage/local-storage.service';
export * from './services/logic/active-logic-checker.service';
export * from './services/message/message.service';
export * from './services/metadata/base-metadata.resolver';
export * from './services/metadata/base-module.resolver';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,67 +24,60 @@
* the words "Supercharged by SuiteCRM".
*/

import {Injectable} from '@angular/core';
import {FieldLogicActionData, FieldLogicActionHandler} from '../field-logic.action';
import {Action, Field, Record, StringArrayMap, StringArrayMatrix, ViewMode} from 'common';
import {ActiveFieldsChecker} from "../../../services/condition-operators/active-fields-checker.service";

@Injectable({
providedIn: 'root'
})
export class UpdateValueAction extends FieldLogicActionHandler {

key = 'updateValue';
modes = ['edit', 'detail', 'list', 'create', 'massupdate', 'filter'] as ViewMode[];

constructor(protected activeFieldsChecker: ActiveFieldsChecker) {
import {isArray, isString} from 'lodash-es';
import {
Action,
ALL_VIEW_MODES,
Field,
Record,
} from 'common';
import { FieldLogicActionData, FieldLogicActionHandler } from '../field-logic.action';
import {ActiveLogicChecker} from '../../../services/logic/active-logic-checker.service';

export type FieldValueTypes = string | string[] | object;

export abstract class ActionableFieldLogicActionHandler extends FieldLogicActionHandler {
modes = ALL_VIEW_MODES;

protected constructor(
protected activeLogicChecker: ActiveLogicChecker
) {
super();
}

run(data: FieldLogicActionData, action: Action): void {
const record = data.record;
const field = data.field;

if (!record || !field) {
return;
}
const params = action.params ?? {};

const activeOnFields: StringArrayMap = (action.params && action.params.activeOnFields) || {} as StringArrayMap;
const relatedFields: string[] = Object.keys(activeOnFields);

const activeOnAttributes: StringArrayMatrix = (action.params && action.params.activeOnAttributes) || {} as StringArrayMatrix;
const relatedAttributesFields: string[] = Object.keys(activeOnAttributes);

if (!relatedFields.length && !relatedAttributesFields.length) {
return;
}

const targetValue = action.params && action.params.targetValue;
const logicIsActive = this.activeLogicChecker.run(record, action);

if (!targetValue) {
return;
}
this.executeLogic(logicIsActive, params, field, record);
}

const isActive = this.activeFieldsChecker.isActive(relatedFields, record, activeOnFields, relatedAttributesFields, activeOnAttributes);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
shouldDisplay(data: FieldLogicActionData): boolean {
return true;
}

let value = data.field?.value;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
executeLogic(logicIsActive: boolean, params: { [p: string]: any }, field: Field, record: Record): void {
}

if (isActive) {
value = targetValue;
protected updateValue(value: FieldValueTypes, field: Field, record: Record): void {
if (isString(value)) {
field.value = value;
} else if (isArray(value)) {
field.valueList = value;
} else {
field.valueObject = value;
}

this.updateValue(field, value.toString(), record);

}

/**
* Update the new value
* @param {object} field
* @param {object} record
*/
protected updateValue(field: Field, value: string, record: Record): void {
field.value = value.toString();
field.formControl.setValue(value);

// re-validate the parent form-control after value update
record.formGroup.updateValueAndValidity({onlySelf: true, emitEvent: true});
}
Expand Down
22 changes: 13 additions & 9 deletions core/app/core/src/lib/fields/field-logic/field-logic.manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,16 @@
import {Injectable} from '@angular/core';
import {BaseActionManager} from '../../services/actions/base-action-manager.service';
import {FieldLogicActionData, FieldLogicActionHandlerMap} from './field-logic.action';
import {Action, ActionContext, ActionHandlerMap, Field, ModeActions, Record, ViewMode} from 'common';
import {Action, ActionContext, Field, ModeActions, Record, ViewMode} from 'common';
import {FieldLogicDisplayTypeAction} from './display-type/field-logic-display-type.action';
import {EmailPrimarySelectAction} from './email-primary-select/email-primary-select.action';
import {RequiredAction} from './required/required.action';
import {UpdateBaseCurrencyAction} from './currency-conversion/update-base-currency.action';
import {UpdateCurrencyAction} from './currency-conversion/update-currency.action';
import {UpdateFlexRelateModuleAction} from './update-flex-relate-module/update-flex-relate-module.action';
import {UpdateValueAction} from './update-value/update-value.action';
import {UpdateFieldAction} from './update-field/update-field.action';
import {UpdateValueBackendAction} from './update-value-backend/update-value-backend.action';
import {DisplayTypeBackendAction} from './display-type-backend/display-type-backend.action';
import {RecordActionData} from '../../views/record/actions/record.action';

@Injectable({
providedIn: 'root'
Expand All @@ -59,7 +58,7 @@ export class FieldLogicManager extends BaseActionManager<FieldLogicActionData> {
required: RequiredAction,
updateBaseCurrency: UpdateBaseCurrencyAction,
updateCurrency: UpdateCurrencyAction,
updateValue: UpdateValueAction,
updateValue: UpdateFieldAction,
updateFlexRelateModule: UpdateFlexRelateModuleAction,
updateValueBackend: UpdateValueBackendAction,
dislayTypeBackend: DisplayTypeBackendAction
Expand All @@ -78,12 +77,13 @@ export class FieldLogicManager extends BaseActionManager<FieldLogicActionData> {

/**
* Run logic for the given field
* @param {object} field
* @param {object} mode
* @param {object} record
* @param triggeringStatus
*
* @param {Field} field Field
* @param {ViewMode} mode Mode
* @param {Record} record Record
* @param {string} triggeringStatus Triggering Status
*/
runLogic(field: Field, mode: ViewMode, record: Record, triggeringStatus: string = ''): void {
runLogic(field: Field, mode: ViewMode, record: Record, triggeringStatus = ''): void {
if (!field.logic) {
return;
}
Expand All @@ -104,6 +104,7 @@ export class FieldLogicManager extends BaseActionManager<FieldLogicActionData> {

/**
* Run the action using given context
*
* @param action
* @param mode
* @param context
Expand All @@ -114,6 +115,7 @@ export class FieldLogicManager extends BaseActionManager<FieldLogicActionData> {

/**
* Run front end action
*
* @param {object} action
* @param {object} mode
* @param {object} context
Expand All @@ -126,6 +128,7 @@ export class FieldLogicManager extends BaseActionManager<FieldLogicActionData> {

/**
* Get module name
*
* @param {object} context
*/
protected getModuleName(context?: ActionContext): string {
Expand All @@ -141,6 +144,7 @@ export class FieldLogicManager extends BaseActionManager<FieldLogicActionData> {

/**
* Parse mode actions
*
* @param declaredActions
* @param mode
* @param triggeringStatus
Expand Down
Loading