import { Component, Input, OnInit, EventEmitter, Output } from '@angular/core'; import { CommonModule } from '@angular/common'; import { MatCardModule } from '@angular/material/card'; import { MatRadioModule } from '@angular/material/radio'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { deleteInstruction, insertInstruction } from '@pega/angular-sdk-components'; import { handleEvent } from '@pega/angular-sdk-components'; import { PConnFieldProps } from '@pega/angular-sdk-components'; import { FieldBase } from '@pega/angular-sdk-components'; interface SelectableCardProps extends PConnFieldProps { selectionList: any; readonlyContextList: any; image: string; primaryField: string; selectionKey: string; renderMode: string; hideFieldLabels?: boolean; additionalProps?: any; imagePosition?: string; imageSize?: string; showImageDescription?: boolean; datasource?: any; } @Component({ selector: 'lib-selectable-card', imports: [MatCardModule, CommonModule, MatRadioModule, MatCheckboxModule], templateUrl: './selectable-card.component.html', styleUrl: './selectable-card.component.scss' }) export class SelectableCardComponent extends FieldBase implements OnInit { @Input() type: string; @Output() valueChange: EventEmitter = new EventEmitter(); configProps$: SelectableCardProps; readOnly = false; disabled = false; radioBtnValue; additionalProps; showNoValue = false; selectionKey?: string; defaultStyle = {}; specialStyle = {}; cardStyle = {}; noLabelStyle: {}; selectedvalues: any; selectionList: any; primaryField: string; commonProps: any = {}; contentList: [ { commonCardProps: { id: string; key: string; fields: any; label: string; selected: boolean }; cardImage: { src: string; alt: string; style: any }; } ]; override ngOnInit(): void { super.ngOnInit(); // styles used in displaying common field props this.defaultStyle = { display: 'grid', gridTemplateColumns: '1fr 1fr', margin: '0.5rem', wordBreak: 'break-word', fontSize: '0.875rem' }; this.specialStyle = { margin: '0.5rem', fontSize: '0.875rem' }; this.noLabelStyle = { alignItems: 'start', marginLeft: '0.5rem' }; } override updateSelf(): void { this.configProps$ = this.pConn$.resolveConfigProps(this.pConn$.getConfigProps()) as SelectableCardProps; const hideFieldLabels = this.configProps$.hideFieldLabels; const datasource: any = this.configProps$.datasource; const additionalProps: any = this.configProps$.additionalProps; const imageSize: string = this.configProps$.imageSize ?? ''; // not using const showImageDescription: boolean = this.configProps$.showImageDescription ?? false; let recordKey = ''; let cardLabel = ''; let image: any; this.disabled = this.configProps$.disabled; this.readOnly = this.configProps$.renderMode === 'ReadOnly' || this.displayMode$ === 'DISPLAY_ONLY' || this.configProps$.readOnly; const imagePosition = this.configProps$.imagePosition; // dynamic styling based on image position and readOnly option let imageWidth = '100%'; this.cardStyle = { display: 'flex', flexDirection: 'column', height: '100%' }; if (imagePosition && imagePosition !== 'block-start') { imageWidth = '30%'; if (imagePosition === 'inline-start') { this.cardStyle = { display: 'flex', flexDirection: 'row', alignItems: this.readOnly ? 'center' : '' }; } else if (imagePosition === 'inline-end') { this.cardStyle = { display: 'flex', flexDirection: 'row-reverse', justifyContent: this.readOnly ? 'space-between' : '', alignItems: this.readOnly ? 'center' : '' }; } } if (this.type === 'radio') { const stateProps = this.pConn$.getStateProps(); image = { imagePosition, imageSize, showImageDescription, imageField: stateProps.image?.split('.').pop(), imageDescription: stateProps.imageDescription?.split('.').pop() }; recordKey = stateProps.value?.split('.').pop() ?? ''; cardLabel = stateProps.primaryField?.split('.').pop() ?? ''; this.value$ = this.configProps$.value; this.radioBtnValue = this.value$; } if (this.type === 'checkbox') { this.testId = this.configProps$.testId; this.displayMode$ = this.configProps$.displayMode ?? ''; this.selectionKey = this.configProps$.selectionKey; recordKey = this.selectionKey?.split('.').pop() ?? ''; cardLabel = this.configProps$.primaryField.split('.').pop() ?? ''; image = { imagePosition, imageSize, showImageDescription, imageField: this.configProps$.image?.split('.').pop(), imageDescription: (this.pConn$?.getRawMetadata()?.config as any).imageDescription?.split('.').pop() }; this.selectionList = this.configProps$.selectionList; this.selectedvalues = this.configProps$.readonlyContextList; this.showNoValue = this.readOnly && this.selectedvalues?.length === 0; // not used this.primaryField = this.configProps$.primaryField; } this.commonProps = { hideFieldLabels, datasource, additionalProps, image, recordKey, cardLabel, radioBtnValue: this.radioBtnValue ?? '' }; const imageDescriptionKey = this.commonProps?.image?.showImageDescription ? this.commonProps?.image?.imageDescription : undefined; const cardDataSource = this.readOnly || this.displayMode$ == 'DISPLAY_ONLY' ? this.selectedvalues || [] : this.commonProps?.datasource?.source; this.contentList = cardDataSource.map(item => { const resolvedFields = this.utils.resolveReferenceFields(item, this.commonProps.hideFieldLabels, this.commonProps.recordKey, this.pConn$); const commonCardProps = { id: item[this.commonProps.recordKey], key: item[this.commonProps.recordKey], fields: resolvedFields, label: item[this.commonProps.cardLabel], selected: this.selectedvalues ? this.selectedvalues?.some?.(data => data[this.commonProps.recordKey] === item[this.commonProps.recordKey]) : false }; const cardImage = item[this.commonProps.image.imageField] ? { src: item[this.commonProps.image.imageField], alt: this.commonProps.image.showImageDescription && imageDescriptionKey ? item[imageDescriptionKey] : '', style: { width: imageWidth, backgroundColor: 'transparent', aspectRatio: '16/9', maxHeight: '100%', objectFit: 'contain', maxWidth: '100%', height: this.readOnly && imagePosition !== 'block-start' ? '5rem' : '' } } : undefined; return { cardImage, commonCardProps }; }); } fieldOnChange(value: any) { handleEvent(this.actionsApi, 'changeNblur', this.propName, value); } fieldOnBlur() { this.pConn$.getValidationApi().validate(this.selectedvalues, this.selectionList); } handleChangeMultiMode(event, element) { if (!element.selected) { insertInstruction(this.pConn$, this.selectionList, this.selectionKey, this.primaryField, { id: element.id, primary: element.label }); } else { deleteInstruction(this.pConn$, this.selectionList, this.selectionKey, { id: element.key, primary: element.label }); } this.pConn$.clearErrorMessages({ property: this.selectionList, category: '', context: '' }); } cardSelect(event, element) { if (this.type === 'radio') { this.fieldOnChange(element.key); } else if (this.type === 'checkbox') { this.handleChangeMultiMode(event, element); } } }