64503: Content Source fetched from API

This commit is contained in:
Kristof De Langhe
2019-08-20 16:25:40 +02:00
parent 2d3dfde6bb
commit 764f532b99
10 changed files with 245 additions and 145 deletions

View File

@@ -101,17 +101,17 @@
"collection.edit.tabs.roles.title": "Collection Edit - Roles",
"collection.edit.tabs.source.external": "This collection harvests its content from an external source",
"collection.edit.tabs.source.form.errors.provider.required": "You must provide a set id of the target collection.",
"collection.edit.tabs.source.form.format": "Metadata Format",
"collection.edit.tabs.source.form.harvest": "Content being harvested",
"collection.edit.tabs.source.form.harvestType": "Content being harvested",
"collection.edit.tabs.source.form.head": "Configure an external source",
"collection.edit.tabs.source.form.options.format.dc": "Simple Dublin Core",
"collection.edit.tabs.source.form.options.format.dim": "DSpace Intermediate Metadata",
"collection.edit.tabs.source.form.options.format.qdc": "Qualified Dublin Core",
"collection.edit.tabs.source.form.options.harvest.1": "Harvest metadata only",
"collection.edit.tabs.source.form.options.harvest.2": "Harvest metadata and references to bitstreams (requires ORE support)",
"collection.edit.tabs.source.form.options.harvest.3": "Harvest metadata and bitstreams (requires ORE support)",
"collection.edit.tabs.source.form.provider": "OAI Provider",
"collection.edit.tabs.source.form.set": "OAI specific set id",
"collection.edit.tabs.source.form.metadataConfigId": "Metadata Format",
"collection.edit.tabs.source.form.oaiSetId": "OAI specific set id",
"collection.edit.tabs.source.form.oaiSource": "OAI Provider",
"collection.edit.tabs.source.form.options.harvestType.METADATA_AND_BITSTREAMS": "Harvest metadata and bitstreams (requires ORE support)",
"collection.edit.tabs.source.form.options.harvestType.METADATA_AND_REF": "Harvest metadata and references to bitstreams (requires ORE support)",
"collection.edit.tabs.source.form.options.harvestType.METADATA_ONLY": "Harvest metadata only",
"collection.edit.tabs.source.form.options.metadataConfigId.dc": "Simple Dublin Core",
"collection.edit.tabs.source.form.options.metadataConfigId.dim": "DSpace Intermediate Metadata",
"collection.edit.tabs.source.form.options.metadataConfigId.qdc": "Qualified Dublin Core",
"collection.edit.tabs.source.head": "Content Source",
"collection.edit.tabs.source.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button",
"collection.edit.tabs.source.notifications.discarded.title": "Changed discarded",

View File

