mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
Merged in CST-13039-multiple-request-patterns (pull request #1141)
CST-13039 multiple request patterns Approved-by: Stefano Maffei
This commit is contained in:
@@ -7,6 +7,11 @@ import {typedObject} from '../../../core/cache/builders/build-decorators';
|
||||
import {NotifyServicePattern} from './ldn-service-patterns.model';
|
||||
|
||||
|
||||
export interface LdnServiceByPattern {
|
||||
allowsMultipleRequests: boolean;
|
||||
services: LdnService[];
|
||||
}
|
||||
|
||||
/** An LdnService and its properties. */
|
||||
@typedObject
|
||||
@inheritSerialization(CacheableObject)
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import { Store } from '@ngrx/store';
|
||||
import {
|
||||
FlushPatchOperationAction,
|
||||
NewPatchAddOperationAction,
|
||||
NewPatchMoveOperationAction,
|
||||
NewPatchRemoveOperationAction,
|
||||
@@ -99,6 +100,20 @@ export class JsonPatchOperationsBuilder {
|
||||
path.path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches a new FlushPatchOperationAction
|
||||
*
|
||||
* @param path
|
||||
* a JsonPatchOperationPathObject representing path
|
||||
*/
|
||||
flushOperation(path: JsonPatchOperationPathObject) {
|
||||
this.store.dispatch(
|
||||
new FlushPatchOperationAction(
|
||||
path.rootElement,
|
||||
path.subRootElement,
|
||||
path.path));
|
||||
}
|
||||
|
||||
protected prepareValue(value: any, plain: boolean, first: boolean) {
|
||||
let operationValue: any = null;
|
||||
if (hasValue(value)) {
|
||||
|
@@ -20,6 +20,7 @@ export const JsonPatchOperationsActionTypes = {
|
||||
COMMIT_JSON_PATCH_OPERATIONS: type('dspace/core/patch/COMMIT_JSON_PATCH_OPERATIONS'),
|
||||
ROLLBACK_JSON_PATCH_OPERATIONS: type('dspace/core/patch/ROLLBACK_JSON_PATCH_OPERATIONS'),
|
||||
FLUSH_JSON_PATCH_OPERATIONS: type('dspace/core/patch/FLUSH_JSON_PATCH_OPERATIONS'),
|
||||
FLUSH_JSON_PATCH_OPERATION: type('dspace/core/patch/FLUSH_JSON_PATCH_OPERATION'),
|
||||
START_TRANSACTION_JSON_PATCH_OPERATIONS: type('dspace/core/patch/START_TRANSACTION_JSON_PATCH_OPERATIONS'),
|
||||
DELETE_PENDING_JSON_PATCH_OPERATIONS: type('dspace/core/patch/DELETE_PENDING_JSON_PATCH_OPERATIONS'),
|
||||
};
|
||||
@@ -120,6 +121,32 @@ export class FlushPatchOperationsAction implements Action {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An ngrx action to flush a single operation of the JSON Patch operations
|
||||
*/
|
||||
export class FlushPatchOperationAction implements Action {
|
||||
type = JsonPatchOperationsActionTypes.FLUSH_JSON_PATCH_OPERATION;
|
||||
payload: {
|
||||
resourceType: string;
|
||||
resourceId: string;
|
||||
path: string
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new FlushPatchOperationsAction
|
||||
*
|
||||
* @param resourceType
|
||||
* the resource's type
|
||||
* @param resourceId
|
||||
* the resource's ID
|
||||
* @param path
|
||||
* the path of the operation
|
||||
*/
|
||||
constructor(resourceType: string, resourceId: string, path: string) {
|
||||
this.payload = { resourceType, resourceId, path };
|
||||
}
|
||||
}
|
||||
/**
|
||||
* An ngrx action to Add new HTTP/PATCH ADD operations to state
|
||||
*/
|
||||
@@ -284,4 +311,5 @@ export type PatchOperationsActions
|
||||
| NewPatchReplaceOperationAction
|
||||
| RollbacktPatchOperationsAction
|
||||
| StartTransactionPatchOperationsAction
|
||||
| DeletePendingJsonPatchOperationsAction;
|
||||
| DeletePendingJsonPatchOperationsAction
|
||||
| FlushPatchOperationAction;
|
||||
|
@@ -12,7 +12,7 @@ import {
|
||||
CommitPatchOperationsAction,
|
||||
StartTransactionPatchOperationsAction,
|
||||
RollbacktPatchOperationsAction,
|
||||
DeletePendingJsonPatchOperationsAction
|
||||
DeletePendingJsonPatchOperationsAction, FlushPatchOperationAction
|
||||
} from './json-patch-operations.actions';
|
||||
import { JsonPatchOperationModel, JsonPatchOperationType } from './json-patch.model';
|
||||
|
||||
@@ -71,7 +71,7 @@ export function jsonPatchOperationsReducer(state = initialState, action: PatchOp
|
||||
}
|
||||
|
||||
case JsonPatchOperationsActionTypes.FLUSH_JSON_PATCH_OPERATIONS: {
|
||||
return flushOperation(state, action as FlushPatchOperationsAction);
|
||||
return flushOperations(state, action as FlushPatchOperationsAction);
|
||||
}
|
||||
|
||||
case JsonPatchOperationsActionTypes.NEW_JSON_PATCH_ADD_OPERATION: {
|
||||
@@ -106,6 +106,10 @@ export function jsonPatchOperationsReducer(state = initialState, action: PatchOp
|
||||
return deletePendingOperations(state, action as DeletePendingJsonPatchOperationsAction);
|
||||
}
|
||||
|
||||
case JsonPatchOperationsActionTypes.FLUSH_JSON_PATCH_OPERATION: {
|
||||
return flushOperation(state, action as FlushPatchOperationAction);
|
||||
}
|
||||
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
@@ -197,6 +201,39 @@ function deletePendingOperations(state: JsonPatchOperationsState, action: Delete
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush one operation from JsonPatchOperationsState.
|
||||
*
|
||||
* @param state
|
||||
* the current state
|
||||
* @param action
|
||||
* an FlushPatchOperationsAction
|
||||
* @return JsonPatchOperationsState
|
||||
* the new state.
|
||||
*/
|
||||
function flushOperation(state: JsonPatchOperationsState, action: FlushPatchOperationAction): JsonPatchOperationsState {
|
||||
const payload = action.payload;
|
||||
if (state[payload.resourceType] && state[payload.resourceType].children) {
|
||||
const body = state[payload.resourceType].children[payload.resourceId].body;
|
||||
const operation = body.filter(operations => operations.operation.path === payload.path)[0];
|
||||
const operationIndex = body.indexOf(operation);
|
||||
const newBody = [...body];
|
||||
newBody.splice(operationIndex, 1);
|
||||
|
||||
return Object.assign({}, state, {
|
||||
[action.payload.resourceType]: Object.assign({}, {
|
||||
children: {
|
||||
[action.payload.resourceId]: {
|
||||
body: newBody,
|
||||
}
|
||||
},
|
||||
})
|
||||
});
|
||||
} else {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new JSON patch operation list.
|
||||
*
|
||||
@@ -273,7 +310,7 @@ function hasValidBody(state: JsonPatchOperationsState, resourceType: any, resour
|
||||
* @return SubmissionObjectState
|
||||
* the new state, with the section new validity status.
|
||||
*/
|
||||
function flushOperation(state: JsonPatchOperationsState, action: FlushPatchOperationsAction): JsonPatchOperationsState {
|
||||
function flushOperations(state: JsonPatchOperationsState, action: FlushPatchOperationsAction): JsonPatchOperationsState {
|
||||
if (hasValue(state[ action.payload.resourceType ])) {
|
||||
let newChildren;
|
||||
if (isNotUndefined(action.payload.resourceId)) {
|
||||
|
@@ -1,115 +1,138 @@
|
||||
<div class="container-fluid">
|
||||
<ng-container *ngIf="patterns?.length > 0">
|
||||
<div *ngFor="let pattern of patterns; let i = index" class="col">
|
||||
<div *ngFor="let ldnPattern of patterns; let i = index" class="col">
|
||||
<label class="row col-form-label"
|
||||
>
|
||||
{{'submission.section.section-coar-notify.control.' + pattern + '.label' | translate }}
|
||||
{{'submission.section.section-coar-notify.control.' + ldnPattern.pattern + '.label' | translate }}
|
||||
</label
|
||||
>
|
||||
<div
|
||||
*ngFor="
|
||||
let service of ldnServiceByPattern[pattern];
|
||||
let serviceIndex = index
|
||||
"
|
||||
>
|
||||
<div class="row">
|
||||
<div ngbDropdown #myDropdown="ngbDropdown" class="w-100">
|
||||
<div class="position-relative right-addon" role="combobox">
|
||||
<i ngbDropdownToggle class="position-absolute scrollable-dropdown-toggle"
|
||||
aria-hidden="true"></i>
|
||||
<input
|
||||
type="text"
|
||||
[readonly]="true"
|
||||
ngbDropdownAnchor
|
||||
[ngClass]="{'border-danger': (getShownSectionErrors$(pattern, serviceIndex) | async)?.length > 0}"
|
||||
class="form-control w-100 scrollable-dropdown-input"
|
||||
[value]="ldnServiceByPattern[pattern][serviceIndex]?.name"
|
||||
(click)="myDropdown.open()"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu scrollable-dropdown-menu w-100"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<div
|
||||
class="scrollable-menu"
|
||||
role="listbox"
|
||||
infiniteScroll
|
||||
[infiniteScrollDistance]="2"
|
||||
[infiniteScrollThrottle]="50"
|
||||
[scrollWindow]="false"
|
||||
>
|
||||
<button
|
||||
*ngIf="(filterServices(pattern) | async)?.length == 0"
|
||||
class="dropdown-item collection-item text-truncate w-100"
|
||||
>
|
||||
{{'submission.section.section-coar-notify.dropdown.no-data' | translate}}
|
||||
</button>
|
||||
<button
|
||||
*ngIf="(filterServices(pattern) | async)?.length > 0"
|
||||
class="dropdown-item collection-item text-truncate w-100"
|
||||
(click)="onChange(pattern, serviceIndex, null)"
|
||||
>
|
||||
{{'submission.section.section-coar-notify.dropdown.select-none' | translate}}
|
||||
</button>
|
||||
<button
|
||||
*ngFor="let serviceOption of filterServices(pattern) | async"
|
||||
[ngClass]="{'bg-light': ldnServiceByPattern[pattern][serviceIndex]?.id == serviceOption.id}"
|
||||
class="dropdown-item collection-item text-truncate w-100"
|
||||
(click)="onChange(pattern, serviceIndex, serviceOption)"
|
||||
>
|
||||
<b>
|
||||
{{ serviceOption.name }}
|
||||
</b>
|
||||
<br />
|
||||
{{ serviceOption.description }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<small
|
||||
class="row text-muted"
|
||||
*ngIf="!ldnServiceByPattern[pattern][serviceIndex]"
|
||||
>
|
||||
{{'submission.section.section-coar-notify.small.notification' | translate : {pattern : pattern} }}
|
||||
</small>
|
||||
<ng-container *ngIf="(getShownSectionErrors$(pattern, serviceIndex) | async)?.length > 0">
|
||||
<small class="row text-danger" *ngFor="let error of (getShownSectionErrors$(pattern, serviceIndex) | async)">
|
||||
{{ error.message | translate}}
|
||||
</small>
|
||||
</ng-container>
|
||||
<div *ngIf="ldnServiceByPattern[ldnPattern.pattern]?.services.length">
|
||||
<div
|
||||
class="row mt-1"
|
||||
*ngIf="ldnServiceByPattern[pattern][serviceIndex]"
|
||||
*ngFor="
|
||||
let service of ldnServiceByPattern[ldnPattern.pattern].services;
|
||||
let serviceIndex = index
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="alert alert-info w-100 d-flex align-items-center flex-row"
|
||||
>
|
||||
<i class="fa-solid fa-circle-info fa-xl ml-2"></i>
|
||||
<div class="ml-4">
|
||||
<div>{{ 'submission.section.section-coar-notify.selection.description' | translate }}</div>
|
||||
<div *ngIf="ldnServiceByPattern[pattern][serviceIndex]?.description; else noDesc">
|
||||
{{ ldnServiceByPattern[pattern][serviceIndex].description }}
|
||||
<div class="row">
|
||||
<div ngbDropdown #myDropdown="ngbDropdown" [class.mt-2]="serviceIndex > 0" class="flex-grow-1">
|
||||
<div class="position-relative right-addon" role="combobox">
|
||||
<i ngbDropdownToggle class="position-absolute scrollable-dropdown-toggle"
|
||||
aria-hidden="true"></i>
|
||||
<input
|
||||
type="text"
|
||||
[readonly]="true"
|
||||
ngbDropdownAnchor
|
||||
[ngClass]="{'border-danger': (getShownSectionErrors$(ldnPattern.pattern, serviceIndex) | async)?.length > 0}"
|
||||
class="form-control w-100 scrollable-dropdown-input"
|
||||
[value]="ldnServiceByPattern[ldnPattern.pattern].services[serviceIndex]?.name"
|
||||
(click)="myDropdown.open()"
|
||||
/>
|
||||
</div>
|
||||
<ng-template #noDesc>
|
||||
<div
|
||||
ngbDropdownMenu
|
||||
class="dropdown-menu scrollable-dropdown-menu w-100"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<div
|
||||
class="scrollable-menu"
|
||||
role="listbox"
|
||||
infiniteScroll
|
||||
[infiniteScrollDistance]="2"
|
||||
[infiniteScrollThrottle]="50"
|
||||
[scrollWindow]="false"
|
||||
>
|
||||
<button
|
||||
*ngIf="(filterServices(ldnPattern.pattern) | async)?.length == 0"
|
||||
class="dropdown-item collection-item text-truncate w-100"
|
||||
>
|
||||
{{'submission.section.section-coar-notify.dropdown.no-data' | translate}}
|
||||
</button>
|
||||
<button
|
||||
*ngIf="(filterServices(ldnPattern.pattern ) | async)?.length > 0"
|
||||
class="dropdown-item collection-item text-truncate w-100"
|
||||
(click)="onChange(ldnPattern.pattern, serviceIndex, null)"
|
||||
>
|
||||
{{'submission.section.section-coar-notify.dropdown.select-none' | translate}}
|
||||
</button>
|
||||
<button
|
||||
*ngFor="let serviceOption of filterServices(ldnPattern.pattern ) | async"
|
||||
[ngClass]="{'bg-light': ldnServiceByPattern[ldnPattern.pattern ].services[serviceIndex]?.id == serviceOption.id}"
|
||||
class="dropdown-item collection-item text-truncate w-100"
|
||||
(click)="onChange(ldnPattern.pattern, serviceIndex, serviceOption)"
|
||||
>
|
||||
<b>
|
||||
{{ serviceOption.name }}
|
||||
</b>
|
||||
<br />
|
||||
{{ serviceOption.description }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button *ngIf="ldnServiceByPattern[ldnPattern.pattern].services.length > 1"
|
||||
type="button" [class.mt-2]="serviceIndex > 0"
|
||||
class="btn btn-secondary ml-2"
|
||||
role="button"
|
||||
title="{{'form.remove' | translate}}"
|
||||
[attr.aria-label]="'form.remove' | translate"
|
||||
(click)="removeService(ldnPattern, serviceIndex)"
|
||||
>
|
||||
<span><i class="fas fa-trash" aria-hidden="true"></i></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<small
|
||||
class="row text-muted"
|
||||
*ngIf="!ldnServiceByPattern[ldnPattern.pattern].services[serviceIndex] &&
|
||||
serviceIndex === ldnServiceByPattern[ldnPattern.pattern].services.length -1"
|
||||
>
|
||||
{{'submission.section.section-coar-notify.small.notification' | translate : {pattern : ldnPattern.pattern} }}
|
||||
</small>
|
||||
<ng-container *ngIf="(getShownSectionErrors$(ldnPattern.pattern , serviceIndex) | async)?.length > 0">
|
||||
<small class="row text-danger" *ngFor="let error of (getShownSectionErrors$(ldnPattern.pattern , serviceIndex) | async)">
|
||||
{{ error.message | translate}}
|
||||
</small>
|
||||
</ng-container>
|
||||
<div
|
||||
class="row mt-1"
|
||||
*ngIf="ldnServiceByPattern[ldnPattern.pattern].services[serviceIndex]"
|
||||
>
|
||||
<div
|
||||
class="alert alert-info w-100 d-flex align-items-center flex-row"
|
||||
>
|
||||
<i class="fa-solid fa-circle-info fa-xl ml-2"></i>
|
||||
<div class="ml-4">
|
||||
<div>{{ 'submission.section.section-coar-notify.selection.description' | translate }}</div>
|
||||
<div *ngIf="ldnServiceByPattern[ldnPattern.pattern].services[serviceIndex]?.description; else noDesc">
|
||||
{{ ldnServiceByPattern[ldnPattern.pattern].services[serviceIndex].description }}
|
||||
</div>
|
||||
<ng-template #noDesc>
|
||||
<span class="text-muted">
|
||||
{{ 'submission.section.section-coar-notify.selection.no-description' | translate }}
|
||||
</span>
|
||||
</ng-template>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" *ngIf="(getShownSectionErrors$(pattern, serviceIndex) | async)?.length > 0">
|
||||
<div
|
||||
class="alert alert-danger w-100 d-flex align-items-center flex-row"
|
||||
>
|
||||
<div class="ml-4">
|
||||
<div class="row" *ngIf="(getShownSectionErrors$(ldnPattern.pattern, serviceIndex) | async)?.length > 0">
|
||||
<div
|
||||
class="alert alert-danger w-100 d-flex align-items-center flex-row"
|
||||
>
|
||||
<div class="ml-4">
|
||||
<span>
|
||||
{{ 'submission.section.section-coar-notify.notification.error' | translate }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div *ngIf="ldnPattern.multipleRequest && (serviceIndex === ldnServiceByPattern[ldnPattern.pattern].services.length - 1)"
|
||||
(click)="addNewService(ldnPattern)"
|
||||
class="btn btn-link mt-2 pl-0"
|
||||
>
|
||||
<i class="fas fa-plus"></i>
|
||||
{{ 'submission.sections.general.add-more' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -118,7 +141,7 @@
|
||||
</ng-container>
|
||||
<ng-container *ngIf="patterns?.length === 0">
|
||||
<p>
|
||||
{{'submission.section.section-coar-notify.info.no-pattern' | translate }}
|
||||
{{ 'submission.section.section-coar-notify.info.no-pattern' | translate }}
|
||||
</p>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
@@ -2,3 +2,4 @@
|
||||
@import '../../../shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component.scss';
|
||||
@import '../../../shared/form/form.component.scss';
|
||||
|
||||
|
||||
|
@@ -8,15 +8,19 @@ import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/jso
|
||||
import { SectionsService } from '../sections.service';
|
||||
import { SectionDataObject } from '../models/section-data.model';
|
||||
|
||||
import { hasNoValue, hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util';
|
||||
import { hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util';
|
||||
|
||||
import { getFirstCompletedRemoteData, getPaginatedListPayload, getRemoteDataPayload } from '../../../core/shared/operators';
|
||||
import { LdnServicesService } from '../../../admin/admin-ldn-services/ldn-services-data/ldn-services-data.service';
|
||||
import { LdnService } from '../../../admin/admin-ldn-services/ldn-services-model/ldn-services.model';
|
||||
import {
|
||||
LdnService,
|
||||
LdnServiceByPattern
|
||||
} from '../../../admin/admin-ldn-services/ldn-services-model/ldn-services.model';
|
||||
import { CoarNotifyConfigDataService } from './coar-notify-config-data.service';
|
||||
import { filter, map, take, tap } from 'rxjs/operators';
|
||||
import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { SubmissionSectionError } from '../../objects/submission-section-error.model';
|
||||
import { LdnPattern } from './submission-coar-notify.config';
|
||||
|
||||
/**
|
||||
* This component represents a section that contains the submission section-coar-notify form.
|
||||
@@ -33,12 +37,12 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent
|
||||
/**
|
||||
* Contains an array of string patterns.
|
||||
*/
|
||||
patterns: string[] = [];
|
||||
patterns: LdnPattern[] = [];
|
||||
/**
|
||||
* An object that maps string keys to arrays of LdnService objects.
|
||||
* Used to store LdnService objects by pattern.
|
||||
*/
|
||||
ldnServiceByPattern: { [key: string]: LdnService[] } = {};
|
||||
ldnServiceByPattern: { [key: string]: LdnServiceByPattern } = {};
|
||||
/**
|
||||
* A map representing all services for each pattern
|
||||
* {
|
||||
@@ -50,7 +54,7 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent
|
||||
* @type {{ [key: string]: {[key: number]: number} }}
|
||||
* @memberof SubmissionSectionCoarNotifyComponent
|
||||
*/
|
||||
previousServices: { [key: string]: {[key: number]: number} } = {};
|
||||
previousServices: { [key: string]: LdnServiceByPattern } = {};
|
||||
|
||||
/**
|
||||
* The [[JsonPatchOperationPathCombiner]] object
|
||||
@@ -109,43 +113,39 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent
|
||||
* Handles the change event of a select element.
|
||||
* @param pattern - The pattern of the select element.
|
||||
* @param index - The index of the select element.
|
||||
* @param selectedService - The selected LDN service.
|
||||
*/
|
||||
onChange(pattern: string, index: number, selectedService: LdnService | null) {
|
||||
// do nothing if the selected value is the same as the previous one
|
||||
if (this.ldnServiceByPattern[pattern][index]?.id === selectedService?.id) {
|
||||
if (this.ldnServiceByPattern[pattern].services[index]?.id === selectedService?.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize the previousServices object for the pattern if it does not exist
|
||||
if (!this.previousServices[pattern]) {
|
||||
this.previousServices[pattern] = {};
|
||||
this.previousServices[pattern] = {
|
||||
services: [],
|
||||
allowsMultipleRequests: this.patterns[pattern]?.multipleRequest
|
||||
};
|
||||
}
|
||||
|
||||
if (hasNoValue(selectedService)) {
|
||||
// on value change, remove the path when the selected value is null
|
||||
// and remove the previous value stored for the same index and pattern
|
||||
this.operationsBuilder.remove(this.pathCombiner.getPath([pattern, index.toString()]));
|
||||
this.sectionService.dispatchRemoveSectionErrors(this.submissionId, this.sectionData.id);
|
||||
this.ldnServiceByPattern[pattern][index] = null;
|
||||
this.previousServices[pattern][index] = null;
|
||||
return;
|
||||
}
|
||||
// store the previous value
|
||||
this.previousServices[pattern][index] = this.ldnServiceByPattern[pattern][index]?.id;
|
||||
this.previousServices[pattern].services[index] = this.ldnServiceByPattern[pattern].services[index];
|
||||
// set the new value
|
||||
this.ldnServiceByPattern[pattern][index] = selectedService;
|
||||
this.ldnServiceByPattern[pattern].services[index] = selectedService;
|
||||
|
||||
const hasPrevValueStored = hasValue(this.previousServices[pattern][index]) && this.previousServices[pattern][index] !== selectedService.id;
|
||||
const hasPrevValueStored = hasValue(this.previousServices[pattern].services[index]) && this.previousServices[pattern].services[index].id !== selectedService?.id;
|
||||
if (hasPrevValueStored) {
|
||||
// replace the path
|
||||
// when there is a previous value stored and it is different from the new one
|
||||
this.operationsBuilder.replace(this.pathCombiner.getPath([pattern, index.toString()]), selectedService.id, true);
|
||||
} else {
|
||||
this.operationsBuilder.flushOperation(this.pathCombiner.getPath([pattern, '-']));
|
||||
}
|
||||
|
||||
if (!hasPrevValueStored || (selectedService?.id && hasPrevValueStored)) {
|
||||
// add the path when there is no previous value stored
|
||||
this.operationsBuilder.add(this.pathCombiner.getPath([pattern, '-']), [selectedService.id], false, true);
|
||||
}
|
||||
// set the previous value to the new value
|
||||
this.previousServices[pattern][index] = this.ldnServiceByPattern[pattern][index].id;
|
||||
this.previousServices[pattern].services[index] = this.ldnServiceByPattern[pattern].services[index];
|
||||
this.sectionService.dispatchRemoveSectionErrors(this.submissionId, this.sectionData.id);
|
||||
this.chd.detectChanges();
|
||||
}
|
||||
@@ -158,48 +158,60 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent
|
||||
* so that the select element is initialized with a null value and to display the default select input.
|
||||
*/
|
||||
initSelectedServicesByPattern(): void {
|
||||
this.patterns.forEach((pattern) => {
|
||||
if (hasValue(this.sectionData.data[pattern])) {
|
||||
this.patterns.forEach((ldnPattern) => {
|
||||
if (hasValue(this.sectionData.data[ldnPattern.pattern])) {
|
||||
this.subs.push(
|
||||
this.filterServices(pattern)
|
||||
this.filterServices(ldnPattern.pattern)
|
||||
.subscribe((services: LdnService[]) => {
|
||||
const selectedServices = services.filter((service) => {
|
||||
const selection = (this.sectionData.data[pattern] as LdnService[]).find((s: LdnService) => s.id === service.id);
|
||||
this.addService(pattern, selection);
|
||||
return this.sectionData.data[pattern].includes(service.id);
|
||||
this.ldnServiceByPattern[ldnPattern.pattern].services = services.filter((service) => {
|
||||
const selection = (this.sectionData.data[ldnPattern.pattern] as LdnService[]).find((s: LdnService) => s.id === service.id);
|
||||
this.addService(ldnPattern, selection);
|
||||
return this.sectionData.data[ldnPattern.pattern].includes(service.id);
|
||||
});
|
||||
this.ldnServiceByPattern[pattern] = selectedServices;
|
||||
})
|
||||
);
|
||||
} else {
|
||||
this.ldnServiceByPattern[pattern] = [];
|
||||
this.addService(pattern, null);
|
||||
this.ldnServiceByPattern[ldnPattern.pattern] = {
|
||||
services: [],
|
||||
allowsMultipleRequests: ldnPattern.multipleRequest
|
||||
};
|
||||
this.addService(ldnPattern, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new service to the selected services for the given pattern.
|
||||
* @param pattern - The pattern to add the new service to.
|
||||
* @param ldnPattern - The pattern to add the new service to.
|
||||
* @param newService - The new service to add.
|
||||
*/
|
||||
addService(pattern: string, newService: LdnService) {
|
||||
addService(ldnPattern: LdnPattern, newService: LdnService) {
|
||||
// Your logic to add a new service to the selected services for the pattern
|
||||
// Example: Push the newService to the array corresponding to the pattern
|
||||
if (!this.ldnServiceByPattern[pattern]) {
|
||||
this.ldnServiceByPattern[pattern] = [];
|
||||
if (!this.ldnServiceByPattern[ldnPattern.pattern]) {
|
||||
this.ldnServiceByPattern[ldnPattern.pattern] = {
|
||||
services: [],
|
||||
allowsMultipleRequests: ldnPattern.multipleRequest
|
||||
};
|
||||
}
|
||||
this.ldnServiceByPattern[pattern].push(newService);
|
||||
this.ldnServiceByPattern[ldnPattern.pattern].services.push(newService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the service at the specified index from the array corresponding to the pattern.
|
||||
* (part of next phase of implementation)
|
||||
* @param ldnPattern - The LDN pattern from which to remove the service
|
||||
* @param serviceIndex - the service index to remove
|
||||
*/
|
||||
removeService(pattern: string, serviceIndex: number) {
|
||||
if (this.ldnServiceByPattern[pattern]) {
|
||||
removeService(ldnPattern: LdnPattern, serviceIndex: number) {
|
||||
if (this.ldnServiceByPattern[ldnPattern.pattern]) {
|
||||
// Remove the service at the specified index from the array
|
||||
this.ldnServiceByPattern[pattern].splice(serviceIndex, 1);
|
||||
this.ldnServiceByPattern[ldnPattern.pattern].services.splice(serviceIndex, 1);
|
||||
this.previousServices[ldnPattern.pattern]?.services.splice(serviceIndex, 1);
|
||||
this.operationsBuilder.flushOperation(this.pathCombiner.getPath([ldnPattern.pattern, '-']));
|
||||
this.sectionService.dispatchRemoveSectionErrors(this.submissionId, this.sectionData.id);
|
||||
}
|
||||
if (!this.ldnServiceByPattern[ldnPattern.pattern].services.length) {
|
||||
this.addNewService(ldnPattern);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,4 +302,13 @@ export class SubmissionSectionCoarNotifyComponent extends SectionModelComponent
|
||||
.filter((subscription) => hasValue(subscription))
|
||||
.forEach((subscription) => subscription.unsubscribe());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new row to dropdown for multiple service selection
|
||||
* @param ldnPattern - the related LDN pattern where the service is added
|
||||
*/
|
||||
addNewService(ldnPattern: LdnPattern): void {
|
||||
//idle new service for new selection
|
||||
this.ldnServiceByPattern[ldnPattern.pattern].services.push(null);
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,10 @@ import { excludeFromEquals } from '../../../core/utilities/equals.decorators';
|
||||
import { typedObject } from '../../../core/cache/builders/build-decorators';
|
||||
import { SUBMISSION_COAR_NOTIFY_CONFIG } from './section-coar-notify-service.resource-type';
|
||||
|
||||
|
||||
export interface LdnPattern {
|
||||
pattern: string,
|
||||
multipleRequest: boolean
|
||||
}
|
||||
/** A SubmissionCoarNotifyConfig and its properties. */
|
||||
@typedObject
|
||||
@inheritSerialization(CacheableObject)
|
||||
@@ -24,7 +27,7 @@ export class SubmissionCoarNotifyConfig extends CacheableObject {
|
||||
uuid: string;
|
||||
|
||||
@autoserialize
|
||||
patterns: string[];
|
||||
patterns: LdnPattern[];
|
||||
|
||||
@deserialize
|
||||
_links: {
|
||||
|
Reference in New Issue
Block a user