description filters

This commit is contained in:
Sofia Papacharalampous 2024-06-24 15:47:34 +03:00
parent 831031b2ef
commit 656fe630ca
17 changed files with 388 additions and 211 deletions

View File

@ -6,6 +6,8 @@ import { DmpLookup } from './dmp.lookup';
import { DmpUserRole } from '../common/enum/dmp-user-role';
import { DescriptionTag } from '../model/description/description';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { ReferenceType } from '../model/reference-type/reference-type';
import { Reference } from '../model/reference/reference';
export class DescriptionLookup extends Lookup implements DescriptionFilter {
ids: Guid[];
@ -24,32 +26,11 @@ export class DescriptionLookup extends Lookup implements DescriptionFilter {
associatedDmpIds: Guid[]; //TODO
roleInDmp: DmpUserRole[]; //TODO
tags: DescriptionTag[]; //TODO
references: ReferenceAndTypeLookup[]; //TODO
constructor() {
super();
}
from(formGroup: UntypedFormGroup): void {
if (!formGroup) return;
this.statuses = formGroup.get("status")?.value ? [formGroup.get("status")?.value] : [];
this.showAllVersions = formGroup.get("showAllVersions")?.value ?? false;
this.roleInDmp = formGroup.get("role")?.value ? [formGroup.get("role")?.value] : [];
this.tags = formGroup.get("tags")?.value ?? [];
this.associatedDmpIds = formGroup.get("associatedDmpIds")?.value ?? [];
this.descriptionTemplateIds = formGroup.get("descriptionTemplates")?.value ?? [];
}
buildForm(): UntypedFormGroup {
return (new UntypedFormBuilder()).group({
status: [this.statuses?.length > 0 ? this.statuses[0] : null],
role: [this.roleInDmp?.length > 0 ? this.roleInDmp[0] : null],
showAllVersions: [this.showAllVersions ?? false],
descriptionTemplates: [this.descriptionTemplateIds],
associatedDmpIds: [this.associatedDmpIds],
tags: [this.tags],
});
}
}
export interface DescriptionFilter {
@ -63,11 +44,15 @@ export interface DescriptionFilter {
dmpSubQuery: DmpLookup;
isActive: IsActive[];
statuses: DescriptionStatus[];
showAllVersions: boolean; //TODO
descriptionTemplateIds: Guid[]; //TODO
associatedDmpIds: Guid[]; //TODO
roleInDmp: DmpUserRole[]; //TODO
tags: DescriptionTag[]; //TODO
//TODO: dynamic reference-types
showAllVersions: boolean;
descriptionTemplateIds: Guid[];
associatedDmpIds: Guid[];
roleInDmp: DmpUserRole[];
tags: DescriptionTag[];
references: ReferenceAndTypeLookup[];
}
export interface ReferenceAndTypeLookup {
referenceType: ReferenceType;
references: Reference[];
}

View File

@ -103,6 +103,19 @@ export class ReferenceTypeService {
valueAssign: (item: ReferenceType) => item.id,
};
public getSingleAutocompleteConfiguration(excludedIds: Guid[] = null): SingleAutoCompleteConfiguration {
return {
initialItems: (data?: any) => this.query(this.buildAutocompleteLookup(null, excludedIds)).pipe(map(x => x.items)),
filterFn: (searchQuery: string, data?: any) => this.query(this.buildAutocompleteLookup(searchQuery, excludedIds)).pipe(map(x => x.items)),
getSelectedItem: (selectedItem: ReferenceType) => this.query(this.buildAutocompleteLookup(null, null, [selectedItem.id])).pipe(map(x => x.items[0])),
displayFn: (item: ReferenceType) => item.name,
titleFn: (item: ReferenceType) => item.name,
valueAssign: (item: ReferenceType) => item,
uniqueAssign: (item: ReferenceType) => JSON.stringify(item),
loadDataOnStart: false
};
}
private buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): ReferenceTypeLookup {
const lookup: ReferenceTypeLookup = new ReferenceTypeLookup();
lookup.page = { size: 100, offset: 0 };

View File

@ -1,10 +1,9 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { FormBuilder, UntypedFormArray, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
@ -15,7 +14,7 @@ import { Dmp, DmpDescriptionTemplate, DmpUser } from '@app/core/model/dmp/dmp';
import { DmpReference } from '@app/core/model/dmp/dmp-reference';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { Reference } from '@app/core/model/reference/reference';
import { DescriptionFilter, DescriptionLookup } from '@app/core/query/description.lookup';
import { DescriptionLookup } from '@app/core/query/description.lookup';
import { AuthService } from '@app/core/services/auth/auth.service';
import { DescriptionService } from '@app/core/services/description/description.service';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
@ -105,6 +104,7 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
protected route: ActivatedRoute,
protected uiNotificationService: UiNotificationService,
protected queryParamsService: QueryParamsService,
protected formBuilder: FormBuilder,
) {
super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService);
}
@ -170,7 +170,7 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
const lookup = new DescriptionLookup();
lookup.metadata = { countAll: true };
lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE };
lookup.statuses = [DescriptionStatus.Draft, DescriptionStatus.Finalized]
// lookup.statuses = [DescriptionStatus.Draft, DescriptionStatus.Finalized, DescriptionStatus.Canceled]
lookup.isActive = [IsActive.Active];
let recentActivityOrder = this.isPublic ? this.toAscSortField(nameof<Description>(x => x.label)) : this.toDescSortField(nameof<Description>(x => x.updatedAt));
@ -213,7 +213,6 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
}
controlModified(): void {
this.lookup.like = this.formGroup.get("like").value;
this.lookup.page = { size: this.pageSize, offset: 0 };
this.filterChanged(this.lookup, true);
@ -247,16 +246,20 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
panelClass: 'dialog-side-panel',
data: {
isPublic: this.isPublic ?? true,
filterForm: this.lookup.buildForm(),
updateDataFn: this.updateDataFn.bind(this)
filterForm: this._buildFormFromLookup(this.lookup),
}
});
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) {
this.updateDataFn(result);
}
});
}
updateDataFn(filterForm: UntypedFormGroup): void {
let testLookup = this.lookup;
testLookup.from(filterForm);
// console.log('testLookup: ', testLookup);
this.lookup = this._patchLookupFromForm(this.lookup, filterForm);
this.filterChanged(this.lookup)
// this.lookup.from(filterForm);
// this.refresh(this.lookup);
}
@ -341,7 +344,7 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
const queryOffset = 0;
const querySize = (lookup.page?.offset ?? 0) + this.pageSize;
lookup.page = { size: querySize, offset: queryOffset };
lookup.statuses = [DescriptionStatus.Draft, DescriptionStatus.Finalized];
// lookup.statuses = [DescriptionStatus.Draft, DescriptionStatus.Finalized];
lookup.project = { fields: this._lookupFields };
lookup.metadata = { countAll: true };
return lookup;
@ -355,6 +358,43 @@ export class DescriptionListingComponent extends BaseListingComponent<BaseDescri
}
}
_patchLookupFromForm(lookup: DescriptionLookup, formGroup: UntypedFormGroup): DescriptionLookup {
if (!formGroup) return;
lookup.statuses = formGroup.get("status")?.value !== null ? [formGroup.get("status")?.value] : null;
lookup.showAllVersions = formGroup.get("showAllVersions")?.value ?? false;
lookup.roleInDmp = formGroup.get("role")?.value !== null ? [formGroup.get("role")?.value] : null;
lookup.tags = formGroup.get("tags")?.value ?? null;
lookup.associatedDmpIds = formGroup.get("associatedDmpIds")?.value ?? null;
lookup.descriptionTemplateIds = formGroup.get("descriptionTemplates")?.value ?? null;
lookup.references = formGroup.get("references")?.value?.filter(reference => reference.referenceType != null && reference.references?.length > 0) ?? null;
return lookup;
}
_buildFormFromLookup(lookup: DescriptionLookup): UntypedFormGroup {
const formArray = this.formBuilder.array([]) as UntypedFormArray;
lookup.references?.forEach(reference => {
let referenceForm = this.formBuilder.group({
referenceType: reference.referenceType,
references: reference.references?.length > 0 ? [reference.references] : []
});
formArray.push(referenceForm);
});
return (new UntypedFormBuilder()).group({
status: [lookup.statuses?.length > 0 ? lookup.statuses[0] : null],
role: [lookup.roleInDmp?.length > 0 ? lookup.roleInDmp[0] : null],
showAllVersions: [lookup.showAllVersions ?? false],
descriptionTemplates: [lookup.descriptionTemplateIds],
associatedDmpIds: [lookup.associatedDmpIds],
tags: [lookup.tags],
references: formArray
});
}
private get _lookupFields(): string[] {
return [
nameof<Description>(x => x.id),

View File

@ -21,7 +21,6 @@ export class DescriptionFilterDialogComponent implements OnInit {
isPublic: boolean,
status: Number,
filterForm: UntypedFormGroup,
updateDataFn: Function,
}
) {
}
@ -39,6 +38,6 @@ export class DescriptionFilterDialogComponent implements OnInit {
}
onFilterChanged(formGroup: UntypedFormGroup) {
this.data.updateDataFn(formGroup);
this.dialogRef.close(formGroup);
}
}