@@ -1,55 +1,57 @@
<div class="container-fluid">
<div class="d-inline-block float-right">
<button class=" btn btn-danger" *ngIf="!(isReinstatable() | async)"
[disabled]="!(hasChanges() | async)"
(click)="discard()"><i
class="fas fa-times"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.discard-button" | translate}}</span>
</button>
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
(click)="reinstate()"><i
class="fas fa-undo-alt"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.reinstate-button" | translate}}</span>
</button>
<button class="btn btn-primary" [disabled]="!(hasChanges() | async) || !isValid()"
(click)="onSubmit()"><i
class="fas fa-save"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.save-button" | translate}}</span>
</button>
<ng-container *ngIf="contentSource">
<div class="container-fluid">
<div class="d-inline-block float-right">
<button class=" btn btn-danger" *ngIf="!(isReinstatable() | async)"
[disabled]="!(hasChanges() | async)"
(click)="discard()"><i
class="fas fa-times"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.discard-button" | translate}}</span>
</button>
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
(click)="reinstate()"><i
class="fas fa-undo-alt"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.reinstate-button" | translate}}</span>
</button>
<button class="btn btn-primary" [disabled]="!(hasChanges() | async) || !isValid()"
(click)="onSubmit()"><i
class="fas fa-save"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.save-button" | translate}}</span>
</button>
</div>
<h4>{{ 'collection.edit.tabs.source.head' | translate }}</h4>
<div class="form-check mb-4">
<input type="checkbox" class="form-check-input" id="externalSourceCheck" [checked]="(contentSource.harvestType !== harvestTypeNone)" (change)="changeExternalSource()">
<label class="form-check-label" for="externalSourceCheck">{{ 'collection.edit.tabs.source.external' | translate }}</label>
</div>
<h4 *ngIf="(contentSource.harvestType !== harvestTypeNone)">{{ 'collection.edit.tabs.source.form.head' | translate }}</h4>
</div>
<h4>{{ 'collection.edit.tabs.source.head' | translate }}</h4>
<div class="form-check mb-4">
<input type="checkbox" class="form-check-input" id="externalSourceCheck" [checked]="contentSource.enabled" (change)="changeExternalSource()">
<label class="form-check-label" for="externalSourceCheck">{{ 'collection.edit.tabs.source.external' | translate }}</label>
<ds-form *ngIf="formGroup && (contentSource.harvestType !== harvestTypeNone)"
[formId]="'collection-source-form-id'"
[formGroup]="formGroup"
[formModel]="formModel"
[formLayout]="formLayout"
[displaySubmit]="false"
(dfChange)="onChange($event)"
(submitForm)="onSubmit()"
(cancel)="onCancel()"></ds-form>
<div class="container-fluid" *ngIf="(contentSource.harvestType !== harvestTypeNone)">
<div class="d-inline-block float-right">
<button class=" btn btn-danger" *ngIf="!(isReinstatable() | async)"
[disabled]="!(hasChanges() | async)"
(click)="discard()"><i
class="fas fa-times"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.discard-button" | translate}}</span>
</button>
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
(click)="reinstate()"><i
class="fas fa-undo-alt"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.reinstate-button" | translate}}</span>
</button>
<button class="btn btn-primary" [disabled]="!(hasChanges() | async) || !isValid()"
(click)="onSubmit()"><i
class="fas fa-save"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.save-button" | translate}}</span>
</button>
</div>
</div>
<h4 *ngIf="contentSource.enabled">{{ 'collection.edit.tabs.source.form.head' | translate }}</h4>
</div>
<ds-form *ngIf="formGroup && contentSource.enabled"
[formId]="'collection-source-form-id'"
[formGroup]="formGroup"
[formModel]="formModel"
[formLayout]="formLayout"
[displaySubmit]="false"
(dfChange)="onChange($event)"
(submitForm)="onSubmit()"
(cancel)="onCancel()"></ds-form>
<div class="container-fluid" *ngIf="contentSource.enabled">
<div class="d-inline-block float-right">
<button class=" btn btn-danger" *ngIf="!(isReinstatable() | async)"
[disabled]="!(hasChanges() | async)"
(click)="discard()"><i
class="fas fa-times"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.discard-button" | translate}}</span>
</button>
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
(click)="reinstate()"><i
class="fas fa-undo-alt"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.reinstate-button" | translate}}</span>
</button>
<button class="btn btn-primary" [disabled]="!(hasChanges() | async) || !isValid()"
(click)="onSubmit()"><i
class="fas fa-save"></i>
<span class="d-none d-sm-inline">&nbsp;{{"item.edit.metadata.save-button" | translate}}</span>
</button>
</div>
</div>
</ng-container>

View File

