diff --git a/resources/i18n/en.json b/resources/i18n/en.json index 63bc598304..a1b5be6f33 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -150,6 +150,8 @@ "footer.copyright": "copyright © 2002-{{ year }}", "footer.link.dspace": "DSpace software", "footer.link.duraspace": "DuraSpace", + "form.add": "Add", + "form.add-help": "Click here to add the current entry and to add another one", "form.cancel": "Cancel", "form.clear": "Clear", "form.clear-help": "Click here to remove the selected value", @@ -162,6 +164,8 @@ "form.group-expand-help": "Click here to expand and add more elements", "form.last-name": "Last name", "form.loading": "Loading...", + "form.lookup": "Lookup", + "form.lookup-help": "Click here to look up an existing relation", "form.no-results": "No results found", "form.no-value": "No value entered", "form.other-information": {}, @@ -224,12 +228,26 @@ "item.edit.reinstate.error": "An error occurred while reinstating the item", "item.edit.reinstate.header": "Reinstate item: {{ id }}", "item.edit.reinstate.success": "The item was reinstated successfully", + "item.edit.relationships.discard-button": "Discard", + "item.edit.relationships.edit.buttons.remove": "Remove", + "item.edit.relationships.edit.buttons.undo": "Undo changes", + "item.edit.relationships.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "item.edit.relationships.notifications.discarded.title": "Changed discarded", + "item.edit.relationships.notifications.failed.title": "Error deleting relationship", + "item.edit.relationships.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + "item.edit.relationships.notifications.outdated.title": "Changed outdated", + "item.edit.relationships.notifications.saved.content": "Your changes to this item's relationships were saved.", + "item.edit.relationships.notifications.saved.title": "Relationships saved", + "item.edit.relationships.reinstate-button": "Undo", + "item.edit.relationships.save-button": "Save", "item.edit.tabs.bitstreams.head": "Item Bitstreams", "item.edit.tabs.bitstreams.title": "Item Edit - Bitstreams", "item.edit.tabs.curate.head": "Curate", "item.edit.tabs.curate.title": "Item Edit - Curate", "item.edit.tabs.metadata.head": "Item Metadata", "item.edit.tabs.metadata.title": "Item Edit - Metadata", + "item.edit.tabs.relationships.head": "Item Relationships", + "item.edit.tabs.relationships.title": "Item Edit - Relationships", "item.edit.tabs.status.buttons.authorizations.button": "Authorizations...", "item.edit.tabs.status.buttons.authorizations.label": "Edit item's authorization policies", "item.edit.tabs.status.buttons.delete.button": "Permanently delete", @@ -309,6 +327,7 @@ "loading.community": "Loading community...", "loading.default": "Loading...", "loading.item": "Loading item...", + "loading.items": "Loading items...", "loading.mydspace-results": "Loading items...", "loading.objects": "Loading...", "loading.recent-submissions": "Loading recent submissions...", @@ -581,6 +600,17 @@ "submission.general.save": "Save", "submission.general.save-later": "Save for later", "submission.mydspace": {}, + "submission.sections.describe.relationship-lookup.close": "Close", + "submission.sections.describe.relationship-lookup.deselect-all": "Deselect all", + "submission.sections.describe.relationship-lookup.deselect-page": "Deselect page", + "submission.sections.describe.relationship-lookup.loading": "Loading...", + "submission.sections.describe.relationship-lookup.placeholder": "Search query", + "submission.sections.describe.relationship-lookup.search": "Go", + "submission.sections.describe.relationship-lookup.select-all": "Select all", + "submission.sections.describe.relationship-lookup.select-page": "Select page", + "submission.sections.describe.relationship-lookup.selected": "Selected {{ size }} items", + "submission.sections.describe.relationship-lookup.title": "Select a {{ label }}", + "submission.sections.describe.relationship-lookup.toggle-dropdown": "Toggle dropdown", "submission.sections.general.add-more": "Add more", "submission.sections.general.collection": "Collection", "submission.sections.general.deposit_error_notice": "There was an issue when submitting the item, please try again later.", diff --git a/src/app/core/metadata/metadata-field.model.ts b/src/app/core/metadata/metadata-field.model.ts index 288934e52d..bba9aae35a 100644 --- a/src/app/core/metadata/metadata-field.model.ts +++ b/src/app/core/metadata/metadata-field.model.ts @@ -6,7 +6,7 @@ import { ResourceType } from '../shared/resource-type'; /** * Class the represents a metadata field */ -export class MetadataField implements ListableObject { +export class MetadataField extends ListableObject { static type = new ResourceType('metadatafield'); /** diff --git a/src/app/core/metadata/metadata-schema.model.ts b/src/app/core/metadata/metadata-schema.model.ts index bc05e475cc..481cd0b9b4 100644 --- a/src/app/core/metadata/metadata-schema.model.ts +++ b/src/app/core/metadata/metadata-schema.model.ts @@ -4,7 +4,7 @@ import { ResourceType } from '../shared/resource-type'; /** * Class that represents a metadata schema */ -export class MetadataSchema implements ListableObject { +export class MetadataSchema extends ListableObject { static type = new ResourceType('metadataschema'); /** diff --git a/src/app/core/metadata/normalized-metadata-field.model.ts b/src/app/core/metadata/normalized-metadata-field.model.ts index c6b2ee32f8..3d8750778d 100644 --- a/src/app/core/metadata/normalized-metadata-field.model.ts +++ b/src/app/core/metadata/normalized-metadata-field.model.ts @@ -2,7 +2,6 @@ import { autoserialize, deserialize, inheritSerialization } from 'cerialize'; import { mapsTo, relationship } from '../cache/builders/build-decorators'; import { MetadataField } from './metadata-field.model'; import { NormalizedObject } from '../cache/models/normalized-object.model'; -import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; import { MetadataSchema } from './metadata-schema.model'; /** @@ -10,7 +9,7 @@ import { MetadataSchema } from './metadata-schema.model'; */ @mapsTo(MetadataField) @inheritSerialization(NormalizedObject) -export class NormalizedMetadataField extends NormalizedObject implements ListableObject { +export class NormalizedMetadataField extends NormalizedObject { /** * The identifier of this normalized metadata field diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model.ts index fc39e8c2c4..8f84ea7a77 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model.ts @@ -10,12 +10,11 @@ import { LanguageCode } from '../../models/form-field-language-value.model'; import { AuthorityOptions } from '../../../../../core/integration/models/authority-options.model'; import { hasValue } from '../../../../empty.util'; import { FormFieldMetadataValueObject } from '../../models/form-field-metadata-value.model'; -import { Workspaceitem } from '../../../../../core/submission/models/workspaceitem.model'; import { RelationshipOptions } from '../../models/relationship-options.model'; -import { Item } from '../../../../../core/shared/item.model'; +import { WorkspaceItem } from '../../../../../core/submission/models/workspaceitem.model'; export interface DsDynamicInputModelConfig extends DynamicInputModelConfig { - workspaceItem: Workspaceitem; + workspaceItem: WorkspaceItem; authorityOptions?: AuthorityOptions; languageCodes?: LanguageCode[]; language?: string; @@ -30,7 +29,7 @@ export class DsDynamicInputModel extends DynamicInputModel { @serializable() private _languageCodes: LanguageCode[]; @serializable() private _language: string; @serializable() languageUpdates: Subject; - @serializable() workspaceItem: Workspaceitem; + @serializable() workspaceItem: WorkspaceItem; @serializable() relationship?: RelationshipOptions; @serializable() repeatable?: boolean; diff --git a/src/app/shared/form/builder/form-builder.service.ts b/src/app/shared/form/builder/form-builder.service.ts index 4bbabdd941..82317e02a7 100644 --- a/src/app/shared/form/builder/form-builder.service.ts +++ b/src/app/shared/form/builder/form-builder.service.ts @@ -26,7 +26,7 @@ import { DynamicRowArrayModel } from './ds-dynamic-form-ui/models/ds-dynamic-row import { DsDynamicInputModel } from './ds-dynamic-form-ui/models/ds-dynamic-input.model'; import { FormFieldMetadataValueObject } from './models/form-field-metadata-value.model'; import { isNgbDateStruct } from '../../date.util'; -import { Workspaceitem } from '../../../core/submission/models/workspaceitem.model'; +import { WorkspaceItem } from '../../../core/submission/models/workspaceitem.model'; @Injectable() export class FormBuilderService extends DynamicFormService { @@ -196,7 +196,7 @@ export class FormBuilderService extends DynamicFormService { return result; } - modelFromConfiguration(json: string | SubmissionFormsModel, scopeUUID: string, initFormValues: any = {}, wsi: Workspaceitem, submissionScope?: string, readOnly = false): DynamicFormControlModel[] | never { + modelFromConfiguration(json: string | SubmissionFormsModel, scopeUUID: string, initFormValues: any = {}, wsi: WorkspaceItem, submissionScope?: string, readOnly = false): DynamicFormControlModel[] | never { let rows: DynamicFormControlModel[] = []; const rawData = typeof json === 'string' ? JSON.parse(json, JSONUtils.parseReviver) : json; diff --git a/src/app/shared/form/builder/parsers/concat-field-parser.ts b/src/app/shared/form/builder/parsers/concat-field-parser.ts index ed8b1eaa8d..9011363dc9 100644 --- a/src/app/shared/form/builder/parsers/concat-field-parser.ts +++ b/src/app/shared/form/builder/parsers/concat-field-parser.ts @@ -15,7 +15,7 @@ import { } from '../ds-dynamic-form-ui/models/ds-dynamic-concat.model'; import { isNotEmpty } from '../../../empty.util'; import { ParserOptions } from './parser-options'; -import { Workspaceitem } from '../../../../core/submission/models/workspaceitem.model'; +import { WorkspaceItem } from '../../../../core/submission/models/workspaceitem.model'; export class ConcatFieldParser extends FieldParser { @@ -23,7 +23,7 @@ export class ConcatFieldParser extends FieldParser { protected initFormValues, protected parserOptions: ParserOptions, protected separator: string, - protected workspaceItem: Workspaceitem, + protected workspaceItem: WorkspaceItem, protected firstPlaceholder: string = null, protected secondPlaceholder: string = null) { super(configData, initFormValues, parserOptions, workspaceItem); diff --git a/src/app/shared/form/builder/parsers/date-field-parser.spec.ts b/src/app/shared/form/builder/parsers/date-field-parser.spec.ts index bbcfa60621..81fcb221e1 100644 --- a/src/app/shared/form/builder/parsers/date-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/date-field-parser.spec.ts @@ -1,6 +1,4 @@ import { FormFieldModel } from '../models/form-field.model'; -import { DynamicConcatModel } from '../ds-dynamic-form-ui/models/ds-dynamic-concat.model'; -import { SeriesFieldParser } from './series-field-parser'; import { DateFieldParser } from './date-field-parser'; import { DynamicDsDatePickerModel } from '../ds-dynamic-form-ui/models/date-picker/date-picker.model'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts index f9aa710761..c9894ed791 100644 --- a/src/app/shared/form/builder/parsers/field-parser.ts +++ b/src/app/shared/form/builder/parsers/field-parser.ts @@ -12,12 +12,12 @@ import { DynamicFormControlLayout } from '@ng-dynamic-forms/core'; import { setLayout } from './parser.utils'; import { AuthorityOptions } from '../../../../core/integration/models/authority-options.model'; import { ParserOptions } from './parser-options'; -import { Workspaceitem } from '../../../../core/submission/models/workspaceitem.model'; +import { WorkspaceItem } from '../../../../core/submission/models/workspaceitem.model'; export abstract class FieldParser { protected fieldId: string; - constructor(protected configData: FormFieldModel, protected initFormValues, protected parserOptions: ParserOptions, protected workspaceItem: Workspaceitem) { + constructor(protected configData: FormFieldModel, protected initFormValues, protected parserOptions: ParserOptions, protected workspaceItem: WorkspaceItem) { } public abstract modelFactory(fieldValue?: FormFieldMetadataValueObject, label?: boolean): any; diff --git a/src/app/shared/form/builder/parsers/name-field-parser.ts b/src/app/shared/form/builder/parsers/name-field-parser.ts index de2b931b17..8e2d3aa992 100644 --- a/src/app/shared/form/builder/parsers/name-field-parser.ts +++ b/src/app/shared/form/builder/parsers/name-field-parser.ts @@ -1,11 +1,11 @@ import { FormFieldModel } from '../models/form-field.model'; import { ConcatFieldParser } from './concat-field-parser'; import { ParserOptions } from './parser-options'; -import { Workspaceitem } from '../../../../core/submission/models/workspaceitem.model'; +import { WorkspaceItem } from '../../../../core/submission/models/workspaceitem.model'; export class NameFieldParser extends ConcatFieldParser { - constructor(protected configData: FormFieldModel, protected initFormValues, protected parserOptions: ParserOptions, wsi: Workspaceitem) { + constructor(protected configData: FormFieldModel, protected initFormValues, protected parserOptions: ParserOptions, wsi: WorkspaceItem) { super(configData, initFormValues, parserOptions, ',', wsi, 'form.last-name', 'form.first-name'); } } diff --git a/src/app/shared/form/builder/parsers/row-parser.ts b/src/app/shared/form/builder/parsers/row-parser.ts index ec533eb390..7291b62322 100644 --- a/src/app/shared/form/builder/parsers/row-parser.ts +++ b/src/app/shared/form/builder/parsers/row-parser.ts @@ -10,7 +10,7 @@ import { FormFieldModel } from '../models/form-field.model'; import { ParserType } from './parser-type'; import { ParserOptions } from './parser-options'; import { ParserFactory } from './parser-factory'; -import { Workspaceitem } from '../../../../core/submission/models/workspaceitem.model'; +import { WorkspaceItem } from '../../../../core/submission/models/workspaceitem.model'; export const ROW_ID_PREFIX = 'df-row-group-config-'; @@ -20,7 +20,7 @@ export class RowParser { constructor(protected rowData, protected scopeUUID, protected initFormValues: any, - protected wsi: Workspaceitem, + protected wsi: WorkspaceItem, protected submissionScope, protected readOnly: boolean) { this.authorityOptions = new IntegrationSearchOptions(scopeUUID); diff --git a/src/app/shared/form/builder/parsers/series-field-parser.ts b/src/app/shared/form/builder/parsers/series-field-parser.ts index fbe2716341..37db1cd15c 100644 --- a/src/app/shared/form/builder/parsers/series-field-parser.ts +++ b/src/app/shared/form/builder/parsers/series-field-parser.ts @@ -1,11 +1,11 @@ import { FormFieldModel } from '../models/form-field.model'; import { ConcatFieldParser } from './concat-field-parser'; import { ParserOptions } from './parser-options'; -import { Workspaceitem } from '../../../../core/submission/models/workspaceitem.model'; +import { WorkspaceItem } from '../../../../core/submission/models/workspaceitem.model'; export class SeriesFieldParser extends ConcatFieldParser { - constructor(protected configData: FormFieldModel, protected initFormValues, protected parserOptions: ParserOptions, wsi: Workspaceitem) { + constructor(protected configData: FormFieldModel, protected initFormValues, protected parserOptions: ParserOptions, wsi: WorkspaceItem) { super(configData, initFormValues, parserOptions, ';', wsi); } } diff --git a/src/app/shared/mocks/mock-form-models.ts b/src/app/shared/mocks/mock-form-models.ts index b42df35bf6..0323b76e90 100644 --- a/src/app/shared/mocks/mock-form-models.ts +++ b/src/app/shared/mocks/mock-form-models.ts @@ -10,7 +10,7 @@ import { AuthorityValue } from '../../core/integration/models/authority.value'; import { FormFieldMetadataValueObject } from '../form/builder/models/form-field-metadata-value.model'; import { DynamicRowGroupModel } from '../form/builder/ds-dynamic-form-ui/models/ds-dynamic-row-group-model'; import { FormRowModel } from '../../core/config/models/config-submission-form.model'; -import { Workspaceitem } from '../../core/submission/models/workspaceitem.model'; +import { WorkspaceItem } from '../../core/submission/models/workspaceitem.model'; export const qualdropSelectConfig = { name: 'dc.identifier_QUALDROP_METADATA', @@ -55,7 +55,7 @@ export const qualdropInputConfig = { disabled: false, repeatable: false, value: 'test', - workspaceItem: new Workspaceitem() + workspaceItem: new WorkspaceItem() }; export const mockQualdropSelectModel = new DynamicSelectModel(qualdropSelectConfig); @@ -132,7 +132,7 @@ const relationGroupConfig = { 'issue test 2' ], }, - workspaceItem: new Workspaceitem() + workspaceItem: new WorkspaceItem() }; export const MockRelationModel: DynamicRelationGroupModel = new DynamicRelationGroupModel(relationGroupConfig); @@ -160,7 +160,7 @@ export const inputWithLanguageAndAuthorityConfig = { display: 'testWithLanguageAndAuthority', id: 'testWithLanguageAndAuthority', }, - workspaceItem: new Workspaceitem() + workspaceItem: new WorkspaceItem() }; export const mockInputWithLanguageAndAuthorityModel = new DsDynamicInputModel(inputWithLanguageAndAuthorityConfig); @@ -183,7 +183,7 @@ export const inputWithLanguageConfig = { disabled: false, repeatable: false, value: 'testWithLanguage', - workspaceItem: new Workspaceitem() + workspaceItem: new WorkspaceItem() }; export const mockInputWithLanguageModel = new DsDynamicInputModel(inputWithLanguageConfig); @@ -211,7 +211,7 @@ export const inputWithLanguageAndAuthorityArrayConfig = { display: 'testLanguageAndAuthorityArray', id: 'testLanguageAndAuthorityArray', }], - workspaceItem: new Workspaceitem() + workspaceItem: new WorkspaceItem() }; export const mockInputWithLanguageAndAuthorityArrayModel = new DsDynamicInputModel(inputWithLanguageAndAuthorityArrayConfig); @@ -223,7 +223,7 @@ export const inputWithFormFieldValueConfig = { disabled: false, repeatable: false, value: new FormFieldMetadataValueObject('testWithFormFieldValue'), - workspaceItem: new Workspaceitem() + workspaceItem: new WorkspaceItem() }; export const mockInputWithFormFieldValueModel = new DsDynamicInputModel(inputWithFormFieldValueConfig); @@ -235,7 +235,7 @@ export const inputWithAuthorityValueConfig = { disabled: false, repeatable: false, value: Object.assign({}, new AuthorityValue(), { value: 'testWithAuthorityValue', id: 'testWithAuthorityValue', display: 'testWithAuthorityValue' }), - workspaceItem: new Workspaceitem() + workspaceItem: new WorkspaceItem() }; export const mockInputWithAuthorityValueModel = new DsDynamicInputModel(inputWithAuthorityValueConfig); @@ -247,7 +247,7 @@ export const inputWithObjectValueConfig = { disabled: false, repeatable: false, value: { value: 'testWithObjectValue', id: 'testWithObjectValue', display: 'testWithObjectValue' }, - workspaceItem: new Workspaceitem() + workspaceItem: new WorkspaceItem() }; export const mockInputWithObjectValueModel = new DsDynamicInputModel(inputWithObjectValueConfig); @@ -263,7 +263,7 @@ export const fileFormEditInputConfig = { readOnly: false, disabled: false, repeatable: false, - workspaceItem: new Workspaceitem() + workspaceItem: new WorkspaceItem() }; export const mockFileFormEditInputModel = new DsDynamicInputModel(fileFormEditInputConfig); diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts index 3715c2a34e..8f464b064c 100644 --- a/src/app/submission/sections/form/section-form.component.ts +++ b/src/app/submission/sections/form/section-form.component.ts @@ -31,7 +31,7 @@ import { NotificationsService } from '../../../shared/notifications/notification import { SectionsService } from '../sections.service'; import { difference } from '../../../shared/object.util'; import { WorkspaceitemSectionFormObject } from '../../../core/submission/models/workspaceitem-section-form.model'; -import { Workspaceitem } from '../../../core/submission/models/workspaceitem.model'; +import { WorkspaceItem } from '../../../core/submission/models/workspaceitem.model'; import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem-data.service'; import { combineLatest as combineLatestObservable } from 'rxjs'; import { getSucceededRemoteData } from '../../../core/shared/operators'; @@ -102,7 +102,7 @@ export class SubmissionSectionformComponent extends SectionModelComponent { */ protected subs: Subscription[] = []; - protected workspaceItem: Workspaceitem; + protected workspaceItem: WorkspaceItem; /** * The FormComponent reference */ @@ -154,10 +154,10 @@ export class SubmissionSectionformComponent extends SectionModelComponent { flatMap(() => combineLatestObservable( this.sectionService.getSectionData(this.submissionId, this.sectionData.id), - this.workspaceItemDataService.findById(this.submissionId).pipe(getSucceededRemoteData(), map((wsiRD: RemoteData) => wsiRD.payload)) + this.workspaceItemDataService.findById(this.submissionId).pipe(getSucceededRemoteData(), map((wsiRD: RemoteData) => wsiRD.payload)) )), take(1)) - .subscribe(([sectionData, workspaceItem]: [WorkspaceitemSectionFormObject, Workspaceitem]) => { + .subscribe(([sectionData, workspaceItem]: [WorkspaceitemSectionFormObject, WorkspaceItem]) => { if (isUndefined(this.formModel)) { this.sectionData.errors = []; // Is the first loading so init form