View File

@ -7,47 +7,20 @@
</div>
</div>
<div class="row justify-content-center" *ngIf="formGroup">
<!-- Search Filter-->
<!-- <mat-form-field class="col-11 search">
<input matInput placeholder="{{'CRITERIA.GRANTS.LIKE'| translate}}" name="grantCriteriaLike"
[formControl]="formGroup.get('like')">
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">
{{formGroup.get('like').getError('backendError').message}}</mat-error>
<mat-icon matSuffix class="style-icon">search</mat-icon>
</mat-form-field> -->
<!-- End of Search Filter -->
<!-- Status Filter-->
<div class="col-10" *ngIf="!isPublic">
<h6 class="category-title">{{ 'DESCRIPTION-LISTING.FILTERS.STATUS.NAME' | translate}}</h6>
<mat-radio-group aria-label="Select an option" [formControl]="formGroup.get('status')" class="row">
<mat-radio-button value="null" [checked]="!formGroup.get('status').value" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.STATUS.TYPES.ANY' | translate }}</mat-radio-button>
<mat-radio-button value="0" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.STATUS.TYPES.DRAFT' | translate }}</mat-radio-button>
<mat-radio-button value="1" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.STATUS.TYPES.FINALIZED' | translate }}</mat-radio-button>
<mat-radio-button [value]="null" [checked]="formGroup.get('status')?.value == null" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.STATUS.TYPES.ANY' | translate }}</mat-radio-button>
<mat-radio-button [value]="statuses.Draft" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.STATUS.TYPES.DRAFT' | translate }}</mat-radio-button>
<mat-radio-button [value]="statuses.Finalized" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.STATUS.TYPES.FINALIZED' | translate }}</mat-radio-button>
<mat-radio-button [value]="statuses.Canceled" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.STATUS.TYPES.CANCELED' | translate }}</mat-radio-button>
</mat-radio-group>
<hr>
</div>
<!-- End of Status Filter-->
<!-- Grant Status -->
<!-- TODO -->
<!-- <div class="col-10" *ngIf="isPublic">
<h6 class="category-title">{{ 'FACET-SEARCH.GRANT-STATUS.TITLE' | translate }}</h6>
<mat-radio-group [formControl]="formGroup.get('grantStatus')">
<mat-list-item>
<mat-radio-button checked value="null" [checked]="!formGroup.get('grantStatus').value">{{ 'FACET-SEARCH.GRANT-STATUS.OPTIONS.ANY' | translate }}</mat-radio-button>
</mat-list-item>
<mat-list-item>
<mat-radio-button value="0">{{ 'FACET-SEARCH.GRANT-STATUS.OPTIONS.ACTIVE' | translate }}</mat-radio-button>
</mat-list-item>
<mat-list-item>
<mat-radio-button value="1">{{ 'FACET-SEARCH.GRANT-STATUS.OPTIONS.INACTIVE' | translate }}</mat-radio-button>
</mat-list-item>
</mat-radio-group>
<hr>
</div> -->
<!-- End of Grant Status -->
<!-- Related Dataset Templates Filters -->
<div class="col-10">
<h6 class="category-title">{{'DESCRIPTION-LISTING.FILTERS.RELATED-DESCRIPTION-TEMPLATES.NAME' | translate}}</h6>
@ -72,62 +45,27 @@
<!-- All Versions Filter-->
<!-- TODO -->
<div class="col-10" *ngIf="!isPublic">
<!-- <div class="col-10" *ngIf="!isPublic">
<h6 class="category-title">{{'DESCRIPTION-LISTING.FILTERS.ALL-VERSIONS'| translate}}</h6>
<mat-slide-toggle [formControl]="formGroup.get('showAllVersions')"></mat-slide-toggle>
<hr>
</div>
</div> -->
<!-- End of All Versions Filter-->
<!-- Related Grant Filters -->
<!-- <div class="col-10">
<h6 class="category-title">{{'CRITERIA.DATA-SETS.RELATED-GRANT' | translate}}</h6>
<mat-form-field class="mb-4">
<mat-label>{{'CRITERIA.DATA-SETS.SELECT-GRANTS' | translate }}</mat-label>
<app-multiple-auto-complete [formControl]="formGroup.get('grants')" [configuration]="grantAutoCompleteConfiguration">
</app-multiple-auto-complete>
</mat-form-field>
<hr>
</div> -->
<!-- End of Related Grants Filters -->
<!-- Related Collaborators Filters -->
<!-- TODO -->
<!-- <div class="col-10" *ngIf="!isPublic">
<h6 class="category-title">{{'CRITERIA.DATA-SETS.RELATED-COLLABORATORS' | translate}}</h6>
<mat-form-field class="mb-4">
<mat-label>{{'CRITERIA.DATA-SETS.SELECT-COLLABORATORS' | translate }}</mat-label>
<app-multiple-auto-complete [formControl]="formGroup.get('collaborators')" [configuration]="collaboratorsAutoCompleteConfiguration">
</app-multiple-auto-complete>
</mat-form-field>
<hr>
</div> -->
<!-- End of Related Collaborators Filters -->
<!-- Role Filter -->
<div class="col-10" *ngIf="isAuthenticated()">
<h6 class="category-title">{{'DESCRIPTION-LISTING.FILTERS.ROLE.NAME' | translate }}</h6>
<mat-radio-group aria-label="Select an option" [formControl]="formGroup.get('role')" class="row">
<mat-radio-button value="null" [checked]="!formGroup.get('role').value" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.ANY' | translate }}</mat-radio-button>
<mat-radio-button value="null" [checked]="formGroup.get('role').value == null" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.ANY' | translate }}</mat-radio-button>
<mat-radio-button value="0" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.OWNER' | translate }}</mat-radio-button>
<mat-radio-button value="1" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.MEMBER' | translate }}</mat-radio-button>
<mat-radio-button value="1" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.VIEWER' | translate }}</mat-radio-button>
<mat-radio-button value="2" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.DESCRIPTION-CONTRIBUTOR' | translate }}</mat-radio-button>
<mat-radio-button value="3" class="col-12">{{ 'DESCRIPTION-LISTING.FILTERS.ROLE.TYPES.REVIEWER' | translate }}</mat-radio-button>
</mat-radio-group>
<hr>
</div>
<!-- End of Role Filter -->
<!-- Related Organization Filter -->
<!-- <div class="col-10">
<h6 class="category-title">{{'CRITERIA.DATA-SETS.ORGANIZATION' | translate }}</h6>
<mat-form-field class="mb-4">
<mat-label>{{'CRITERIA.DATA-SETS.SELECT-ORGANIZATIONS' | translate}}</mat-label>
<app-multiple-auto-complete [formControl]="formGroup.get('organisations')" [configuration]="organisationAutoCompleteConfiguration">
</app-multiple-auto-complete>
</mat-form-field>
<hr>
</div> -->
<!-- End of Related Organization Filter -->
<!-- Tags Filter -->
<div class="col-10">
<h6 class="category-title">{{'DESCRIPTION-LISTING.FILTERS.TAGS.NAME' | translate }}</h6>
@ -139,52 +77,56 @@
</div>
<!-- End of Tags Filter -->
<!-- Import Button -->
<!-- <div class="col-10 import">
<button class="importButton" mat-raised-button color="primary" (click)="fileSave($event)"
type="button col-auto">
{{'DMP-UPLOAD.ACTIONS.IMPORT' | translate}}
</button>
</div> -->
<!-- Reference Types -->
<div class="col-10 mb-1">
<h6 class="category-title">{{'DESCRIPTION-LISTING.FILTERS.REFERENCE-TYPES.NAME' | translate }}</h6>
<!-- {{ filterFormGroup.get('references')?.value | json }} -->
<ng-container *ngFor="let referenceForm of filterFormGroup.get('references')?.controls; let i=index">
{{ referenceForm.get('referenceTypeId')?.value | json }}
<div class="row">
<div class="col-12">
<mat-form-field class="w-100" *ngIf="referenceForm.get('referenceTypeId')">
<mat-label>{{'DESCRIPTION-LISTING.FILTERS.REFERENCE-TYPES.REFERENCE-TYPE' | translate}}</mat-label>
<app-single-auto-complete [formControl]="referenceForm.get('referenceTypeId')" [configuration]="referenceTypeAutocompleteConfiguration">
</app-single-auto-complete>
</mat-form-field>
</div>
</div>
<div class="row" *ngIf="referenceForm.get('referenceTypeId')?.value && selectReferenceAutocompleteConfiguration(referenceForm.get('referenceTypeId').value.id)">
{{ referenceForm.get('references')?.value | json}}
<div class="col-12">
<mat-form-field class="w-100 mb-2">
<mat-label>{{'DESCRIPTION-LISTING.FILTERS.REFERENCE-TYPES.REFERENCE' | translate}}</mat-label>
<app-multiple-auto-complete [formControl]="referenceForm.get('references')" [configuration]="selectReferenceAutocompleteConfiguration(referenceForm.get('referenceTypeId').value.id)">
</app-multiple-auto-complete>
</mat-form-field>
</div>
</div>
<button mat-icon-button class="col-auto" (click)="deleteRow(i)" type="button">
<mat-icon>delete</mat-icon>
</button>
</ng-container>
<div class="col-10">
<div class="row align-items-center">
<button mat-icon-button color="primary" [disabled]="false" (click)="addReferenceType()">
<mat-icon>add_circle</mat-icon>
</button>
<span>
<span class="mt-1">{{'DESCRIPTION-LISTING.ACTIONS.ADD-REFERENCE-TYPE' | translate}}</span>
</span>
</div>
</div>
</div>
<!-- End of Reference Types -->
<div class="col-auto ml-auto mb-4">
<button class="normal-btn-sm" (click)="controlModified()">
{{'DESCRIPTION-LISTING.FILTERS.APPLY-FILTERS' | translate}}
</button>
</div>
</div>
</div>
</div>
<!-- <form class="dataset-criteria">
<mat-card class="mat-card">
<mat-card-header>
<mat-card-title>
<h4>{{'CRITERIA.FILTERS'| translate}}</h4>
</mat-card-title>
<div class="col"></div>
<button class="importButton" mat-raised-button color="primary" (click)="fileImport($event)" type="button col-auto">
{{'DATASET-UPLOAD.ACTIONS.IMPORT' | translate}}
</button>
</mat-card-header>
<div class="row">
<mat-form-field class="col-md-3">
<input matInput placeholder=" {{'CRITERIA.DATA-SETS.LIKE'| translate}}" name="datasetCriteriaName" [(ngModel)]="criteria.like"
(ngModelChange)="controlModified()">
</mat-form-field>
<mat-form-field class="col-md-3">
<app-multiple-auto-complete placeholder="{{'CRITERIA.DMP.LIKE'| translate}}" name="dmpCriteriaName" [(ngModel)]="criteria.dmpIds"
(ngModelChange)="controlModified()" [configuration]="dmpAutoCompleteConfiguration"></app-multiple-auto-complete>
</mat-form-field>
<mat-form-field class="col-md-3">
<mat-select placeholder=" {{'CRITERIA.DATA-SETS.STATUS'| translate}}" name="datasetCriteriastatus" [(ngModel)]="criteria.status"
(ngModelChange)="controlModified()">
<mat-option [value]="null">{{'CRITERIA.DATA-SETS.NONE'| translate}}</mat-option>
<mat-option [value]="statuses.Draft">{{enumUtils.toDatasetStatusString(statuses.Draft)}}</mat-option>
<mat-option [value]="statuses.Finalized">{{enumUtils.toDatasetStatusString(statuses.Finalized)}}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="col-md-3">
<app-multiple-auto-complete name="datasetCriteriaTags" [(ngModel)]="criteria.tags" (ngModelChange)="controlModified()" placeholder="{{'CRITERIA.DATA-SETS.TAGS' | translate}}"
[configuration]="tagsAutoCompleteConfiguration"></app-multiple-auto-complete>
</mat-form-field>
</div>
</mat-card>
</form> -->