@@ -1,8 +1,13 @@
import { Component, Inject, OnDestroy, OnInit } from '@angular/core';
import { AbstractTrackableComponent } from '../../../shared/trackable/abstract-trackable.component';
import {
DynamicFormControlModel, DynamicFormGroupModel, DynamicFormLayout, DynamicFormService,
DynamicInputModel, DynamicOptionControlModel, DynamicRadioGroupModel,
DynamicFormControlModel,
DynamicFormGroupModel,
DynamicFormLayout,
DynamicFormService,
DynamicInputModel,
DynamicOptionControlModel,
DynamicRadioGroupModel,
DynamicSelectModel,
DynamicTextAreaModel
} from '@ng-dynamic-forms/core';
@@ -12,16 +17,18 @@ import { ObjectUpdatesService } from '../../../core/data/object-updates/object-u
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { FormGroup } from '@angular/forms';
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
import { ContentSource } from '../../../core/shared/content-source.model';
import { ContentSource, ContentSourceHarvestType } from '../../../core/shared/content-source.model';
import { Observable } from 'rxjs/internal/Observable';
import { RemoteData } from '../../../core/data/remote-data';
import { Collection } from '../../../core/shared/collection.model';
import { first, map } from 'rxjs/operators';
import { first, map, switchMap, take } from 'rxjs/operators';
import { ActivatedRoute, Router } from '@angular/router';
import { FieldUpdate, FieldUpdates } from '../../../core/data/object-updates/object-updates.reducer';
import { Subscription } from 'rxjs/internal/Subscription';
import { cloneDeep } from 'lodash';
import { GLOBAL_CONFIG, GlobalConfig } from '../../../../config';
import { CollectionDataService } from '../../../core/data/collection-data.service';
import { getSucceededRemoteData } from '../../../core/shared/operators';
/**
* Component for managing the content source of the collection
@@ -64,9 +71,9 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
/**
* The Dynamic Input Model for the OAI Provider
*/
providerModel = new DynamicInputModel({
id: 'provider',
name: 'provider',
oaiSourceModel = new DynamicInputModel({
id: 'oaiSource',
name: 'oaiSource',
required: true,
validators: {
required: null
@@ -79,17 +86,17 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
/**
* The Dynamic Input Model for the OAI Set
*/
setModel = new DynamicInputModel({
id: 'set',
name: 'set'
oaiSetIdModel = new DynamicInputModel({
id: 'oaiSetId',
name: 'oaiSetId'
});
/**
* The Dynamic Input Model for the Metadata Format used
*/
formatModel = new DynamicSelectModel({
id: 'format',
name: 'format',
metadataConfigIdModel = new DynamicSelectModel({
id: 'metadataConfigId',
name: 'metadataConfigId',
options: [
{
value: 'dc'
@@ -100,24 +107,25 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
{
value: 'dim'
}
]
],
value: 'dc'
});
/**
* The Dynamic Input Model for the type of harvesting
*/
harvestModel = new DynamicRadioGroupModel<number>({
id: 'harvest',
name: 'harvest',
harvestTypeModel = new DynamicRadioGroupModel<string>({
id: 'harvestType',
name: 'harvestType',
options: [
{
value: 1
value: ContentSourceHarvestType.Metadata
},
{
value: 2
value: ContentSourceHarvestType.MetadataAndRef
},
{
value: 3
value: ContentSourceHarvestType.MetadataAndBitstreams
}
]
});
@@ -125,7 +133,7 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
/**
* All input models in a simple array for easier iterations
*/
inputModels = [this.providerModel, this.setModel, this.formatModel, this.harvestModel];
inputModels = [this.oaiSourceModel, this.oaiSetIdModel, this.metadataConfigIdModel, this.harvestTypeModel];
/**
* The dynamic form fields used for editing the content source of a collection
@@ -133,22 +141,22 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
*/
formModel: DynamicFormControlModel[] = [
new DynamicFormGroupModel({
id: 'providerContainer',
id: 'oaiSourceContainer',
group: [
this.providerModel
this.oaiSourceModel
]
}),
new DynamicFormGroupModel({
id: 'setContainer',
id: 'oaiSetContainer',
group: [
this.setModel,
this.formatModel
this.oaiSetIdModel,
this.metadataConfigIdModel
]
}),
new DynamicFormGroupModel({
id: 'harvestContainer',
id: 'harvestTypeContainer',
group: [
this.harvestModel
this.harvestTypeModel
]
})
];
@@ -157,38 +165,38 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
* Layout used for structuring the form inputs
*/
formLayout: DynamicFormLayout = {
provider: {
oaiSource: {
grid: {
host: 'col-12 d-inline-block'
}
},
set: {
oaiSetId: {
grid: {
host: 'col col-sm-6 d-inline-block'
}
},
format: {
metadataConfigId: {
grid: {
host: 'col col-sm-6 d-inline-block'
}
},
harvest: {
harvestType: {
grid: {
host: 'col-12',
option: 'btn-outline-secondary'
}
},
setContainer: {
oaiSetContainer: {
grid: {
host: 'row'
}
},
providerContainer: {
oaiSourceContainer: {
grid: {
host: 'row'
}
},
harvestContainer: {
harvestTypeContainer: {
grid: {
host: 'row'
}
@@ -205,6 +213,8 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
*/
updateSub: Subscription;
harvestTypeNone = ContentSourceHarvestType.None;
public constructor(public objectUpdatesService: ObjectUpdatesService,
public notificationsService: NotificationsService,
protected location: Location,
@@ -212,7 +222,8 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
protected translate: TranslateService,
protected route: ActivatedRoute,
protected router: Router,
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,) {
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
protected collectionService: CollectionDataService) {
super(objectUpdatesService, notificationsService, translate);
}
@@ -229,16 +240,21 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
this.formGroup = this.formService.createFormGroup(this.formModel);
this.collectionRD$ = this.route.parent.data.pipe(first(), map((data) => data.dso));
/* Create a new ContentSource object - TODO: Update to be fetched from the collection */
this.contentSource = new ContentSource();
this.collectionRD$.pipe(
getSucceededRemoteData(),
map((col) => col.payload.uuid),
switchMap((uuid) => this.collectionService.getContentSource(uuid)),
take(1)
).subscribe((contentSource: ContentSource) => {
this.contentSource = contentSource;
this.initializeOriginalContentSource();
});
this.updateFieldTranslations();
this.translate.onLangChange
.subscribe(() => {
this.updateFieldTranslations();
});
this.initializeOriginalContentSource();
}
/**
@@ -254,15 +270,15 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
if (update) {
const field = update.field as ContentSource;
this.formGroup.patchValue({
providerContainer: {
provider: field.provider
oaiSourceContainer: {
oaiSource: field.oaiSource
},
setContainer: {
set: field.set,
format: field.format
oaiSetContainer: {
oaiSetId: field.oaiSetId,
metadataConfigId: field.metadataConfigId
},
harvestContainer: {
harvest: field.harvest
harvestTypeContainer: {
harvestType: field.harvestType
}
});
this.contentSource = cloneDeep(field);
@@ -307,7 +323,7 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
* @param event
*/
onChange(event) {
this.updateContentSourceField(event.model);
this.updateContentSourceField(event.model, true);
this.saveFieldUpdate();
}
@@ -331,24 +347,28 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
* Is the current form valid to be submitted ?
*/
isValid(): boolean {
return !this.contentSource.enabled || this.formGroup.valid;
return (this.contentSource.harvestType === ContentSourceHarvestType.None) || this.formGroup.valid;
}
/**
* Switch the external source on or off and fire a field update
*/
changeExternalSource() {
this.contentSource.enabled = !this.contentSource.enabled;
this.updateContentSource();
if (this.contentSource.harvestType === ContentSourceHarvestType.None) {
this.contentSource.harvestType = ContentSourceHarvestType.Metadata;
} else {
this.contentSource.harvestType = ContentSourceHarvestType.None;
}
this.updateContentSource(false);
}
/**
* Loop over all inputs and update the Content Source with their value
*/
updateContentSource() {
updateContentSource(updateHarvestType: boolean) {
this.inputModels.forEach(
(fieldModel: DynamicInputModel) => {
this.updateContentSourceField(fieldModel)
this.updateContentSourceField(fieldModel, updateHarvestType)
}
);
this.saveFieldUpdate();
@@ -358,8 +378,8 @@ export class CollectionSourceComponent extends AbstractTrackableComponent implem
* Update the Content Source with the value from a DynamicInputModel
* @param fieldModel
*/
updateContentSourceField(fieldModel: DynamicInputModel) {
if (hasValue(fieldModel.value)) {
updateContentSourceField(fieldModel: DynamicInputModel, updateHarvestType: boolean) {
if (hasValue(fieldModel.value) && !(fieldModel.id === this.harvestTypeModel.id && !updateHarvestType)) {
this.contentSource[fieldModel.id] = fieldModel.value;
}
}

View File

@@ -14,6 +14,7 @@ import { DSpaceObject } from '../shared/dspace-object.model';
import { NormalizedAuthStatus } from '../auth/models/normalized-auth-status.model';
import { MetadataSchema } from '../metadata/metadata-schema.model';
import { MetadataField } from '../metadata/metadata-field.model';
import { ContentSource } from '../shared/content-source.model';
/* tslint:disable:max-classes-per-file */
export class RestResponse {
@@ -288,4 +289,17 @@ export class FilteredDiscoveryQueryResponse extends RestResponse {
super(true, statusCode, statusText);
}
}
/**
* A successful response containing exactly one MetadataSchema
*/
export class ContentSourceSuccessResponse extends RestResponse {
constructor(
public contentsource: ContentSource,
public statusCode: number,
public statusText: string,
) {
super(true, statusCode, statusText);
}
}
/* tslint:enable:max-classes-per-file */

View File

@@ -117,6 +117,7 @@ import { MetadatafieldParsingService } from './data/metadatafield-parsing.servic
import { NormalizedSubmissionUploadsModel } from './config/models/normalized-config-submission-uploads.model';
import { NormalizedBrowseEntry } from './shared/normalized-browse-entry.model';
import { BrowseDefinition } from './shared/browse-definition.model';
import { ContentSourceResponseParsingService } from './data/content-source-response-parsing.service';
const IMPORTS = [
CommonModule,
@@ -203,6 +204,7 @@ const PROVIDERS = [
TaskResponseParsingService,
ClaimedTaskDataService,
PoolTaskDataService,
ContentSourceResponseParsingService,
// register AuthInterceptor as HttpInterceptor
{
provide: HTTP_INTERCEPTORS,

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { filter, map, take } from 'rxjs/operators';
import { filter, map, take, tap } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
@@ -16,9 +16,12 @@ import { HttpClient } from '@angular/common/http';
import { NormalizedObjectBuildService } from '../cache/builders/normalized-object-build.service';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
import { Observable } from 'rxjs/internal/Observable';
import { FindAllOptions } from './request.models';
import { ContentSourceRequest, FindAllOptions, RestRequest } from './request.models';
import { RemoteData } from './remote-data';
import { PaginatedList } from './paginated-list';
import { ContentSource } from '../shared/content-source.model';
import { configureRequest, filterSuccessfulResponses, getRequestFromRequestHref } from '../shared/operators';
import { ContentSourceSuccessResponse } from '../cache/response.models';
@Injectable()
export class CollectionDataService extends ComColDataService<Collection> {
@@ -57,4 +60,21 @@ export class CollectionDataService extends ComColDataService<Collection> {
map((collections: RemoteData<PaginatedList<Collection>>) => collections.payload.totalElements > 0)
);
}
getHarvesterEndpoint(collectionId: string): Observable<string> {
return this.halService.getEndpoint(this.linkPath).pipe(
map((href: string) => `${href}/${collectionId}/harvester`)
);
}
getContentSource(collectionId: string): Observable<ContentSource> {
return this.getHarvesterEndpoint(collectionId).pipe(
map((href: string) => new ContentSourceRequest(this.requestService.generateRequestId(), href)),
configureRequest(this.requestService),
map((request: RestRequest) => request.href),
getRequestFromRequestHref(this.requestService),
filterSuccessfulResponses(),
map((response: ContentSourceSuccessResponse) => response.contentsource)
);
}
}

View File

@@ -0,0 +1,19 @@
import { Injectable } from '@angular/core';
import { ResponseParsingService } from './parsing.service';
import { RestRequest } from './request.models';
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
import { ContentSourceSuccessResponse, RestResponse } from '../cache/response.models';
import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer';
import { ContentSource } from '../shared/content-source.model';
@Injectable()
export class ContentSourceResponseParsingService implements ResponseParsingService {
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
const payload = data.payload;
const deserialized = new DSpaceRESTv2Serializer(ContentSource).deserialize(payload);
return new ContentSourceSuccessResponse(deserialized, data.statusCode, data.statusText);
}
}

View File

@@ -93,14 +93,16 @@ export class ObjectUpdatesService {
const objectUpdates = this.getObjectEntry(url);
return objectUpdates.pipe(map((objectEntry) => {
const fieldUpdates: FieldUpdates = {};
Object.keys(objectEntry.fieldStates).forEach((uuid) => {
let fieldUpdate = objectEntry.fieldUpdates[uuid];
if (isEmpty(fieldUpdate)) {
const identifiable = initialFields.find((object: Identifiable) => object.uuid === uuid);
fieldUpdate = { field: identifiable, changeType: undefined };
}
fieldUpdates[uuid] = fieldUpdate;
});
if (hasValue(objectEntry)) {
Object.keys(objectEntry.fieldStates).forEach((uuid) => {
let fieldUpdate = objectEntry.fieldUpdates[uuid];
if (isEmpty(fieldUpdate)) {
const identifiable = initialFields.find((object: Identifiable) => object.uuid === uuid);
fieldUpdate = {field: identifiable, changeType: undefined};
}
fieldUpdates[uuid] = fieldUpdate;
});
}
return fieldUpdates;
}))
}

View File

@@ -18,6 +18,7 @@ import { MetadataschemaParsingService } from './metadataschema-parsing.service';
import { MetadatafieldParsingService } from './metadatafield-parsing.service';
import { URLCombiner } from '../url-combiner/url-combiner';
import { TaskResponseParsingService } from '../tasks/task-response-parsing.service';
import { ContentSourceResponseParsingService } from './content-source-response-parsing.service';
/* tslint:disable:max-classes-per-file */
@@ -358,6 +359,16 @@ export class CreateRequest extends PostRequest {
}
}
export class ContentSourceRequest extends GetRequest {
constructor(uuid: string, href: string) {
super(uuid, href);
}
getResponseParser(): GenericConstructor<ResponseParsingService> {
return ContentSourceResponseParsingService;
}
}
/**
* Request to delete an object based on its identifier
*/

View File

@@ -1,41 +1,51 @@
import { v4 as uuid } from 'uuid';
import { autoserialize, autoserializeAs } from 'cerialize';
export enum ContentSourceHarvestType {
None = 'NONE',
Metadata = 'METADATA_ONLY',
MetadataAndRef = 'METADATA_AND_REF',
MetadataAndBitstreams = 'METADATA_AND_BITSTREAMS'
}
/**
* A model class that holds information about the Content Source of a Collection
*/
export class ContentSource {
/**
* Unique identifier
* Unique identifier, this is necessary to store the ContentSource in FieldUpdates
* Because the ContentSource coming from the REST API doesn't have a UUID, we're using the selflink
*/
@autoserializeAs('self')
uuid: string;
/**
* Does this collection harvest its content from an external source ?
* OAI Provider / Source
*/
enabled = false;
/**
* OAI Provider
*/
provider: string;
@autoserializeAs('oai_source')
oaiSource: string;
/**
* OAI Specific set ID
*/
set: string;
@autoserializeAs('oai_set_id')
oaiSetId: string;
/**
* Metadata Format
* The ID of the metadata format used
*/
format = 'dc';
@autoserializeAs('metadata_config_id')
metadataConfigId = 'dc';
/**
* Type of content being harvested
* Defaults to 'NONE', meaning the collection doesn't harvest its content from an external source
*/
harvest = 3;
@autoserializeAs('harvest_type')
harvestType = ContentSourceHarvestType.None;
constructor() {
// TODO: Remove this once the Content Source is fetched from the REST API and a custom generated UUID is not necessary anymore
this.uuid = uuid();
}
/**
* The REST link to itself
*/
@autoserialize
self: string;
}