Skip to content

Commit

Permalink
Sync repo from v92 to v92 20240812072532 (#169)
Browse files Browse the repository at this point in the history
* Automated sync from source branch v92

* Readme updated

* binaries reset

* readme fixed

---------

Co-authored-by: imx-sync-bot <imx-sync-bot@oneidentity>
  • Loading branch information
Martina-Graeber-One-Identity and imx-sync-bot authored Aug 19, 2024
1 parent cf9abc6 commit b489b3b
Show file tree
Hide file tree
Showing 18 changed files with 224 additions and 174 deletions.
2 changes: 1 addition & 1 deletion .commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
a389dcd952875866288789039304ce0360b6d655
d7376dc1bc7c9b8080948907c5bb14befb21039c
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@

## Change log

### August 12, 2024
- 459770: Fixed an issue where the request parameter validation result was not working on first input.
- 462048: Fixed an issue with delegation search caching.
- 461659: Fixed an issue regarding delegation or ESet requests on the Request History page.
- 460151: Fixed an issue with the QueryWhereClause evaluation during the value check on updated parameter.
- 460511: Fixed an issue that causes the side navigation on New Request to show search results twice.
- 461414: Fixed the scrollability of the Operation Support Portal's Process view
- 462785: Fixed an UI issue regarding the alignment for the column "User account is disabled" and its data.


### July 30, 2024

The v92 branch has been updated with fixes for the following issues.
Expand Down
92 changes: 35 additions & 57 deletions imxweb/projects/qbm/src/lib/cdr/edit-fk/edit-fk.component.html
Original file line number Diff line number Diff line change
@@ -1,85 +1,63 @@
<mat-form-field appearance="outline" *ngIf="hasCandidatesOrIsLoading && columnContainer?.canEdit; else noCandidatesAvailOrReadonly">
<mat-form-field appearance="outline"
*ngIf="hasCandidatesOrIsLoading && columnContainer?.canEdit; else noCandidatesAvailOrReadonly">
<mat-label>
{{ columnContainer?.display | translate }}
<ng-container *ngIf="selectedTable && columnContainer?.fkRelations?.length > 1 && !isHierarchical">
({{ '#LDS#Table: {0}' | translate | ldsReplace : metadataProvider.tables[selectedTable.TableName]?.DisplaySingular || selectedTable.TableName }})
({{ '#LDS#Table: {0}' | translate | ldsReplace : metadataProvider.tables[selectedTable.TableName]?.DisplaySingular
|| selectedTable.TableName }})
</ng-container>
</mat-label>
<eui-icon icon="search" *ngIf="columnContainer?.canEdit && auto.isOpen" matPrefix></eui-icon>

<input
#inputControl
matInput
type="search"
[formControl]="control"
[matAutocomplete]="auto"
[readonly]="!columnContainer?.canEdit || isHierarchical"
(keydown.esc)="close($event); inputControl.blur()"
(focusout)="close($event)"
(focus)="inputFocus()"
<input #inputControl matInput type="search" [formControl]="control" [matAutocomplete]="auto"
[readonly]="!columnContainer?.canEdit || isHierarchical" (keydown.esc)="close($event); inputControl.blur()"
(focusout)="close($event)" (focus)="inputFocus()"
[attr.data-imx-identifier]="'cdr-edit-fk-input-search-candidates-' + columnContainer?.name"
[required]="columnContainer.isValueRequired"
/>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="getDisplay" (optionSelected)="optionSelected($event); inputControl.blur()" (opened)="onOpened()" #autocomplete>
<mat-option
*ngFor="let candidate of candidates; index as i; trackBy: candidateTrackByFn"
[value]="candidate"
class="imx-candidate-option"
[attr.data-imx-identifier]="'cdr-edit-fk-mat-option-assign-candidate-' + columnContainer?.name"
>
<div class="imx-candidate-item">
<div class="imx-candidate-content">
<div class="imx-candidate-display">{{ getDisplay(candidate) }}</div>
<div *ngIf="getDisplay(candidate) !== candidate.displayLong" class="imx-candidate-longdisplay">
{{ candidate.displayLong }}
[required]="columnContainer.isValueRequired" />
<mat-autocomplete #auto="matAutocomplete" [displayWith]="getDisplay"
(optionSelected)="optionSelected($event); inputControl.blur()" (opened)="onOpened()" #autocomplete>
<ng-container *ngIf="!loading">
<mat-option *ngFor="let candidate of candidates; index as i; trackBy: candidateTrackByFn" [value]="candidate"
class="imx-candidate-option"
[attr.data-imx-identifier]="'cdr-edit-fk-mat-option-assign-candidate-' + columnContainer?.name">
<div class="imx-candidate-item">
<div class="imx-candidate-content">
<div class="imx-candidate-display">{{ getDisplay(candidate) }}</div>
<div *ngIf="getDisplay(candidate) !== candidate.displayLong" class="imx-candidate-longdisplay">
{{ candidate.displayLong }}
</div>
</div>
</div>
</div>
</mat-option>
<mat-option *ngIf="loading" disabled>{{ '#LDS#Loading...' | translate }}</mat-option>
</mat-option>
</ng-container>
<mat-option *ngIf="loading" disabled>{{ '#LDS#Loading...' | translate }}</mat-option>
</mat-autocomplete>
<div matSuffix class="imx-suffix-container">
<mat-spinner diameter="30" *ngIf="loading"></mat-spinner>
<eui-icon
*ngIf="columnContainer?.canEdit && control.value && !loading"
icon="close"
class="imx-icon-delete"
<eui-icon *ngIf="columnContainer?.canEdit && control.value && !loading" icon="close" class="imx-icon-delete"
(click)="removeAssignment($event)"
[attr.data-imx-identifier]="'cdr-edit-fk-button-remove-assignment-' + columnContainer?.name"
></eui-icon>
[attr.data-imx-identifier]="'cdr-edit-fk-button-remove-assignment-' + columnContainer?.name"></eui-icon>
<div class="imx-spacer"></div>
<button
*ngIf="columnContainer?.canEdit && (isHierarchical || columnContainer?.fkRelations?.length > 1)"
mat-button
color="primary"
type="button"
(click)="editAssignment($event)"
[attr.data-imx-identifier]="'cdr-edit-fk-button-open-picker-' + columnContainer?.name"
>
<button *ngIf="columnContainer?.canEdit && (isHierarchical || columnContainer?.fkRelations?.length > 1)" mat-button
color="primary" type="button" (click)="editAssignment($event)"
[attr.data-imx-identifier]="'cdr-edit-fk-button-open-picker-' + columnContainer?.name">
{{ columnContainer?.value?.length ? ('#LDS#Change' | translate) : ('#LDS#Select' | translate) }}
</button>
</div>
<mat-error *ngIf="control.errors?.checkAutocomplete">
{{ '#LDS#The value entered in the {0} box could not be found. Please select a value from the list.' | translate | ldsReplace : (columnContainer?.display | translate) }}
{{ '#LDS#The value entered in the {0} box could not be found. Please select a value from the list.' | translate |
ldsReplace : (columnContainer?.display | translate) }}
</mat-error>
<mat-error *ngIf="control.errors?.['required']">
{{ '#LDS#This field is mandatory.' | translate }}
</mat-error>
</mat-form-field>

<ng-template #noCandidatesAvailOrReadonly>
<imx-view-property
*ngIf="columnContainer?.canEdit"
[columnContainer]="columnContainer"
defaultValue="#LDS#No data"
[attr.data-imx-identifier]="'cdr-edit-fk-no-candidates-' + columnContainer?.name"
>
<imx-view-property *ngIf="columnContainer?.canEdit" [columnContainer]="columnContainer" defaultValue="#LDS#No data"
[attr.data-imx-identifier]="'cdr-edit-fk-no-candidates-' + columnContainer?.name">
</imx-view-property>
<imx-view-property
*ngIf="!columnContainer?.canEdit"
[columnContainer]="columnContainer"
defaultValue="#LDS#Not set"
[attr.data-imx-identifier]="'cdr-edit-fk-candidates-readonly-' + columnContainer?.name"
>
<imx-view-property *ngIf="!columnContainer?.canEdit" [columnContainer]="columnContainer" defaultValue="#LDS#Not set"
[attr.data-imx-identifier]="'cdr-edit-fk-candidates-readonly-' + columnContainer?.name">
</imx-view-property>
</ng-template>
</ng-template>
30 changes: 20 additions & 10 deletions imxweb/projects/qbm/src/lib/cdr/edit-fk/edit-fk.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,15 @@ export class EditFkComponent implements CdrEditor, AfterViewInit, OnDestroy, OnI
/**
* A list of possible candidates, that can be selected.
*/
public candidates: Candidate[];
private _candidates: Candidate[];

public get candidates(): Candidate[] {
return this._candidates;
}

public set candidates(value: Candidate[]) {
this._candidates = value;
}

/**
* Indicator that the component is loading data from the server.
Expand Down Expand Up @@ -211,7 +219,7 @@ export class EditFkComponent implements CdrEditor, AfterViewInit, OnDestroy, OnI
public async onOpened(): Promise<void> {
// Use the stashed values if we already have a selected value
this.parameters = this.savedParameters ?? { PageSize: this.pageSize, StartIndex: 0 };
if ((this.savedCandidates?.length ?? 0) > 0) {
if (!!this.savedCandidates?.length) {
this.candidates = this.savedCandidates;
} else if (this.parameters.search || this.parameters.filter || this.control.value == null) {
await this.updateCandidates({ search: undefined, filter: undefined, StartIndex: 0 }, false);
Expand Down Expand Up @@ -485,10 +493,10 @@ export class EditFkComponent implements CdrEditor, AfterViewInit, OnDestroy, OnI
const multipleFkRelations = this.columnContainer.fkRelations && this.columnContainer.fkRelations.length > 1;
const identityRelatedTable = this.selectedTable.TableName === 'Person';

const newCandidates = candidateCollection.Entities.map((entityData) => {
let key: string = null;
let detailValue: string = entityData.LongDisplay;
const defaultEmailColumn = entityData.Columns['DefaultEmailAddress'];
const newCandidates = candidateCollection.Entities?.map((entityData) => {
let key: string = '';
let detailValue: string = entityData.LongDisplay ?? '';
const defaultEmailColumn = entityData.Columns?.['DefaultEmailAddress'];
/**
* If the candidates data relate to identities (fkRelation Person table)
* then we want to use the email address for the detail line (displayLong)
Expand All @@ -498,7 +506,7 @@ export class EditFkComponent implements CdrEditor, AfterViewInit, OnDestroy, OnI
}
if (multipleFkRelations) {
this.logger.trace(this, 'dynamic foreign key');
const xObjectKeyColumn = entityData.Columns['XObjectKey'];
const xObjectKeyColumn = entityData.Columns?.['XObjectKey'];
key = xObjectKeyColumn ? xObjectKeyColumn.Value : undefined;
} else {
this.logger.trace(this, 'foreign key');
Expand All @@ -510,7 +518,7 @@ export class EditFkComponent implements CdrEditor, AfterViewInit, OnDestroy, OnI
} else {
this.logger.trace(this, 'Use the primary key');
const keys = entityData.Keys;
key = keys && keys.length ? keys[0] : undefined;
key = keys && keys.length ? keys[0] : '';
}
}
return {
Expand All @@ -520,9 +528,11 @@ export class EditFkComponent implements CdrEditor, AfterViewInit, OnDestroy, OnI
};
});
if (concatCandidates) {
this.candidates.push(...newCandidates);
this.candidates.push(...(newCandidates || []));
this.savedCandidates = this.candidates;
} else {
this.candidates = newCandidates;
this.candidates = newCandidates || [];
this.savedCandidates = this.candidates;
}
} finally {
this.loading = false;
Expand Down
45 changes: 29 additions & 16 deletions imxweb/projects/qbm/src/lib/cdr/editor-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*
*/
import { OnDestroy, Component, EventEmitter, ErrorHandler } from '@angular/core';
import { AbstractControl, Validators } from '@angular/forms';
import { AbstractControl, ValidatorFn, Validators } from '@angular/forms';
import { Subject, Subscription } from 'rxjs';

import { CdrEditor, ValueHasChangedEventArg } from './cdr-editor.interface';
Expand Down Expand Up @@ -73,7 +73,7 @@ export abstract class EditorBase<T = any> implements CdrEditor, OnDestroy {
* @ignore
* Used for the template and displays the last server error, that occured while loading content.
*/
public lastError: ServerError;
public lastError: ServerError | undefined;

/**
* The maximal length a string could have.
Expand All @@ -99,21 +99,20 @@ export abstract class EditorBase<T = any> implements CdrEditor, OnDestroy {
* If an error occured, it returns its message
*/
public get validationErrorMessage(): string {
if (this.control.errors?.['generalError']) {
return this.lastError.toString();
}
return undefined;
return this.lastError?.toString() || '';
}

/**
* Binds a column dependent reference to the component, by setting the control value and subscribing to the events,
* the CDR or the ColumnContainer emits
* the CDR or the ColumnContainer emits
* @param cdref a column dependent reference
*/
public bind(cdref: ColumnDependentReference): void {
if (cdref && cdref.column) {
this.columnContainer.init(cdref);

this.control.addValidators(EditorBase.hasServerError(this));

this.setControlValue();

this.subscribers.push(this.control.valueChanges.subscribe(async (value) => this.writeValue(value)));
Expand All @@ -133,7 +132,7 @@ export abstract class EditorBase<T = any> implements CdrEditor, OnDestroy {
return;
}

if (this.control.value !== this.columnContainer.value) {
if (!this.control.hasError('generalError') && this.control.value !== this.columnContainer.value) {
this.logger.trace(
this,
`Control (${this.columnContainer.name}) set to new value:`,
Expand All @@ -150,8 +149,16 @@ export abstract class EditorBase<T = any> implements CdrEditor, OnDestroy {
this.updateRequested.subscribe(() => {
setTimeout(() => {
try {
this.setControlValue();
this.control.updateValueAndValidity({ onlySelf: true, emitEvent: false });
if (!this.control.hasError('generalError') && this.control.value !== this.columnContainer.value) {
this.logger.trace(
this,
`Control (${this.columnContainer.name}) set to new value:`,
this.columnContainer.value,
this.control.value
);
this.setControlValue();
this.control.updateValueAndValidity({ onlySelf: true, emitEvent: false });
}
} finally {
}
this.valueHasChanged.emit({ value: this.control.value });
Expand All @@ -176,9 +183,9 @@ export abstract class EditorBase<T = any> implements CdrEditor, OnDestroy {
this.columnContainer.type !== ValType.Bool // because bool is always valid
) {
this.logger.debug(this, `A value for column "${this.columnContainer.name}" is required`);
this.control.setValidators(Validators.required);
this.control.setValidators([Validators.required, EditorBase.hasServerError(this)]);
} else {
this.control.setValidators(null);
this.control.setValidators(EditorBase.hasServerError(this));
}
}

Expand All @@ -187,11 +194,10 @@ export abstract class EditorBase<T = any> implements CdrEditor, OnDestroy {
* @param value the new value
*/
private async writeValue(value: any): Promise<void> {
if (this.control.errors) {
this.logger.debug(this, 'writeValue - validation failed');
if (this.control.errors && Object.keys(this.control.errors).some((elem) => elem !== 'generalError')) {
this.logger.debug(this, 'writeValue - client validation failed');
return;
}

this.logger.debug(this, 'writeValue called with value', value);

if (!this.columnContainer.canEdit || this.columnContainer.value === value) {
Expand All @@ -203,10 +209,11 @@ export abstract class EditorBase<T = any> implements CdrEditor, OnDestroy {
try {
this.logger.debug(this, 'writeValue - PutValue...');
await this.columnContainer.updateValue(value);
this.lastError = undefined;
} catch (e) {
this.lastError = e;
this.logger.error(this, e);
this.control.setErrors({ generalError: true });
this.control.updateValueAndValidity({ emitEvent: true });
} finally {
this.isBusy = false;
this.isWriting = false;
Expand All @@ -218,4 +225,10 @@ export abstract class EditorBase<T = any> implements CdrEditor, OnDestroy {

this.valueHasChanged.emit({ value, forceEmit: true });
}

private static hasServerError(base: any): ValidatorFn {
return (_: AbstractControl): { [key: string]: boolean } | null => {
return !base.lastError ? null : { generalError: true };
};
}
}
11 changes: 7 additions & 4 deletions imxweb/projects/qbm/src/lib/cdr/entity-column-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
*
*/

import { IForeignKeyInfo, IValueMetadata, ValType, ValueConstraint, ValueStruct } from 'imx-qbm-dbts';
import { Subscription } from 'rxjs';
import { ValueWrapper } from '../value-wrapper/value-wrapper';
import { ColumnDependentReference } from './column-dependent-reference.interface';
import { ValueStruct, IForeignKeyInfo, ValType, ValueConstraint, IValueMetadata } from 'imx-qbm-dbts';
import { LimitedValuesContainer } from './limited-values-container';
import { ValueWrapper } from '../value-wrapper/value-wrapper';
import { Subscription } from 'rxjs';

/**
* An implementation of the {@link ValueWrapper} interface.
Expand Down Expand Up @@ -113,6 +113,10 @@ export class EntityColumnContainer<T = any> implements ValueWrapper<T> {
return this.cdr?.hint;
}

public get showDisplayValue(): boolean {
return !!this.metaData?.CanSee();
}

/**
* An container, that wraps limited value functionality
*/
Expand Down Expand Up @@ -141,7 +145,6 @@ export class EntityColumnContainer<T = any> implements ValueWrapper<T> {
return new Subscription(() => subscription?.unsubscribe());
}


/**
* Updates the value and puts it into the column
* @param value The new value for the column
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="imx-readonly-view" readonly>
<span class="column-display">{{ (columnContainer?.display | translate) + (columnContainer.isValueRequired ? '*' :'') }}</span>
<span class="column-value">{{ displayedValue | translate }}</span>
<span class="column-display">{{ (columnContainer?.display | translate) + (columnContainer.isValueRequired ? '*' : '') }}</span>
<span class="column-value">{{ columnContainer.showDisplayValue ? (displayedValue | translate) : '' }}</span>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -1313,18 +1313,18 @@ export class DataSourceToolbarComponent implements OnChanges, OnInit, OnDestroy
this.columnOptions?.resetView();

this.searchTerms = [];
if (this.settings.navigationState.search) {
if (this.settings.navigationState?.search) {
this.searchControl.reset(null);
delete this.settings.navigationState.search;
}
if (this.settings.navigationState.OrderBy) {
if (this.settings.navigationState?.OrderBy) {
delete this.settings.navigationState.OrderBy;
this.clearSort(false);
}
if (this.settings?.groupData?.currentGrouping) {
this.clearGroupedBy(false);
}
delete this.settings.navigationState.filter;
delete this.settings.navigationState?.filter;
if (this.filtersCurrentlyApplied) {
this.clearFilters(false);
}
Expand Down
Loading

0 comments on commit b489b3b

Please sign in to comment.