diff --git a/src/app/+bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts b/src/app/+bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts index c5c6db3694..659c7b9fd9 100644 --- a/src/app/+bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts +++ b/src/app/+bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts @@ -25,7 +25,8 @@ import { BitstreamFormat } from '../../core/shared/bitstream-format.model'; import { BitstreamFormatSupportLevel } from '../../core/shared/bitstream-format-support-level'; import { RestResponse } from '../../core/cache/response.models'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; -import { MetadataValue } from '../../core/shared/metadata.models'; +import { MetadataMap, MetadataValue } from '../../core/shared/metadata.models'; +import { Metadata } from '../../core/shared/metadata.utils'; @Component({ selector: 'ds-edit-bitstream-page', @@ -388,7 +389,7 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { */ onSubmit() { const updatedValues = this.formGroup.getRawValue(); - const newBitstream = this.formToBitstream(updatedValues); + this.formToBitstream(updatedValues); const selectedFormat = this.formats.find((f: BitstreamFormat) => f.id === updatedValues.formatContainer.selectedFormat); const isNewFormat = selectedFormat.id !== this.originalFormat.id; @@ -398,14 +399,14 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { extraOperations.push(operation); } - const updatedBitstream$ = this.bitstreamService.update(newBitstream, extraOperations).pipe( + const updatedBitstream$ = this.bitstreamService.update(this.bitstream, extraOperations).pipe( tap(() => this.bitstreamService.commitUpdates()), getSucceededRemoteData(), getRemoteDataPayload() ); if (isNewFormat) { - const updatedFormatResponse$ = this.bitstreamService.updateFormat(newBitstream, selectedFormat); + const updatedFormatResponse$ = this.bitstreamService.updateFormat(this.bitstream, selectedFormat); observableCombineLatest(updatedBitstream$, updatedFormatResponse$).subscribe(([bitstream, formatResponse]) => { this.onSuccess(bitstream, formatResponse); }); @@ -434,24 +435,16 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { * Parse form data to an updated bitstream object * @param rawForm Raw form data */ - formToBitstream(rawForm): Bitstream { - const newBitstream = cloneDeep(this.bitstream); + formToBitstream(rawForm) { + const newMetadata = cloneDeep(this.bitstream.metadata); // TODO: Set bitstream to primary when supported const primary = rawForm.fileNamePrimaryContainer.primaryBitstream; - newBitstream.name = rawForm.fileNamePrimaryContainer.fileName; - newBitstream.description = rawForm.descriptionContainer.description; - - const otherFormat = rawForm.formatContainer.otherFormat; - if (isNotEmpty(otherFormat)) { - const currentOtherFormat = newBitstream.firstMetadata('dc.format'); - if (hasValue(currentOtherFormat)) { - currentOtherFormat.value = otherFormat; - } else { - newBitstream.metadata['dc.format'] = [Object.assign(new MetadataValue(), { value: otherFormat })]; - } + Metadata.setFirstValue(newMetadata, 'dc.title', rawForm.fileNamePrimaryContainer.fileName); + Metadata.setFirstValue(newMetadata, 'dc.description', rawForm.descriptionContainer.description); + if (isNotEmpty(rawForm.formatContainer.otherFormat)) { + Metadata.setFirstValue(newMetadata, 'dc.format', rawForm.formatContainer.otherFormat); } - - return newBitstream; + this.bitstream.metadata = newMetadata; } /** diff --git a/src/app/core/data/dso-change-analyzer.service.ts b/src/app/core/data/dso-change-analyzer.service.ts index 205b696a24..ce3ed2452e 100644 --- a/src/app/core/data/dso-change-analyzer.service.ts +++ b/src/app/core/data/dso-change-analyzer.service.ts @@ -4,6 +4,8 @@ import { ChangeAnalyzer } from './change-analyzer'; import { NormalizedDSpaceObject } from '../cache/models/normalized-dspace-object.model'; import { Injectable } from '@angular/core'; import { DSpaceObject } from '../shared/dspace-object.model'; +import { MetadataMap } from '../shared/metadata.models'; +import { cloneDeep } from 'lodash'; /** * A class to determine what differs between two @@ -22,9 +24,21 @@ export class DSOChangeAnalyzer implements ChangeAnalyzer * The second object to compare */ diff(object1: T | NormalizedDSpaceObject, object2: T | NormalizedDSpaceObject): Operation[] { - return compare(object1.metadata, object2.metadata) - // Filter out operations on UUIDs, as they should never change - .filter((operation: Operation) => !operation.path.endsWith('/uuid')) + return compare(this.filterUUIDsFromMetadata(object1.metadata), this.filterUUIDsFromMetadata(object2.metadata)) .map((operation: Operation) => Object.assign({}, operation, { path: '/metadata' + operation.path })); } + + /** + * Filter the UUIDs out of a MetadataMap + * @param metadata + */ + filterUUIDsFromMetadata(metadata: MetadataMap): MetadataMap { + const result = cloneDeep(metadata); + for (const key of Object.keys(result)) { + for (const metadataValue of result[key]) { + metadataValue.uuid = undefined; + } + } + return result; + } } diff --git a/src/app/core/shared/metadata.utils.ts b/src/app/core/shared/metadata.utils.ts index 62a1957e22..e034dbfb7e 100644 --- a/src/app/core/shared/metadata.utils.ts +++ b/src/app/core/shared/metadata.utils.ts @@ -1,4 +1,4 @@ -import { isEmpty, isNotUndefined, isUndefined } from '../../shared/empty.util'; +import { isEmpty, isNotEmpty, isNotUndefined, isUndefined } from '../../shared/empty.util'; import { MetadataMapInterface, MetadataValue, @@ -215,4 +215,19 @@ export class Metadata { }); return metadataMap; } + + /** + * Set the first value of a metadata by field key + * Creates a new MetadataValue if the field doesn't exist yet + * @param mdMap The map to add/change values in + * @param key The metadata field + * @param value The value to add + */ + public static setFirstValue(mdMap: MetadataMapInterface, key: string, value: string) { + if (isNotEmpty(mdMap[key])) { + mdMap[key][0].value = value; + } else { + mdMap[key] = [Object.assign(new MetadataValue(), { value: value })] + } + } }