diff --git a/packages/angular-sdk-components/src/lib/_components/field/dropdown/dropdown.component.ts b/packages/angular-sdk-components/src/lib/_components/field/dropdown/dropdown.component.ts index 66073ede..fd340fe9 100644 --- a/packages/angular-sdk-components/src/lib/_components/field/dropdown/dropdown.component.ts +++ b/packages/angular-sdk-components/src/lib/_components/field/dropdown/dropdown.component.ts @@ -5,12 +5,47 @@ import { MatOptionModule } from '@angular/material/core'; import { MatSelectModule } from '@angular/material/select'; import { MatFormFieldModule } from '@angular/material/form-field'; import { interval } from 'rxjs'; +import isEqual from 'fast-deep-equal'; import { AngularPConnectData, AngularPConnectService } from '../../../_bridge/angular-pconnect'; +import { DatapageService } from '../../../_services/datapage.service'; import { Utils } from '../../../_helpers/utils'; import { ComponentMapperComponent } from '../../../_bridge/component-mapper/component-mapper.component'; import { handleEvent } from '../../../_helpers/event-util'; import { PConnFieldProps } from '../../../_types/PConnProps.interface'; +function flattenParameters(params = {}) { + const flatParams = {}; + Object.keys(params).forEach(key => { + const { name, value: theVal } = params[key]; + flatParams[name] = theVal; + }); + + return flatParams; +} + +function preProcessColumns(columnList) { + return columnList.map(col => { + const tempColObj = { ...col }; + tempColObj.value = col.value && col.value.startsWith('.') ? col.value.substring(1) : col.value; + return tempColObj; + }); +} + +function getDisplayFieldsMetaData(columnList) { + const displayColumns = columnList.filter(col => col.display === 'true'); + const metaDataObj: any = { key: '', primary: '', secondary: [] }; + const keyCol = columnList.filter(col => col.key === 'true'); + metaDataObj.key = keyCol.length > 0 ? keyCol[0].value : 'auto'; + for (let index = 0; index < displayColumns.length; index += 1) { + if (displayColumns[index].primary === 'true') { + metaDataObj.primary = displayColumns[index].value; + } else { + metaDataObj.secondary.push(displayColumns[index].value); + } + } + return metaDataObj; +} + interface IOption { key: string; value: string; @@ -22,6 +57,11 @@ interface DropdownProps extends PConnFieldProps { datasource?: any[]; onRecordChange?: any; fieldMetadata?: any; + listType?: string; + columns?: any[]; + deferDatasource?: boolean; + datasourceMetadata?: any; + parameters?: any; } @Component({ @@ -53,7 +93,7 @@ export class DropdownComponent implements OnInit, OnDestroy { testId = ''; helperText: string; hideLabel: any; - + theDatasource: any[] | null; fieldControl = new FormControl('', null); fieldMetadata: any[]; localeContext = ''; @@ -67,7 +107,8 @@ export class DropdownComponent implements OnInit, OnDestroy { constructor( private angularPConnect: AngularPConnectService, private cdRef: ChangeDetectorRef, - private utils: Utils + private utils: Utils, + private dataPageService: DatapageService ) {} ngOnInit(): void { @@ -78,8 +119,9 @@ export class DropdownComponent implements OnInit, OnDestroy { // Then, continue on with other initialization // call updateSelf when initializing - // this.updateSelf(); this.checkAndUpdate(); + // this should get called afer checkAndUpdate + this.getDatapageData(); if (this.formGroup$) { // add control to formGroup @@ -122,7 +164,6 @@ export class DropdownComponent implements OnInit, OnDestroy { updateSelf(): void { // moved this from ngOnInit() and call this from there instead... this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as DropdownProps; - if (this.configProps$.value != undefined) { this.value$ = this.configProps$.value; } @@ -132,6 +173,7 @@ export class DropdownComponent implements OnInit, OnDestroy { this.label$ = this.configProps$.label; this.helperText = this.configProps$.helperText; this.hideLabel = this.configProps$.hideLabel; + const datasource = this.configProps$.datasource; // timeout and detectChanges to avoid ExpressionChangedAfterItHasBeenCheckedError setTimeout(() => { if (this.configProps$.required != null) { @@ -140,6 +182,11 @@ export class DropdownComponent implements OnInit, OnDestroy { this.cdRef.detectChanges(); }); + if (!isEqual(datasource, this.theDatasource)) { + // inbound datasource is different, so update theDatasource + this.theDatasource = datasource || null; + } + if (this.configProps$.visibility != null) { this.bVisible$ = this.utils.getBooleanValue(this.configProps$.visibility); } @@ -161,14 +208,18 @@ export class DropdownComponent implements OnInit, OnDestroy { this.componentReference = this.pConn$.getStateProps().value; - const optionsList = [...this.utils.getOptionList(this.configProps$, this.pConn$.getDataObject())]; - optionsList?.unshift({ key: 'Select', value: this.pConn$.getLocalizedValue('Select...', '', '') }); - this.options$ = optionsList; if (this.value$ === '' && !this.bReadonly$) { this.value$ = 'Select'; } + if (this.theDatasource) { + const optionsList = [...this.utils.getOptionList(this.configProps$, this.pConn$.getDataObject())]; + optionsList?.unshift({ key: 'Select', value: this.pConn$.getLocalizedValue('Select...', '', '') }); + this.options$ = optionsList; + } + this.actionsApi = this.pConn$.getActionsApi(); + this.propName = this.pConn$.getStateProps().value; const className = this.pConn$.getCaseInfo().getClassName(); const refName = this.propName?.slice(this.propName.lastIndexOf('.') + 1); @@ -199,6 +250,56 @@ export class DropdownComponent implements OnInit, OnDestroy { } } + getDatapageData() { + const configProps = this.pConn$.getConfigProps() as DropdownProps; + let { listType, parameters, datasource = [], columns = [] } = configProps; + const { deferDatasource, datasourceMetadata } = configProps; + const context = this.pConn$.getContextName(); + if (deferDatasource && datasourceMetadata?.datasource?.name) { + listType = 'datapage'; + datasource = datasourceMetadata.datasource.name; + const { parameters: dataSourceParameters, propertyForDisplayText, propertyForValue } = datasourceMetadata.datasource; + parameters = flattenParameters(dataSourceParameters); + const displayProp = propertyForDisplayText?.startsWith('@P') ? propertyForDisplayText.substring(3) : propertyForDisplayText; + const valueProp = propertyForValue?.startsWith('@P') ? propertyForValue.substring(3) : propertyForValue; + columns = [ + { + key: 'true', + setProperty: 'Associated property', + value: valueProp + }, + { + display: 'true', + primary: 'true', + useForSearch: true, + value: displayProp + } + ]; + } + + columns = preProcessColumns(columns) || []; + if (!this.displayMode$ && listType !== 'associated' && typeof datasource === 'string') { + this.getData(datasource, parameters, columns, context); + } + } + + getData(datasource, parameters, columns, context) { + this.dataPageService.getDataPageData(datasource, parameters, context).then((results: any) => { + const optionsData: any[] = []; + const displayColumn = getDisplayFieldsMetaData(columns); + results?.forEach(element => { + const val = element[displayColumn.primary]?.toString(); + const obj = { + key: element[displayColumn.key] || element.pyGUID, + value: val + }; + optionsData.push(obj); + }); + optionsData?.unshift({ key: 'Select', value: this.pConn$.getLocalizedValue('Select...', '', '') }); + this.options$ = optionsData; + }); + } + isSelected(buttonValue: string): boolean { return this.value$ === buttonValue; } diff --git a/packages/angular-sdk-components/src/lib/_components/template/simple-table-manual/simple-table-manual.component.scss b/packages/angular-sdk-components/src/lib/_components/template/simple-table-manual/simple-table-manual.component.scss index b23e74e5..a4bd3638 100644 --- a/packages/angular-sdk-components/src/lib/_components/template/simple-table-manual/simple-table-manual.component.scss +++ b/packages/angular-sdk-components/src/lib/_components/template/simple-table-manual/simple-table-manual.component.scss @@ -4,6 +4,7 @@ width: 100%; margin-top: 0.5rem; margin-bottom: 0.5rem; + overflow-y: auto; } table {