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 Conditional Options Logic #392

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
104 changes: 85 additions & 19 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 @@ -128,8 +130,8 @@ export interface FieldMetadata {
digits?: number;
isBaseCurrency?: boolean;
labelDisplay?: string;
options$?: Observable<Option[]>;
extraOptions?: Option[];
conditionalOptions?: { [value: string]: Option };
onClick?: FieldClickCallback;
tinymce?: any;
date_time_format?: string;
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 @@ -185,11 +197,14 @@ export interface Field {
asyncValidators?: AsyncValidatorFn[];
valueSubject?: BehaviorSubject<FieldValue>;
valueChanges$?: Observable<FieldValue>;
options?: Option[];
optionsState?: Option[];
optionsSubject?: BehaviorSubject<Option[]>;
optionsChanges$?: Observable<Option[]>;
fieldDependencies?: ObjectMap;
attributeDependencies?: AttributeDependency[];
logic?: FieldLogicMap;
displayLogic?: FieldLogicMap;
previousValue?: string;
}

export class BaseField implements Field {
Expand All @@ -212,6 +227,9 @@ export class BaseField implements Field {
attributes?: FieldAttributeMap;
valueSubject?: BehaviorSubject<FieldValue>;
valueChanges$?: Observable<FieldValue>;
optionsState?: Option[];
optionsSubject?: BehaviorSubject<Option[]>;
optionsChanges$?: Observable<Option[]>;
fieldDependencies: ObjectMap = {};
attributeDependencies: AttributeDependency[] = [];
logic?: FieldLogicMap;
Expand All @@ -225,30 +243,48 @@ export class BaseField implements Field {
constructor() {
this.valueSubject = new BehaviorSubject<FieldValue>({} as FieldValue);
this.valueChanges$ = this.valueSubject.asObservable();

this.optionsSubject = new BehaviorSubject<Option[]>(this.optionsState);
this.optionsChanges$ = this.optionsSubject.asObservable();
}

get value(): string {
return this.valueState;
}

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 +293,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 +311,44 @@ export class BaseField implements Field {
}

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

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

protected emitValueChanges() {
get options(): Option[] {
return this.optionsState;
}

set options(options: Option[]) {
this.optionsState = options;
this.emitOptionsChanges();
}

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;
protected emitOptionsChanges(): void {
this.optionsSubject.next(deepClone(this.optionsState));
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export class SavedFilterRecordStore extends RecordStore {

/**
* Get search fields metadata
*
* @returns SearchMetaFieldMap
*/
public getSearchFields(): SearchMetaFieldMap {
Expand All @@ -104,6 +105,7 @@ export class SavedFilterRecordStore extends RecordStore {

/**
* Set search fields metadata
*
* @param {object} searchFields SearchMetaFieldMap
*/
public setSearchFields(searchFields: SearchMetaFieldMap): void {
Expand All @@ -112,6 +114,7 @@ export class SavedFilterRecordStore extends RecordStore {

/**
* Get list fields metadata
*
* @returns SearchMetaFieldMap
*/
public getListColumns(): ColumnDefinition[] {
Expand All @@ -120,6 +123,7 @@ export class SavedFilterRecordStore extends RecordStore {

/**
* Set list fields metadata
*
* @param {object} listColumns SearchMetaFieldMap
*/
public setListColumns(listColumns: ColumnDefinition[]): void {
Expand Down Expand Up @@ -153,6 +157,7 @@ export class SavedFilterRecordStore extends RecordStore {
* Extract base record
*
* @returns {object} Record
* @param record
*/
extractBaseRecord(record: SavedFilter): Record {
if (!record) {
Expand All @@ -170,7 +175,7 @@ export class SavedFilterRecordStore extends RecordStore {
module: record.module,
key: record.key,
searchModule: record.searchModule,
criteria: criteria,
criteria,
attributes: record.attributes,
} as SavedFilter);
}
Expand Down Expand Up @@ -206,11 +211,12 @@ export class SavedFilterRecordStore extends RecordStore {

/**
* Init Order by options using list view columns set as default
*
* @param record
*/
protected initOrderByOptions(record: SavedFilter): void {
if (!record.fields || !record.fields.orderBy) {
return
return;
}

record.fields.orderBy.metadata = record.fields.orderBy.metadata || {} as FieldMetadata;
Expand All @@ -228,14 +234,16 @@ export class SavedFilterRecordStore extends RecordStore {
options.push({
value: column.fieldDefinition.name || column.name,
label
})
});
});

record.fields.orderBy.metadata.options$ = of(options).pipe(shareReplay());
record.fields.orderBy.definition.options = null;
record.fields.orderBy.options = options;
}

/**
* Get criteria from filter
*
* @param filter
*/
protected getCriteria(filter: SavedFilter): SearchCriteria {
Expand Down
3 changes: 3 additions & 0 deletions core/app/core/src/lib/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,8 @@ 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/conditional-options/conditional-options.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';
Expand Down Expand Up @@ -466,6 +468,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
Loading