View File

@ -1,15 +1,21 @@
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { FormBuilder, UntypedFormArray, UntypedFormGroup } from '@angular/forms';
import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { Reference } from '@app/core/model/reference/reference';
import { AuthService } from '@app/core/services/auth/auth.service';
import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
import { ReferenceService } from '@app/core/services/reference/reference.service';
import { TagService } from '@app/core/services/tag/tag.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { BaseCriteriaComponent } from '@app/ui/misc/criteria/base-criteria.component';
import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model';
import { Guid } from '@common/types/guid';
import { takeUntil } from 'rxjs/operators';
@Component({
@ -29,18 +35,13 @@ export class DescriptionFilterComponent extends BaseCriteriaComponent implements
statuses = DescriptionStatus;
options: UntypedFormGroup;
selectedReferenceTypes: Guid[];
get tagAutoCompleteConfiguration(): MultipleAutoCompleteConfiguration {
return this.tagService.multipleAutocompleteConfiguration;
};
get descriptionTemplateAutoCompleteConfiguration(): MultipleAutoCompleteConfiguration {
return this.descriptionTemplateTypeService.getMultipleAutoCompleteSearchConfiguration();
};
get dmpAutoCompleteConfiguration(): MultipleAutoCompleteConfiguration {
return this.dmpService.multipleAutocompleteConfiguration;
};
descriptionTemplateAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
dmpAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
tagAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
referenceTypeAutocompleteConfiguration: SingleAutoCompleteConfiguration;
referenceAutocompleteConfiguration: Map<string, MultipleAutoCompleteConfiguration>;
constructor(
public enumUtils: EnumUtils,
@ -48,39 +49,101 @@ export class DescriptionFilterComponent extends BaseCriteriaComponent implements
private descriptionTemplateTypeService: DescriptionTemplateTypeService,
private dmpService: DmpService,
private tagService: TagService,
private referenceService: ReferenceService,
private referenceTypeService: ReferenceTypeService,
private formBuilder: FormBuilder,
) {
super(new ValidationErrorModel());
}
ngOnInit() {
super.ngOnInit();
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['filterFormGroup']) {
this.selectedReferenceTypes = this._buildSelectedReferenceTypes(this.filterFormGroup);
this.descriptionTemplateAutoCompleteConfiguration = this.descriptionTemplateTypeService.getMultipleAutoCompleteSearchConfiguration();
this.dmpAutoCompleteConfiguration = this.dmpService.multipleAutocompleteConfiguration;
this.tagAutoCompleteConfiguration = this.tagService.multipleAutocompleteConfiguration;
this.referenceTypeAutocompleteConfiguration = this.getReferenceTypeAutocompleteConfiguration(this.selectedReferenceTypes);
this.referenceAutocompleteConfiguration = new Map<string, MultipleAutoCompleteConfiguration>();
this.formGroup = this.filterFormGroup;
this.formGroup.get('status')?.valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.controlModified());
this.formGroup.get('role')?.valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.controlModified());
this.formGroup.get('descriptionTemplates')?.valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.controlModified());
this.formGroup.get('associatedDmpIds')?.valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.controlModified());
this.formGroup.get('showAllVersions')?.valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.controlModified());
this.formGroup.get('tags')?.valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.controlModified());
const formArray = this.formGroup.get('references') as UntypedFormArray;
formArray?.controls.forEach(control => {
let referenceTypeId: string = control.get('referenceType')?.value?.id;
if (referenceTypeId && referenceTypeId != '') {
let excludedReferences = control.get('references')?.value ?? [];
let referenceAutocomplete = this.getReferenceAutocompleteConfiguration(Guid.parse(referenceTypeId), excludedReferences);
this.referenceAutocompleteConfiguration.set(referenceTypeId, referenceAutocomplete);
}
control.get('referenceType')?.valueChanges.pipe(takeUntil(this._destroyed))
.subscribe(referenceType => {
this.selectedReferenceTypes = this._buildSelectedReferenceTypes(this.formGroup);
this.referenceTypeAutocompleteConfiguration = this.getReferenceTypeAutocompleteConfiguration(this.selectedReferenceTypes);
if (referenceTypeId && referenceTypeId != '') {
let excludedReferences = control.get('references')?.value ?? [];
let referenceAutocomplete = this.getReferenceAutocompleteConfiguration(Guid.parse(referenceTypeId), excludedReferences);
this.referenceAutocompleteConfiguration.set(referenceTypeId, referenceAutocomplete);
}
control.get('references')?.reset()
});
control.get('references')?.valueChanges.pipe(takeUntil(this._destroyed))
.subscribe(references => {
let referenceAutocomplete = this.getReferenceAutocompleteConfiguration(Guid.parse(referenceTypeId), references ?? []);
this.referenceAutocompleteConfiguration.set(referenceTypeId, referenceAutocomplete);
});
});
}
}
addReferenceType(): void {
if (!this.formGroup.get('references')) this.formGroup.addControl('references', this.formBuilder.array([]));
const formArray = this.formGroup.get('references') as UntypedFormArray;
const referenceForm = this.formBuilder.group({
referenceType: null,
references: []
});
referenceForm?.get('referenceType')?.valueChanges.pipe(takeUntil(this._destroyed))
.subscribe((reference: ReferenceType) => {
this.selectedReferenceTypes = this._buildSelectedReferenceTypes(this.formGroup);
this.referenceTypeAutocompleteConfiguration = this.getReferenceTypeAutocompleteConfiguration(this.selectedReferenceTypes);
referenceForm.get('references')?.reset();
if (reference?.id) {
let referenceAutocomplete = this.getReferenceAutocompleteConfiguration(reference.id, []);
this.referenceAutocompleteConfiguration.set(reference?.id?.toString(), referenceAutocomplete);
}
});
referenceForm.get('references')?.valueChanges.pipe(takeUntil(this._destroyed))
.subscribe(references => {
let referenceTypeId = references?.filter(reference => reference?.type?.id != null)?.first?.type?.id ?? null;
if (!referenceTypeId) return;
let referenceAutocomplete = this.getReferenceAutocompleteConfiguration(referenceTypeId, references ?? []);
this.referenceAutocompleteConfiguration.set(referenceTypeId, referenceAutocomplete);
});
formArray.push(referenceForm);
}
deleteRow(index: number): void {
const formArray = this.formGroup.get('references') as UntypedFormArray;
formArray.removeAt(index);
}
controlModified(): void {
this.clearErrorModel();
this.filterChanged.emit(this.formGroup);
@ -94,4 +157,29 @@ export class DescriptionFilterComponent extends BaseCriteriaComponent implements
isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
getReferenceTypeAutocompleteConfiguration(selectedReferenceTypes: Guid[]): SingleAutoCompleteConfiguration {
return this.referenceTypeService.getSingleAutocompleteConfiguration(selectedReferenceTypes);
};
selectReferenceAutocompleteConfiguration(referenceTypeId: string): MultipleAutoCompleteConfiguration {
return this.referenceAutocompleteConfiguration.get(referenceTypeId);
};
getReferenceAutocompleteConfiguration(referenceTypeId: Guid, excludedIds: Reference[]): MultipleAutoCompleteConfiguration {
let autocomplete = this.referenceService.getMultipleAutoCompleteSearchConfiguration(referenceTypeId, excludedIds);
return autocomplete;
};
private _buildSelectedReferenceTypes(formGroup: UntypedFormGroup): Guid[] {
const formArray = formGroup.get('references') as UntypedFormArray;
let selectedReferenceTypes = [];
formArray.controls.forEach(control => {
let id = control.get('referenceType')?.value?.id;
if (id) selectedReferenceTypes.push(Guid.parse(id));
});
return selectedReferenceTypes;
}
}

