mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
Merge branch 'w2p-113560_edit-item-add-relationships-one-by-one_contribute-7.6' into w2p-113560_edit-item-add-relationships-one-by-one_contribute-7_x
This commit is contained in:
@@ -19,7 +19,7 @@ import {
|
|||||||
SetEditableFieldUpdateAction,
|
SetEditableFieldUpdateAction,
|
||||||
SetValidFieldUpdateAction
|
SetValidFieldUpdateAction
|
||||||
} from './object-updates.actions';
|
} from './object-updates.actions';
|
||||||
import { distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators';
|
import { distinctUntilChanged, filter, map, switchMap, take } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
hasNoValue,
|
hasNoValue,
|
||||||
hasValue,
|
hasValue,
|
||||||
@@ -198,8 +198,14 @@ export class ObjectUpdatesService {
|
|||||||
* @param url The page's URL for which the changes are saved
|
* @param url The page's URL for which the changes are saved
|
||||||
* @param field An updated field for the page's object
|
* @param field An updated field for the page's object
|
||||||
*/
|
*/
|
||||||
saveAddFieldUpdate(url: string, field: Identifiable) {
|
saveAddFieldUpdate(url: string, field: Identifiable): Observable<boolean> {
|
||||||
|
const update$: Observable<boolean> = this.getFieldUpdatesExclusive(url, [field]).pipe(
|
||||||
|
filter((fieldUpdates: FieldUpdates) => fieldUpdates[field.uuid].changeType === FieldChangeType.ADD),
|
||||||
|
take(1),
|
||||||
|
map(() => true),
|
||||||
|
);
|
||||||
this.saveFieldUpdate(url, field, FieldChangeType.ADD);
|
this.saveFieldUpdate(url, field, FieldChangeType.ADD);
|
||||||
|
return update$;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -207,8 +213,14 @@ export class ObjectUpdatesService {
|
|||||||
* @param url The page's URL for which the changes are saved
|
* @param url The page's URL for which the changes are saved
|
||||||
* @param field An updated field for the page's object
|
* @param field An updated field for the page's object
|
||||||
*/
|
*/
|
||||||
saveRemoveFieldUpdate(url: string, field: Identifiable) {
|
saveRemoveFieldUpdate(url: string, field: Identifiable): Observable<boolean> {
|
||||||
|
const update$: Observable<boolean> = this.getFieldUpdatesExclusive(url, [field]).pipe(
|
||||||
|
filter((fieldUpdates: FieldUpdates) => fieldUpdates[field.uuid].changeType === FieldChangeType.REMOVE),
|
||||||
|
take(1),
|
||||||
|
map(() => true),
|
||||||
|
);
|
||||||
this.saveFieldUpdate(url, field, FieldChangeType.REMOVE);
|
this.saveFieldUpdate(url, field, FieldChangeType.REMOVE);
|
||||||
|
return update$;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -305,29 +305,28 @@ export class EditRelationshipListComponent implements OnInit, OnDestroy {
|
|||||||
modalComp.submitEv = () => {
|
modalComp.submitEv = () => {
|
||||||
modalComp.isPending = true;
|
modalComp.isPending = true;
|
||||||
const isLeft = this.currentItemIsLeftItem$.getValue();
|
const isLeft = this.currentItemIsLeftItem$.getValue();
|
||||||
const addOperations = modalComp.toAdd.map((searchResult: any) => ({ type: 'add', searchResult }));
|
const addOperations = modalComp.toAdd.map((searchResult: ItemSearchResult) => ({ type: 'add', searchResult }));
|
||||||
const removeOperations = modalComp.toRemove.map((searchResult: any) => ({ type: 'remove', searchResult }));
|
const removeOperations = modalComp.toRemove.map((searchResult: ItemSearchResult) => ({ type: 'remove', searchResult }));
|
||||||
observableFrom([...addOperations, ...removeOperations]).pipe(
|
observableFrom([...addOperations, ...removeOperations]).pipe(
|
||||||
concatMap(({ type, searchResult }: { type: string, searchResult: any }) => {
|
concatMap(({ type, searchResult }: { type: string, searchResult: ItemSearchResult }) => {
|
||||||
|
const relatedItem: Item = searchResult.indexableObject;
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
const relatedItem = searchResult.indexableObject;
|
|
||||||
return this.relationshipService.getNameVariant(this.listId, relatedItem.uuid).pipe(
|
return this.relationshipService.getNameVariant(this.listId, relatedItem.uuid).pipe(
|
||||||
map((nameVariant) => {
|
switchMap((nameVariant) => {
|
||||||
const update = {
|
const update = {
|
||||||
uuid: this.relationshipType.id + '-' + searchResult.indexableObject.uuid,
|
uuid: `${this.relationshipType.id}-${relatedItem.uuid}`,
|
||||||
nameVariant,
|
nameVariant,
|
||||||
type: this.relationshipType,
|
type: this.relationshipType,
|
||||||
originalIsLeft: isLeft,
|
originalIsLeft: isLeft,
|
||||||
originalItem: this.item,
|
originalItem: this.item,
|
||||||
relatedItem,
|
relatedItem,
|
||||||
} as RelationshipIdentifiable;
|
} as RelationshipIdentifiable;
|
||||||
this.objectUpdatesService.saveAddFieldUpdate(this.url, update);
|
return this.objectUpdatesService.saveAddFieldUpdate(this.url, update);
|
||||||
return update;
|
|
||||||
}),
|
}),
|
||||||
take(1)
|
take(1)
|
||||||
);
|
);
|
||||||
} else if (type === 'remove') {
|
} else if (type === 'remove') {
|
||||||
return this.relationshipService.getNameVariant(this.listId, searchResult.indexableObjectuuid).pipe(
|
return this.relationshipService.getNameVariant(this.listId, relatedItem.uuid).pipe(
|
||||||
switchMap((nameVariant) => {
|
switchMap((nameVariant) => {
|
||||||
return this.getRelationFromId(searchResult.indexableObject).pipe(
|
return this.getRelationFromId(searchResult.indexableObject).pipe(
|
||||||
map( (relationship: Relationship) => {
|
map( (relationship: Relationship) => {
|
||||||
@@ -339,9 +338,8 @@ export class EditRelationshipListComponent implements OnInit, OnDestroy {
|
|||||||
originalItem: this.item,
|
originalItem: this.item,
|
||||||
relationship,
|
relationship,
|
||||||
} as RelationshipIdentifiable;
|
} as RelationshipIdentifiable;
|
||||||
this.objectUpdatesService.saveRemoveFieldUpdate(this.url,update);
|
return this.objectUpdatesService.saveRemoveFieldUpdate(this.url,update);
|
||||||
return update;
|
}),
|
||||||
})
|
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
take(1)
|
take(1)
|
||||||
|
@@ -5,9 +5,9 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<ng-container *ngFor="let item of items; trackBy: trackItem">
|
<ng-container *ngFor="let itemDTO of itemDTOs$ | async; trackBy: trackItemDTO">
|
||||||
<div *ngVar="(isSelectedVirtualMetadataItem(item) | async) as selected"
|
<div *ngVar="(itemDTO.isSelectedVirtualMetadataItem$ | async) as selected"
|
||||||
(click)="setSelectedVirtualMetadataItem(item, !selected)"
|
(click)="setSelectedVirtualMetadataItem(itemDTO.item, !selected)"
|
||||||
class="item d-flex flex-row">
|
class="item d-flex flex-row">
|
||||||
<div class="m-2">
|
<div class="m-2">
|
||||||
<label>
|
<label>
|
||||||
@@ -15,9 +15,9 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-column">
|
<div class="flex-column">
|
||||||
<ds-listable-object-component-loader [object]="item">
|
<ds-listable-object-component-loader [object]="itemDTO.item">
|
||||||
</ds-listable-object-component-loader>
|
</ds-listable-object-component-loader>
|
||||||
<div *ngFor="let metadata of virtualMetadata.get(item.uuid)">
|
<div *ngFor="let metadata of virtualMetadata.get(itemDTO.item.uuid)">
|
||||||
<div class="font-weight-bold">
|
<div class="font-weight-bold">
|
||||||
{{metadata.metadataField}}
|
{{metadata.metadataField}}
|
||||||
</div>
|
</div>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<div class="d-flex flex-row-reverse m-2">
|
<div class="d-flex flex-row-reverse m-2">
|
||||||
<button class="btn btn-primary save"
|
<button class="btn btn-primary save"
|
||||||
(click)="save.emit()">
|
(click)="save.emit()">
|
||||||
<i class="fas fa-save"></i> {{"item.edit.metadata.save-button" | translate}}
|
<i aria-hidden="true" class="fas fa-save"></i> {{ 'item.edit.metadata.save-button' | translate }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -61,6 +61,7 @@ describe('VirtualMetadataComponent', () => {
|
|||||||
comp.url = url;
|
comp.url = url;
|
||||||
comp.leftItem = item;
|
comp.leftItem = item;
|
||||||
comp.rightItem = relatedItem;
|
comp.rightItem = relatedItem;
|
||||||
|
comp.ngOnChanges();
|
||||||
comp.relationshipId = relationshipId;
|
comp.relationshipId = relationshipId;
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
@@ -1,9 +1,18 @@
|
|||||||
import { Component, EventEmitter, Inject, Input, OnInit, Output } from '@angular/core';
|
import { Component, EventEmitter, Inject, Input, OnInit, Output, OnChanges, OnDestroy } from '@angular/core';
|
||||||
import {Observable} from 'rxjs';
|
import { Observable, Subscription, BehaviorSubject } from 'rxjs';
|
||||||
import {Item} from '../../../core/shared/item.model';
|
import {Item} from '../../../core/shared/item.model';
|
||||||
import {MetadataValue} from '../../../core/shared/metadata.models';
|
import {MetadataValue} from '../../../core/shared/metadata.models';
|
||||||
import {ObjectUpdatesService} from '../../../core/data/object-updates/object-updates.service';
|
import {ObjectUpdatesService} from '../../../core/data/object-updates/object-updates.service';
|
||||||
import { APP_CONFIG, AppConfig } from '../../../../config/app-config.interface';
|
import { APP_CONFIG, AppConfig } from '../../../../config/app-config.interface';
|
||||||
|
import { hasValue } from '../../../shared/empty.util';
|
||||||
|
|
||||||
|
interface ItemDTO {
|
||||||
|
|
||||||
|
item: Item;
|
||||||
|
|
||||||
|
isSelectedVirtualMetadataItem$: Observable<boolean>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-virtual-metadata',
|
selector: 'ds-virtual-metadata',
|
||||||
@@ -14,7 +23,7 @@ import { APP_CONFIG, AppConfig } from '../../../../config/app-config.interface';
|
|||||||
* The component is shown when a relationship is marked to be deleted.
|
* The component is shown when a relationship is marked to be deleted.
|
||||||
* Each item has a checkbox to indicate whether its virtual metadata should be saved as real metadata.
|
* Each item has a checkbox to indicate whether its virtual metadata should be saved as real metadata.
|
||||||
*/
|
*/
|
||||||
export class VirtualMetadataComponent implements OnInit {
|
export class VirtualMetadataComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current url of this page
|
* The current url of this page
|
||||||
@@ -55,9 +64,9 @@ export class VirtualMetadataComponent implements OnInit {
|
|||||||
/**
|
/**
|
||||||
* Get an array of the left and the right item of the relationship to be deleted.
|
* Get an array of the left and the right item of the relationship to be deleted.
|
||||||
*/
|
*/
|
||||||
get items() {
|
itemDTOs$: BehaviorSubject<ItemDTO[]> = new BehaviorSubject([]);
|
||||||
return [this.leftItem, this.rightItem];
|
|
||||||
}
|
subs: Subscription[] = [];
|
||||||
|
|
||||||
public virtualMetadata: Map<string, VirtualMetadata[]> = new Map<string, VirtualMetadata[]>();
|
public virtualMetadata: Map<string, VirtualMetadata[]> = new Map<string, VirtualMetadata[]>();
|
||||||
|
|
||||||
@@ -109,14 +118,33 @@ export class VirtualMetadataComponent implements OnInit {
|
|||||||
/**
|
/**
|
||||||
* Prevent unnecessary rerendering so fields don't lose focus
|
* Prevent unnecessary rerendering so fields don't lose focus
|
||||||
*/
|
*/
|
||||||
trackItem(index, item: Item) {
|
trackItemDTO(index, itemDTO: ItemDTO): string {
|
||||||
return item && item.uuid;
|
return itemDTO?.item?.uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.items.forEach((item) => {
|
this.subs.push(this.itemDTOs$.subscribe((itemDTOs: ItemDTO[]) => {
|
||||||
this.virtualMetadata.set(item.uuid, this.getVirtualMetadata(item));
|
itemDTOs.forEach((itemDTO: ItemDTO) => this.virtualMetadata.set(itemDTO.item.uuid, this.getVirtualMetadata(itemDTO.item)));
|
||||||
});
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges(): void {
|
||||||
|
if (hasValue(this.leftItem) && hasValue(this.rightItem)) {
|
||||||
|
this.itemDTOs$.next([
|
||||||
|
{
|
||||||
|
item: this.leftItem,
|
||||||
|
isSelectedVirtualMetadataItem$: this.isSelectedVirtualMetadataItem(this.leftItem),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item: this.rightItem,
|
||||||
|
isSelectedVirtualMetadataItem$: this.isSelectedVirtualMetadataItem(this.rightItem),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.subs.forEach((sub: Subscription) => sub.unsubscribe());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user