View File

@ -837,6 +837,7 @@
"DMP": "Plan",
"EMPTY-LIST": "Hutsik dago oraindik.",
"ACTIONS": {
"ADD-REFERENCE-TYPE": "Add a Reference Type",
"ADD-DESCRIPTION": "Add Description",
"TAKE-A-TOUR": "Do you need help? Take a tour..",
"LOAD-MORE": "Load more",
@ -858,12 +859,14 @@
},
"FILTERS": {
"NAME": "Filters",
"APPLY-FILTERS": "Apply filters",
"STATUS": {
"NAME": "Status",
"TYPES": {
"ANY": "Any",
"DRAFT": "Draft",
"FINALIZED": "Finalized"
"FINALIZED": "Finalized",
"CANCELED": "Canceled"
}
},
"RELATED-DESCRIPTION-TEMPLATES": {
@ -880,9 +883,16 @@
"TYPES": {
"ANY": "Any",
"OWNER": "Owner",
"MEMBER": "Member"
"VIEWER": "Viewer",
"DESCRIPTION-CONTRIBUTOR": "Description Contributor",
"REVIEWER": "Reviewer"
}
},
"REFERENCE-TYPES": {
"NAME": "Reference Types",
"REFERENCE-TYPE": "Select Reference Type",
"REFERENCE": "Select Reference"
},
"TAGS": {
"NAME": "Tags",
"PLACEHOLDER": "Select Tags"

View File

@ -837,6 +837,7 @@
"DMP": "Plan",
"EMPTY-LIST": "Nothing here yet.",
"ACTIONS": {
"ADD-REFERENCE-TYPE": "Add a Reference Type",
"ADD-DESCRIPTION": "Add Description",
"TAKE-A-TOUR": "Do you need help? Take a tour..",
"LOAD-MORE": "Load more",
@ -858,12 +859,14 @@
},
"FILTERS": {
"NAME": "Filters",
"APPLY-FILTERS": "Apply filters",
"STATUS": {
"NAME": "Status",
"TYPES": {
"ANY": "Any",
"DRAFT": "Draft",
"FINALIZED": "Finalized"
"FINALIZED": "Finalized",
"CANCELED": "Canceled"
}
},
"RELATED-DESCRIPTION-TEMPLATES": {
@ -880,9 +883,16 @@
"TYPES": {
"ANY": "Any",
"OWNER": "Owner",
"MEMBER": "Member"
"VIEWER": "Viewer",
"DESCRIPTION-CONTRIBUTOR": "Description Contributor",
"REVIEWER": "Reviewer"
}
},
"REFERENCE-TYPES": {
"NAME": "Reference Types",
"REFERENCE-TYPE": "Select Reference Type",
"REFERENCE": "Select Reference"
},
"TAGS": {
"NAME": "Tags",
"PLACEHOLDER": "Select Tags"

View File

@ -837,6 +837,7 @@
"DMP": "Plan",
"EMPTY-LIST": "Nothing here yet.",
"ACTIONS": {
"ADD-REFERENCE-TYPE": "Add a Reference Type",
"ADD-DESCRIPTION": "Add Description",
"TAKE-A-TOUR": "Do you need help? Take a tour..",
"LOAD-MORE": "Load more",
@ -858,12 +859,14 @@
},
"FILTERS": {
"NAME": "Filters",
"APPLY-FILTERS": "Apply filters",
"STATUS": {
"NAME": "Status",
"TYPES": {
"ANY": "Any",
"DRAFT": "Draft",
"FINALIZED": "Finalized"
"FINALIZED": "Finalized",
"CANCELED": "Canceled"
}
},
"RELATED-DESCRIPTION-TEMPLATES": {
@ -880,12 +883,19 @@
"TYPES": {
"ANY": "Any",
"OWNER": "Owner",
"MEMBER": "Member"
"VIEWER": "Viewer",
"DESCRIPTION-CONTRIBUTOR": "Description Contributor",
"REVIEWER": "Reviewer"
}
},
"TAGS": {
"NAME": "Tags",
"PLACEHOLDER": "Select Tags"
},
"REFERENCE-TYPES": {
"NAME": "Reference Types",
"REFERENCE-TYPE": "Select Reference Type",
"REFERENCE": "Select Reference"
}
}
},

View File

@ -837,6 +837,7 @@
"DMP": "Plan",
"EMPTY-LIST": "Nada todavía por aquí.",
"ACTIONS": {
"ADD-REFERENCE-TYPE": "Add a Reference Type",
"ADD-DESCRIPTION": "Add Description",
"TAKE-A-TOUR": "Do you need help? Take a tour..",
"LOAD-MORE": "Load more",
@ -858,12 +859,14 @@
},
"FILTERS": {
"NAME": "Filters",
"APPLY-FILTERS": "Apply filters",
"STATUS": {
"NAME": "Status",
"TYPES": {
"ANY": "Any",
"DRAFT": "Draft",
"FINALIZED": "Finalized"
"FINALIZED": "Finalized",
"CANCELED": "Canceled"
}
},
"RELATED-DESCRIPTION-TEMPLATES": {
@ -880,9 +883,16 @@
"TYPES": {
"ANY": "Any",
"OWNER": "Owner",
"MEMBER": "Member"
"VIEWER": "Viewer",
"DESCRIPTION-CONTRIBUTOR": "Description Contributor",
"REVIEWER": "Reviewer"
}
},
"REFERENCE-TYPES": {
"NAME": "Reference Types",
"REFERENCE-TYPE": "Select Reference Type",
"REFERENCE": "Select Reference"
},
"TAGS": {
"NAME": "Tags",
"PLACEHOLDER": "Select Tags"

View File

@ -837,6 +837,7 @@
"DMP": "Plan",
"EMPTY-LIST": "Τίποτα ακόμα εδώ.",
"ACTIONS": {
"ADD-REFERENCE-TYPE": "Add a Reference Type",
"ADD-DESCRIPTION": "Add Description",
"TAKE-A-TOUR": "Do you need help? Take a tour..",
"LOAD-MORE": "Load more",
@ -858,12 +859,14 @@
},
"FILTERS": {
"NAME": "Filters",
"APPLY-FILTERS": "Apply filters",
"STATUS": {
"NAME": "Status",
"TYPES": {
"ANY": "Any",
"DRAFT": "Draft",
"FINALIZED": "Finalized"
"FINALIZED": "Finalized",
"CANCELED": "Canceled"
}
},
"RELATED-DESCRIPTION-TEMPLATES": {
@ -880,9 +883,16 @@
"TYPES": {
"ANY": "Any",
"OWNER": "Owner",
"MEMBER": "Member"
"VIEWER": "Viewer",
"DESCRIPTION-CONTRIBUTOR": "Description Contributor",
"REVIEWER": "Reviewer"
}
},
"REFERENCE-TYPES": {
"NAME": "Reference Types",
"REFERENCE-TYPE": "Select Reference Type",
"REFERENCE": "Select Reference"
},
"TAGS": {
"NAME": "Tags",
"PLACEHOLDER": "Select Tags"

View File

@ -837,6 +837,7 @@
"DMP": "Plan",
"EMPTY-LIST": "Ništa još nije dostupno.",
"ACTIONS": {
"ADD-REFERENCE-TYPE": "Add a Reference Type",
"ADD-DESCRIPTION": "Add Description",
"TAKE-A-TOUR": "Do you need help? Take a tour..",
"LOAD-MORE": "Load more",
@ -858,12 +859,14 @@
},
"FILTERS": {
"NAME": "Filters",
"APPLY-FILTERS": "Apply filters",
"STATUS": {
"NAME": "Status",
"TYPES": {
"ANY": "Any",
"DRAFT": "Draft",
"FINALIZED": "Finalized"
"FINALIZED": "Finalized",
"CANCELED": "Canceled"
}
},
"RELATED-DESCRIPTION-TEMPLATES": {
@ -880,9 +883,16 @@
"TYPES": {
"ANY": "Any",
"OWNER": "Owner",
"MEMBER": "Member"
"VIEWER": "Viewer",
"DESCRIPTION-CONTRIBUTOR": "Description Contributor",
"REVIEWER": "Reviewer"
}
},
"REFERENCE-TYPES": {
"NAME": "Reference Types",
"REFERENCE-TYPE": "Select Reference Type",
"REFERENCE": "Select Reference"
},
"TAGS": {
"NAME": "Tags",
"PLACEHOLDER": "Select Tags"

View File

@ -837,6 +837,7 @@
"DMP": "Plan",
"EMPTY-LIST": "Jeszcze nic tu nie ma",
"ACTIONS": {
"ADD-REFERENCE-TYPE": "Add a Reference Type",
"ADD-DESCRIPTION": "Add Description",
"TAKE-A-TOUR": "Do you need help? Take a tour..",
"LOAD-MORE": "Load more",
@ -858,12 +859,14 @@
},
"FILTERS": {
"NAME": "Filters",
"APPLY-FILTERS": "Apply filters",
"STATUS": {
"NAME": "Status",
"TYPES": {
"ANY": "Any",
"DRAFT": "Draft",
"FINALIZED": "Finalized"
"FINALIZED": "Finalized",
"CANCELED": "Canceled"
}
},
"RELATED-DESCRIPTION-TEMPLATES": {
@ -880,9 +883,16 @@
"TYPES": {
"ANY": "Any",
"OWNER": "Owner",
"MEMBER": "Member"
"VIEWER": "Viewer",
"DESCRIPTION-CONTRIBUTOR": "Description Contributor",
"REVIEWER": "Reviewer"
}
},
"REFERENCE-TYPES": {
"NAME": "Reference Types",
"REFERENCE-TYPE": "Select Reference Type",
"REFERENCE": "Select Reference"
},
"TAGS": {
"NAME": "Tags",
"PLACEHOLDER": "Select Tags"

View File

@ -837,6 +837,7 @@
"DMP": "Plan",
"EMPTY-LIST": "Sem informação",
"ACTIONS": {
"ADD-REFERENCE-TYPE": "Add a Reference Type",
"ADD-DESCRIPTION": "Add Description",
"TAKE-A-TOUR": "Do you need help? Take a tour..",
"LOAD-MORE": "Load more",
@ -858,12 +859,14 @@
},
"FILTERS": {
"NAME": "Filters",
"APPLY-FILTERS": "Apply filters",
"STATUS": {
"NAME": "Status",
"TYPES": {
"ANY": "Any",
"DRAFT": "Draft",
"FINALIZED": "Finalized"
"FINALIZED": "Finalized",
"CANCELED": "Canceled"
}
},
"RELATED-DESCRIPTION-TEMPLATES": {
@ -880,9 +883,16 @@
"TYPES": {
"ANY": "Any",
"OWNER": "Owner",
"MEMBER": "Member"
"VIEWER": "Viewer",
"DESCRIPTION-CONTRIBUTOR": "Description Contributor",
"REVIEWER": "Reviewer"
}
},
"REFERENCE-TYPES": {
"NAME": "Reference Types",
"REFERENCE-TYPE": "Select Reference Type",
"REFERENCE": "Select Reference"
},
"TAGS": {
"NAME": "Tags",
"PLACEHOLDER": "Select Tags"

View File

@ -837,6 +837,7 @@
"DMP": "Plan",
"EMPTY-LIST": "Zatiaľ prázdne.",
"ACTIONS": {
"ADD-REFERENCE-TYPE": "Add a Reference Type",
"ADD-DESCRIPTION": "Add Description",
"TAKE-A-TOUR": "Do you need help? Take a tour..",
"LOAD-MORE": "Load more",
@ -858,12 +859,16 @@
},
"FILTERS": {
"NAME": "Filters",
"APPLY-FILTERS": "Apply filters",
"STATUS": {
"NAME": "Status",
"TYPES": {
"ANY": "Any",
"DRAFT": "Draft",
"FINALIZED": "Finalized"
"FINALIZED": "Finalized",
"VIEWER": "Viewer",
"DESCRIPTION-CONTRIBUTOR": "Description Contributor",
"REVIEWER": "Reviewer"
}
},
"RELATED-DESCRIPTION-TEMPLATES": {
@ -883,6 +888,11 @@
"MEMBER": "Member"
}
},
"REFERENCE-TYPES": {
"NAME": "Reference Types",
"REFERENCE-TYPE": "Select Reference Type",
"REFERENCE": "Select Reference"
},
"TAGS": {
"NAME": "Tags",
"PLACEHOLDER": "Select Tags"

View File

@ -837,6 +837,7 @@
"DMP": "Plan",
"EMPTY-LIST": "Još uvek ništa nije dostupno.",
"ACTIONS": {
"ADD-REFERENCE-TYPE": "Add a Reference Type",
"ADD-DESCRIPTION": "Add Description",
"TAKE-A-TOUR": "Do you need help? Take a tour..",
"LOAD-MORE": "Load more",
@ -858,12 +859,14 @@
},
"FILTERS": {
"NAME": "Filters",
"APPLY-FILTERS": "Apply filters",
"STATUS": {
"NAME": "Status",
"TYPES": {
"ANY": "Any",
"DRAFT": "Draft",
"FINALIZED": "Finalized"
"FINALIZED": "Finalized",
"CANCELED": "Canceled"
}
},
"RELATED-DESCRIPTION-TEMPLATES": {
@ -880,9 +883,16 @@
"TYPES": {
"ANY": "Any",
"OWNER": "Owner",
"MEMBER": "Member"
"VIEWER": "Viewer",
"DESCRIPTION-CONTRIBUTOR": "Description Contributor",
"REVIEWER": "Reviewer"
}
},
"REFERENCE-TYPES": {
"NAME": "Reference Types",
"REFERENCE-TYPE": "Select Reference Type",
"REFERENCE": "Select Reference"
},
"TAGS": {
"NAME": "Tags",
"PLACEHOLDER": "Select Tags"

View File

@ -837,6 +837,7 @@
"DMP": "Plan",
"EMPTY-LIST": "Burada Henüz Bir Şey Yok.",
"ACTIONS": {
"ADD-REFERENCE-TYPE": "Add a Reference Type",
"ADD-DESCRIPTION": "Add Description",
"TAKE-A-TOUR": "Do you need help? Take a tour..",
"LOAD-MORE": "Load more",
@ -858,12 +859,14 @@
},
"FILTERS": {
"NAME": "Filters",
"APPLY-FILTERS": "Apply filters",
"STATUS": {
"NAME": "Status",
"TYPES": {
"ANY": "Any",
"DRAFT": "Draft",
"FINALIZED": "Finalized"
"FINALIZED": "Finalized",
"CANCELED": "Canceled"
}
},
"RELATED-DESCRIPTION-TEMPLATES": {
@ -880,9 +883,16 @@
"TYPES": {
"ANY": "Any",
"OWNER": "Owner",
"MEMBER": "Member"
"VIEWER": "Viewer",
"DESCRIPTION-CONTRIBUTOR": "Description Contributor",
"REVIEWER": "Reviewer"
}
},
"REFERENCE-TYPES": {
"NAME": "Reference Types",
"REFERENCE-TYPE": "Select Reference Type",
"REFERENCE": "Select Reference"
},
"TAGS": {
"NAME": "Tags",
"PLACEHOLDER": "Select Tags"