mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Merge pull request #697 from atmire/Refactor-registry-service-and-associated-models
Refactor registry service and associated models
This commit is contained in:
@@ -4,6 +4,7 @@ import { NgModule } from '@angular/core';
|
|||||||
import { MetadataSchemaComponent } from './metadata-schema/metadata-schema.component';
|
import { MetadataSchemaComponent } from './metadata-schema/metadata-schema.component';
|
||||||
import { URLCombiner } from '../../core/url-combiner/url-combiner';
|
import { URLCombiner } from '../../core/url-combiner/url-combiner';
|
||||||
import { getRegistriesModulePath } from '../admin-routing.module';
|
import { getRegistriesModulePath } from '../admin-routing.module';
|
||||||
|
import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver';
|
||||||
|
|
||||||
const BITSTREAMFORMATS_MODULE_PATH = 'bitstream-formats';
|
const BITSTREAMFORMATS_MODULE_PATH = 'bitstream-formats';
|
||||||
|
|
||||||
@@ -14,16 +15,28 @@ export function getBitstreamFormatsModulePath() {
|
|||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
RouterModule.forChild([
|
RouterModule.forChild([
|
||||||
{path: 'metadata', component: MetadataRegistryComponent, data: {title: 'admin.registries.metadata.title'}},
|
|
||||||
{
|
{
|
||||||
path: 'metadata/:schemaName',
|
path: 'metadata',
|
||||||
component: MetadataSchemaComponent,
|
resolve: { breadcrumb: I18nBreadcrumbResolver },
|
||||||
data: {title: 'admin.registries.schema.title'}
|
data: {title: 'admin.registries.metadata.title', breadcrumbKey: 'admin.registries.metadata'},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: MetadataRegistryComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':schemaName',
|
||||||
|
resolve: { breadcrumb: I18nBreadcrumbResolver },
|
||||||
|
component: MetadataSchemaComponent,
|
||||||
|
data: {title: 'admin.registries.schema.title', breadcrumbKey: 'admin.registries.schema'}
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: BITSTREAMFORMATS_MODULE_PATH,
|
path: BITSTREAMFORMATS_MODULE_PATH,
|
||||||
|
resolve: { breadcrumb: I18nBreadcrumbResolver },
|
||||||
loadChildren: './bitstream-formats/bitstream-formats.module#BitstreamFormatsModule',
|
loadChildren: './bitstream-formats/bitstream-formats.module#BitstreamFormatsModule',
|
||||||
data: {title: 'admin.registries.bitstream-formats.title'}
|
data: {title: 'admin.registries.bitstream-formats.title', breadcrumbKey: 'admin.registries.bitstream-formats'}
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
|
@@ -4,6 +4,7 @@ import { BitstreamFormatsResolver } from './bitstream-formats.resolver';
|
|||||||
import { EditBitstreamFormatComponent } from './edit-bitstream-format/edit-bitstream-format.component';
|
import { EditBitstreamFormatComponent } from './edit-bitstream-format/edit-bitstream-format.component';
|
||||||
import { BitstreamFormatsComponent } from './bitstream-formats.component';
|
import { BitstreamFormatsComponent } from './bitstream-formats.component';
|
||||||
import { AddBitstreamFormatComponent } from './add-bitstream-format/add-bitstream-format.component';
|
import { AddBitstreamFormatComponent } from './add-bitstream-format/add-bitstream-format.component';
|
||||||
|
import { I18nBreadcrumbResolver } from '../../../core/breadcrumbs/i18n-breadcrumb.resolver';
|
||||||
|
|
||||||
const BITSTREAMFORMAT_EDIT_PATH = ':id/edit';
|
const BITSTREAMFORMAT_EDIT_PATH = ':id/edit';
|
||||||
const BITSTREAMFORMAT_ADD_PATH = 'add';
|
const BITSTREAMFORMAT_ADD_PATH = 'add';
|
||||||
@@ -17,14 +18,18 @@ const BITSTREAMFORMAT_ADD_PATH = 'add';
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: BITSTREAMFORMAT_ADD_PATH,
|
path: BITSTREAMFORMAT_ADD_PATH,
|
||||||
|
resolve: { breadcrumb: I18nBreadcrumbResolver },
|
||||||
component: AddBitstreamFormatComponent,
|
component: AddBitstreamFormatComponent,
|
||||||
|
data: {breadcrumbKey: 'admin.registries.bitstream-formats.create'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: BITSTREAMFORMAT_EDIT_PATH,
|
path: BITSTREAMFORMAT_EDIT_PATH,
|
||||||
component: EditBitstreamFormatComponent,
|
component: EditBitstreamFormatComponent,
|
||||||
resolve: {
|
resolve: {
|
||||||
bitstreamFormat: BitstreamFormatsResolver
|
bitstreamFormat: BitstreamFormatsResolver,
|
||||||
}
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: {breadcrumbKey: 'admin.registries.bitstream-formats.edit'}
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
],
|
],
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
<ds-pagination
|
<ds-pagination
|
||||||
*ngIf="(metadataSchemas | async)?.payload?.totalElements > 0"
|
*ngIf="(metadataSchemas | async)?.payload?.totalElements > 0"
|
||||||
[paginationOptions]="config"
|
[paginationOptions]="config"
|
||||||
[pageInfoState]="(metadataSchemas | async)?.payload"
|
|
||||||
[collectionSize]="(metadataSchemas | async)?.payload?.totalElements"
|
[collectionSize]="(metadataSchemas | async)?.payload?.totalElements"
|
||||||
[hideGear]="true"
|
[hideGear]="true"
|
||||||
[hidePagerWhenSinglePage]="true"
|
[hidePagerWhenSinglePage]="true"
|
||||||
|
@@ -4,7 +4,7 @@ import { Observable, combineLatest as observableCombineLatest } from 'rxjs';
|
|||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||||
import { map, take } from 'rxjs/operators';
|
import { filter, map, switchMap, take } from 'rxjs/operators';
|
||||||
import { hasValue } from '../../../shared/empty.util';
|
import { hasValue } from '../../../shared/empty.util';
|
||||||
import { RestResponse } from '../../../core/cache/response.models';
|
import { RestResponse } from '../../../core/cache/response.models';
|
||||||
import { zip } from 'rxjs/internal/observable/zip';
|
import { zip } from 'rxjs/internal/observable/zip';
|
||||||
@@ -12,6 +12,8 @@ import { NotificationsService } from '../../../shared/notifications/notification
|
|||||||
import { Route, Router } from '@angular/router';
|
import { Route, Router } from '@angular/router';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||||
|
import { toFindListOptions } from '../../../shared/pagination/pagination.utils';
|
||||||
|
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-metadata-registry',
|
selector: 'ds-metadata-registry',
|
||||||
@@ -37,6 +39,11 @@ export class MetadataRegistryComponent {
|
|||||||
pageSize: 25
|
pageSize: 25
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the list of MetadataSchemas needs an update
|
||||||
|
*/
|
||||||
|
needsUpdate$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
|
||||||
|
|
||||||
constructor(private registryService: RegistryService,
|
constructor(private registryService: RegistryService,
|
||||||
private notificationsService: NotificationsService,
|
private notificationsService: NotificationsService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
@@ -50,14 +57,17 @@ export class MetadataRegistryComponent {
|
|||||||
*/
|
*/
|
||||||
onPageChange(event) {
|
onPageChange(event) {
|
||||||
this.config.currentPage = event;
|
this.config.currentPage = event;
|
||||||
this.updateSchemas();
|
this.forceUpdateSchemas();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the list of schemas by fetching it from the rest api or cache
|
* Update the list of schemas by fetching it from the rest api or cache
|
||||||
*/
|
*/
|
||||||
private updateSchemas() {
|
private updateSchemas() {
|
||||||
this.metadataSchemas = this.registryService.getMetadataSchemas(this.config);
|
this.metadataSchemas = this.needsUpdate$.pipe(
|
||||||
|
filter((update) => update === true),
|
||||||
|
switchMap(() => this.registryService.getMetadataSchemas(toFindListOptions(this.config)))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,8 +75,7 @@ export class MetadataRegistryComponent {
|
|||||||
* a new REST call
|
* a new REST call
|
||||||
*/
|
*/
|
||||||
public forceUpdateSchemas() {
|
public forceUpdateSchemas() {
|
||||||
this.registryService.clearMetadataSchemaRequests().subscribe();
|
this.needsUpdate$.next(true);
|
||||||
this.updateSchemas();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -125,6 +134,7 @@ export class MetadataRegistryComponent {
|
|||||||
* Delete all the selected metadata schemas
|
* Delete all the selected metadata schemas
|
||||||
*/
|
*/
|
||||||
deleteSchemas() {
|
deleteSchemas() {
|
||||||
|
this.registryService.clearMetadataSchemaRequests().subscribe();
|
||||||
this.registryService.getSelectedMetadataSchemas().pipe(take(1)).subscribe(
|
this.registryService.getSelectedMetadataSchemas().pipe(take(1)).subscribe(
|
||||||
(schemas) => {
|
(schemas) => {
|
||||||
const tasks$ = [];
|
const tasks$ = [];
|
||||||
|
@@ -21,7 +21,8 @@ describe('MetadataSchemaFormComponent', () => {
|
|||||||
const registryServiceStub = {
|
const registryServiceStub = {
|
||||||
getActiveMetadataSchema: () => observableOf(undefined),
|
getActiveMetadataSchema: () => observableOf(undefined),
|
||||||
createOrUpdateMetadataSchema: (schema: MetadataSchema) => observableOf(schema),
|
createOrUpdateMetadataSchema: (schema: MetadataSchema) => observableOf(schema),
|
||||||
cancelEditMetadataSchema: () => {}
|
cancelEditMetadataSchema: () => {},
|
||||||
|
clearMetadataSchemaRequests: () => observableOf(undefined)
|
||||||
};
|
};
|
||||||
const formBuilderServiceStub = {
|
const formBuilderServiceStub = {
|
||||||
createFormGroup: () => {
|
createFormGroup: () => {
|
||||||
|
@@ -128,6 +128,7 @@ export class MetadataSchemaFormComponent implements OnInit, OnDestroy {
|
|||||||
* Emit the updated/created schema using the EventEmitter submitForm
|
* Emit the updated/created schema using the EventEmitter submitForm
|
||||||
*/
|
*/
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
|
this.registryService.clearMetadataSchemaRequests().subscribe();
|
||||||
this.registryService.getActiveMetadataSchema().pipe(take(1)).subscribe(
|
this.registryService.getActiveMetadataSchema().pipe(take(1)).subscribe(
|
||||||
(schema) => {
|
(schema) => {
|
||||||
const values = {
|
const values = {
|
||||||
@@ -139,7 +140,7 @@ export class MetadataSchemaFormComponent implements OnInit, OnDestroy {
|
|||||||
this.submitForm.emit(newSchema);
|
this.submitForm.emit(newSchema);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.registryService.createOrUpdateMetadataSchema(Object.assign(new MetadataSchema(), {
|
this.registryService.createOrUpdateMetadataSchema(Object.assign(new MetadataSchema(), schema, {
|
||||||
id: schema.id,
|
id: schema.id,
|
||||||
prefix: (values.prefix ? values.prefix : schema.prefix),
|
prefix: (values.prefix ? values.prefix : schema.prefix),
|
||||||
namespace: (values.namespace ? values.namespace : schema.namespace)
|
namespace: (values.namespace ? values.namespace : schema.namespace)
|
||||||
@@ -148,6 +149,7 @@ export class MetadataSchemaFormComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.clearFields();
|
this.clearFields();
|
||||||
|
this.registryService.cancelEditMetadataSchema();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,7 @@ describe('MetadataFieldFormComponent', () => {
|
|||||||
createOrUpdateMetadataField: (field: MetadataField) => observableOf(field),
|
createOrUpdateMetadataField: (field: MetadataField) => observableOf(field),
|
||||||
cancelEditMetadataField: () => {},
|
cancelEditMetadataField: () => {},
|
||||||
cancelEditMetadataSchema: () => {},
|
cancelEditMetadataSchema: () => {},
|
||||||
|
clearMetadataFieldRequests: () => observableOf(undefined)
|
||||||
};
|
};
|
||||||
const formBuilderServiceStub = {
|
const formBuilderServiceStub = {
|
||||||
createFormGroup: () => {
|
createFormGroup: () => {
|
||||||
|
@@ -153,6 +153,7 @@ export class MetadataFieldFormComponent implements OnInit, OnDestroy {
|
|||||||
* Emit the updated/created field using the EventEmitter submitForm
|
* Emit the updated/created field using the EventEmitter submitForm
|
||||||
*/
|
*/
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
|
this.registryService.clearMetadataFieldRequests().subscribe();
|
||||||
this.registryService.getActiveMetadataField().pipe(take(1)).subscribe(
|
this.registryService.getActiveMetadataField().pipe(take(1)).subscribe(
|
||||||
(field) => {
|
(field) => {
|
||||||
const values = {
|
const values = {
|
||||||
@@ -166,7 +167,7 @@ export class MetadataFieldFormComponent implements OnInit, OnDestroy {
|
|||||||
this.submitForm.emit(newField);
|
this.submitForm.emit(newField);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.registryService.createOrUpdateMetadataField(Object.assign(new MetadataField(), {
|
this.registryService.createOrUpdateMetadataField(Object.assign(new MetadataField(), field, {
|
||||||
id: field.id,
|
id: field.id,
|
||||||
schema: this.metadataSchema,
|
schema: this.metadataSchema,
|
||||||
element: (values.element ? values.element : field.element),
|
element: (values.element ? values.element : field.element),
|
||||||
@@ -177,6 +178,7 @@ export class MetadataFieldFormComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.clearFields();
|
this.clearFields();
|
||||||
|
this.registryService.cancelEditMetadataField();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -1,36 +1,37 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="metadata-schema row">
|
<div class="metadata-schema row">
|
||||||
<div class="col-12">
|
<div class="col-12" *ngVar="(metadataSchema$ | async) as schema">
|
||||||
|
|
||||||
<h2 id="header" class="border-bottom pb-2">{{'admin.registries.schema.head' | translate}}: "{{(metadataSchema | async)?.payload?.prefix}}"</h2>
|
<h2 id="header" class="border-bottom pb-2">{{'admin.registries.schema.head' | translate}}: "{{schema?.prefix}}"</h2>
|
||||||
|
|
||||||
<p id="description" class="pb-2">{{'admin.registries.schema.description' | translate:namespace }}</p>
|
<p id="description" class="pb-2">{{'admin.registries.schema.description' | translate:{ namespace: schema?.namespace } }}</p>
|
||||||
|
|
||||||
<ds-metadata-field-form
|
<ds-metadata-field-form
|
||||||
[metadataSchema]="(metadataSchema | async)?.payload"
|
[metadataSchema]="schema"
|
||||||
(submitForm)="forceUpdateFields()"></ds-metadata-field-form>
|
(submitForm)="forceUpdateFields()"></ds-metadata-field-form>
|
||||||
|
|
||||||
<h3>{{'admin.registries.schema.fields.head' | translate}}</h3>
|
<h3>{{'admin.registries.schema.fields.head' | translate}}</h3>
|
||||||
|
|
||||||
<ds-pagination
|
<ng-container *ngVar="(metadataFields$ | async)?.payload as fields">
|
||||||
*ngIf="(metadataFields | async)?.payload?.totalElements > 0"
|
<ds-pagination
|
||||||
[paginationOptions]="config"
|
*ngIf="fields?.totalElements > 0"
|
||||||
[pageInfoState]="(metadataFields | async)?.payload"
|
[paginationOptions]="config"
|
||||||
[collectionSize]="(metadataFields | async)?.payload?.totalElements"
|
[pageInfoState]="fields"
|
||||||
[hideGear]="false"
|
[collectionSize]="fields?.totalElements"
|
||||||
[hidePagerWhenSinglePage]="true"
|
[hideGear]="false"
|
||||||
(pageChange)="onPageChange($event)">
|
[hidePagerWhenSinglePage]="true"
|
||||||
<div class="table-responsive">
|
(pageChange)="onPageChange($event)">
|
||||||
<table id="metadata-fields" class="table table-striped table-hover">
|
<div class="table-responsive">
|
||||||
<thead>
|
<table id="metadata-fields" class="table table-striped table-hover">
|
||||||
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th scope="col">{{'admin.registries.schema.fields.table.field' | translate}}</th>
|
<th scope="col">{{'admin.registries.schema.fields.table.field' | translate}}</th>
|
||||||
<th scope="col">{{'admin.registries.schema.fields.table.scopenote' | translate}}</th>
|
<th scope="col">{{'admin.registries.schema.fields.table.scopenote' | translate}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr *ngFor="let field of (metadataFields | async)?.payload?.page"
|
<tr *ngFor="let field of fields?.page"
|
||||||
[ngClass]="{'table-primary' : isActive(field) | async}">
|
[ngClass]="{'table-primary' : isActive(field) | async}">
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
@@ -39,22 +40,23 @@
|
|||||||
(change)="selectMetadataField(field, $event)">
|
(change)="selectMetadataField(field, $event)">
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td class="selectable-row" (click)="editField(field)">{{(metadataSchema | async)?.payload?.prefix}}.{{field.element}}<label *ngIf="field.qualifier">.</label>{{field.qualifier}}</td>
|
<td class="selectable-row" (click)="editField(field)">{{schema?.prefix}}.{{field.element}}<label *ngIf="field.qualifier">.</label>{{field.qualifier}}</td>
|
||||||
<td class="selectable-row" (click)="editField(field)">{{field.scopeNote}}</td>
|
<td class="selectable-row" (click)="editField(field)">{{field.scopeNote}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
</ds-pagination>
|
||||||
|
|
||||||
|
<div *ngIf="fields?.totalElements == 0" class="alert alert-info w-100 mb-2" role="alert">
|
||||||
|
{{'admin.registries.schema.fields.no-items' | translate}}
|
||||||
</div>
|
</div>
|
||||||
</ds-pagination>
|
|
||||||
|
|
||||||
<div *ngIf="(metadataFields | async)?.payload?.totalElements == 0" class="alert alert-info w-100 mb-2" role="alert">
|
<div>
|
||||||
{{'admin.registries.schema.fields.no-items' | translate}}
|
<button [routerLink]="['/admin/registries/metadata']" class="btn btn-primary">{{'admin.registries.schema.return' | translate}}</button>
|
||||||
</div>
|
<button *ngIf="fields?.page?.length > 0" type="submit" class="btn btn-danger float-right" (click)="deleteFields()">{{'admin.registries.schema.fields.table.delete' | translate}}</button>
|
||||||
|
</div>
|
||||||
<div>
|
</ng-container>
|
||||||
<button [routerLink]="['/admin/registries/metadata']" class="btn btn-primary">{{'admin.registries.schema.return' | translate}}</button>
|
|
||||||
<button *ngIf="(metadataFields | async)?.payload?.page?.length > 0" type="submit" class="btn btn-danger float-right" (click)="deleteFields()">{{'admin.registries.schema.fields.table.delete' | translate}}</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -22,6 +22,7 @@ import { RestResponse } from '../../../core/cache/response.models';
|
|||||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||||
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||||
|
import { VarDirective } from '../../../shared/utils/var.directive';
|
||||||
|
|
||||||
describe('MetadataSchemaComponent', () => {
|
describe('MetadataSchemaComponent', () => {
|
||||||
let comp: MetadataSchemaComponent;
|
let comp: MetadataSchemaComponent;
|
||||||
@@ -124,7 +125,7 @@ describe('MetadataSchemaComponent', () => {
|
|||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [CommonModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule],
|
imports: [CommonModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule],
|
||||||
declarations: [MetadataSchemaComponent, PaginationComponent, EnumKeysPipe],
|
declarations: [MetadataSchemaComponent, PaginationComponent, EnumKeysPipe, VarDirective],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: RegistryService, useValue: registryServiceStub },
|
{ provide: RegistryService, useValue: registryServiceStub },
|
||||||
{ provide: ActivatedRoute, useValue: activatedRouteStub },
|
{ provide: ActivatedRoute, useValue: activatedRouteStub },
|
||||||
|
@@ -5,7 +5,7 @@ import { Observable, combineLatest as observableCombineLatest } from 'rxjs';
|
|||||||
import { RemoteData } from '../../../core/data/remote-data';
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||||
import { map, take } from 'rxjs/operators';
|
import { map, switchMap, take } from 'rxjs/operators';
|
||||||
import { hasValue } from '../../../shared/empty.util';
|
import { hasValue } from '../../../shared/empty.util';
|
||||||
import { RestResponse } from '../../../core/cache/response.models';
|
import { RestResponse } from '../../../core/cache/response.models';
|
||||||
import { zip } from 'rxjs/internal/observable/zip';
|
import { zip } from 'rxjs/internal/observable/zip';
|
||||||
@@ -13,6 +13,10 @@ import { NotificationsService } from '../../../shared/notifications/notification
|
|||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
||||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||||
|
import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
||||||
|
import { toFindListOptions } from '../../../shared/pagination/pagination.utils';
|
||||||
|
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||||
|
import { combineLatest } from 'rxjs/internal/observable/combineLatest';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-metadata-schema',
|
selector: 'ds-metadata-schema',
|
||||||
@@ -24,21 +28,15 @@ import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
|||||||
* The admin can create, edit or delete metadata fields here.
|
* The admin can create, edit or delete metadata fields here.
|
||||||
*/
|
*/
|
||||||
export class MetadataSchemaComponent implements OnInit {
|
export class MetadataSchemaComponent implements OnInit {
|
||||||
|
|
||||||
/**
|
|
||||||
* The namespace of the metadata schema
|
|
||||||
*/
|
|
||||||
namespace;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The metadata schema
|
* The metadata schema
|
||||||
*/
|
*/
|
||||||
metadataSchema: Observable<RemoteData<MetadataSchema>>;
|
metadataSchema$: Observable<MetadataSchema>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of all the fields attached to this metadata schema
|
* A list of all the fields attached to this metadata schema
|
||||||
*/
|
*/
|
||||||
metadataFields: Observable<RemoteData<PaginatedList<MetadataField>>>;
|
metadataFields$: Observable<RemoteData<PaginatedList<MetadataField>>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pagination config used to display the list of metadata fields
|
* Pagination config used to display the list of metadata fields
|
||||||
@@ -49,6 +47,11 @@ export class MetadataSchemaComponent implements OnInit {
|
|||||||
pageSizeOptions: [25, 50, 100, 200]
|
pageSizeOptions: [25, 50, 100, 200]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not the list of MetadataFields needs an update
|
||||||
|
*/
|
||||||
|
needsUpdate$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
|
||||||
|
|
||||||
constructor(private registryService: RegistryService,
|
constructor(private registryService: RegistryService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private notificationsService: NotificationsService,
|
private notificationsService: NotificationsService,
|
||||||
@@ -68,7 +71,7 @@ export class MetadataSchemaComponent implements OnInit {
|
|||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
initialize(params) {
|
initialize(params) {
|
||||||
this.metadataSchema = this.registryService.getMetadataSchemaByName(params.schemaName);
|
this.metadataSchema$ = this.registryService.getMetadataSchemaByName(params.schemaName).pipe(getFirstSucceededRemoteDataPayload());
|
||||||
this.updateFields();
|
this.updateFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,18 +81,20 @@ export class MetadataSchemaComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
onPageChange(event) {
|
onPageChange(event) {
|
||||||
this.config.currentPage = event;
|
this.config.currentPage = event;
|
||||||
this.updateFields();
|
this.forceUpdateFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the list of fields by fetching it from the rest api or cache
|
* Update the list of fields by fetching it from the rest api or cache
|
||||||
*/
|
*/
|
||||||
private updateFields() {
|
private updateFields() {
|
||||||
this.metadataSchema.subscribe((schemaData) => {
|
this.metadataFields$ = combineLatest(this.metadataSchema$, this.needsUpdate$).pipe(
|
||||||
const schema = schemaData.payload;
|
switchMap(([schema, update]: [MetadataSchema, boolean]) => {
|
||||||
this.metadataFields = this.registryService.getMetadataFieldsBySchema(schema, this.config);
|
if (update) {
|
||||||
this.namespace = {namespace: schemaData.payload.namespace};
|
return this.registryService.getMetadataFieldsBySchema(schema, toFindListOptions(this.config));
|
||||||
});
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,8 +102,7 @@ export class MetadataSchemaComponent implements OnInit {
|
|||||||
* a new REST call
|
* a new REST call
|
||||||
*/
|
*/
|
||||||
public forceUpdateFields() {
|
public forceUpdateFields() {
|
||||||
this.registryService.clearMetadataFieldRequests().subscribe();
|
this.needsUpdate$.next(true);
|
||||||
this.updateFields();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,6 +161,7 @@ export class MetadataSchemaComponent implements OnInit {
|
|||||||
* Delete all the selected metadata fields
|
* Delete all the selected metadata fields
|
||||||
*/
|
*/
|
||||||
deleteFields() {
|
deleteFields() {
|
||||||
|
this.registryService.clearMetadataFieldRequests().subscribe();
|
||||||
this.registryService.getSelectedMetadataFields().pipe(take(1)).subscribe(
|
this.registryService.getSelectedMetadataFields().pipe(take(1)).subscribe(
|
||||||
(fields) => {
|
(fields) => {
|
||||||
const tasks$ = [];
|
const tasks$ = [];
|
||||||
|
@@ -14,7 +14,7 @@ describe('I18nBreadcrumbResolver', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should resolve the breadcrumb config', () => {
|
it('should resolve the breadcrumb config', () => {
|
||||||
const resolvedConfig = resolver.resolve({ data: { breadcrumbKey: i18nKey }, url: [path] } as any, {} as any);
|
const resolvedConfig = resolver.resolve({ data: { breadcrumbKey: i18nKey }, url: [path], pathFromRoot: [{ url: [path] }] } as any, {} as any);
|
||||||
const expectedConfig = { provider: i18nBreadcrumbService, key: i18nKey, url: path };
|
const expectedConfig = { provider: i18nBreadcrumbService, key: i18nKey, url: path };
|
||||||
expect(resolvedConfig).toEqual(expectedConfig);
|
expect(resolvedConfig).toEqual(expectedConfig);
|
||||||
});
|
});
|
||||||
|
@@ -25,7 +25,17 @@ export class I18nBreadcrumbResolver implements Resolve<BreadcrumbConfig<string>>
|
|||||||
if (hasNoValue(key)) {
|
if (hasNoValue(key)) {
|
||||||
throw new Error('You provided an i18nBreadcrumbResolver for url \"' + route.url + '\" but no breadcrumbKey in the route\'s data')
|
throw new Error('You provided an i18nBreadcrumbResolver for url \"' + route.url + '\" but no breadcrumbKey in the route\'s data')
|
||||||
}
|
}
|
||||||
const fullPath = route.url.join('');
|
const fullPath = this.getResolvedUrl(route);
|
||||||
return { provider: this.breadcrumbService, key: key, url: fullPath };
|
return { provider: this.breadcrumbService, key: key, url: fullPath };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the full URL of an ActivatedRouteSnapshot
|
||||||
|
* @param route
|
||||||
|
*/
|
||||||
|
getResolvedUrl(route: ActivatedRouteSnapshot): string {
|
||||||
|
return route.pathFromRoot
|
||||||
|
.map((v) => v.url.map((segment) => segment.toString()).join('/'))
|
||||||
|
.join('/');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
45
src/app/core/cache/response.models.ts
vendored
45
src/app/core/cache/response.models.ts
vendored
@@ -6,9 +6,6 @@ import { ConfigObject } from '../config/models/config.model';
|
|||||||
import { FacetValue } from '../../shared/search/facet-value.model';
|
import { FacetValue } from '../../shared/search/facet-value.model';
|
||||||
import { SearchFilterConfig } from '../../shared/search/search-filter-config.model';
|
import { SearchFilterConfig } from '../../shared/search/search-filter-config.model';
|
||||||
import { IntegrationModel } from '../integration/models/integration.model';
|
import { IntegrationModel } from '../integration/models/integration.model';
|
||||||
import { RegistryMetadataschemasResponse } from '../registry/registry-metadataschemas-response.model';
|
|
||||||
import { RegistryMetadatafieldsResponse } from '../registry/registry-metadatafields-response.model';
|
|
||||||
import { RegistryBitstreamformatsResponse } from '../registry/registry-bitstreamformats-response.model';
|
|
||||||
import { PaginatedList } from '../data/paginated-list';
|
import { PaginatedList } from '../data/paginated-list';
|
||||||
import { SubmissionObject } from '../submission/models/submission-object.model';
|
import { SubmissionObject } from '../submission/models/submission-object.model';
|
||||||
import { DSpaceObject } from '../shared/dspace-object.model';
|
import { DSpaceObject } from '../shared/dspace-object.model';
|
||||||
@@ -40,48 +37,6 @@ export class DSOSuccessResponse extends RestResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A successful response containing a list of MetadataSchemas wrapped in a RegistryMetadataschemasResponse
|
|
||||||
*/
|
|
||||||
export class RegistryMetadataschemasSuccessResponse extends RestResponse {
|
|
||||||
constructor(
|
|
||||||
public metadataschemasResponse: RegistryMetadataschemasResponse,
|
|
||||||
public statusCode: number,
|
|
||||||
public statusText: string,
|
|
||||||
public pageInfo?: PageInfo
|
|
||||||
) {
|
|
||||||
super(true, statusCode, statusText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A successful response containing a list of MetadataFields wrapped in a RegistryMetadatafieldsResponse
|
|
||||||
*/
|
|
||||||
export class RegistryMetadatafieldsSuccessResponse extends RestResponse {
|
|
||||||
constructor(
|
|
||||||
public metadatafieldsResponse: RegistryMetadatafieldsResponse,
|
|
||||||
public statusCode: number,
|
|
||||||
public statusText: string,
|
|
||||||
public pageInfo?: PageInfo
|
|
||||||
) {
|
|
||||||
super(true, statusCode, statusText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A successful response containing a list of BitstreamFormats wrapped in a RegistryBitstreamformatsResponse
|
|
||||||
*/
|
|
||||||
export class RegistryBitstreamformatsSuccessResponse extends RestResponse {
|
|
||||||
constructor(
|
|
||||||
public bitstreamformatsResponse: RegistryBitstreamformatsResponse,
|
|
||||||
public statusCode: number,
|
|
||||||
public statusText: string,
|
|
||||||
public pageInfo?: PageInfo
|
|
||||||
) {
|
|
||||||
super(true, statusCode, statusText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A successful response containing exactly one MetadataSchema
|
* A successful response containing exactly one MetadataSchema
|
||||||
*/
|
*/
|
||||||
|
@@ -69,13 +69,8 @@ import { ItemDataService } from './data/item-data.service';
|
|||||||
import { LicenseDataService } from './data/license-data.service';
|
import { LicenseDataService } from './data/license-data.service';
|
||||||
import { LookupRelationService } from './data/lookup-relation.service';
|
import { LookupRelationService } from './data/lookup-relation.service';
|
||||||
import { MappedCollectionsReponseParsingService } from './data/mapped-collections-reponse-parsing.service';
|
import { MappedCollectionsReponseParsingService } from './data/mapped-collections-reponse-parsing.service';
|
||||||
import { MetadatafieldParsingService } from './data/metadatafield-parsing.service';
|
|
||||||
import { MetadataschemaParsingService } from './data/metadataschema-parsing.service';
|
|
||||||
import { MyDSpaceResponseParsingService } from './data/mydspace-response-parsing.service';
|
import { MyDSpaceResponseParsingService } from './data/mydspace-response-parsing.service';
|
||||||
import { ObjectUpdatesService } from './data/object-updates/object-updates.service';
|
import { ObjectUpdatesService } from './data/object-updates/object-updates.service';
|
||||||
import { RegistryBitstreamformatsResponseParsingService } from './data/registry-bitstreamformats-response-parsing.service';
|
|
||||||
import { RegistryMetadatafieldsResponseParsingService } from './data/registry-metadatafields-response-parsing.service';
|
|
||||||
import { RegistryMetadataschemasResponseParsingService } from './data/registry-metadataschemas-response-parsing.service';
|
|
||||||
import { RelationshipTypeService } from './data/relationship-type.service';
|
import { RelationshipTypeService } from './data/relationship-type.service';
|
||||||
import { RelationshipService } from './data/relationship.service';
|
import { RelationshipService } from './data/relationship.service';
|
||||||
import { ResourcePolicyService } from './resource-policy/resource-policy.service';
|
import { ResourcePolicyService } from './resource-policy/resource-policy.service';
|
||||||
@@ -145,6 +140,8 @@ import { Version } from './shared/version.model';
|
|||||||
import { VersionHistory } from './shared/version-history.model';
|
import { VersionHistory } from './shared/version-history.model';
|
||||||
import { WorkflowActionDataService } from './data/workflow-action-data.service';
|
import { WorkflowActionDataService } from './data/workflow-action-data.service';
|
||||||
import { WorkflowAction } from './tasks/models/workflow-action-object.model';
|
import { WorkflowAction } from './tasks/models/workflow-action-object.model';
|
||||||
|
import { MetadataSchemaDataService } from './data/metadata-schema-data.service';
|
||||||
|
import { MetadataFieldDataService } from './data/metadata-field-data.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When not in production, endpoint responses can be mocked for testing purposes
|
* When not in production, endpoint responses can be mocked for testing purposes
|
||||||
@@ -201,9 +198,6 @@ const PROVIDERS = [
|
|||||||
FacetValueResponseParsingService,
|
FacetValueResponseParsingService,
|
||||||
FacetValueMapResponseParsingService,
|
FacetValueMapResponseParsingService,
|
||||||
FacetConfigResponseParsingService,
|
FacetConfigResponseParsingService,
|
||||||
RegistryMetadataschemasResponseParsingService,
|
|
||||||
RegistryMetadatafieldsResponseParsingService,
|
|
||||||
RegistryBitstreamformatsResponseParsingService,
|
|
||||||
MappedCollectionsReponseParsingService,
|
MappedCollectionsReponseParsingService,
|
||||||
DebugResponseParsingService,
|
DebugResponseParsingService,
|
||||||
SearchResponseParsingService,
|
SearchResponseParsingService,
|
||||||
@@ -223,8 +217,6 @@ const PROVIDERS = [
|
|||||||
JsonPatchOperationsBuilder,
|
JsonPatchOperationsBuilder,
|
||||||
AuthorityService,
|
AuthorityService,
|
||||||
IntegrationResponseParsingService,
|
IntegrationResponseParsingService,
|
||||||
MetadataschemaParsingService,
|
|
||||||
MetadatafieldParsingService,
|
|
||||||
UploaderService,
|
UploaderService,
|
||||||
UUIDService,
|
UUIDService,
|
||||||
NotificationsService,
|
NotificationsService,
|
||||||
@@ -264,6 +256,8 @@ const PROVIDERS = [
|
|||||||
LicenseDataService,
|
LicenseDataService,
|
||||||
ItemTypeDataService,
|
ItemTypeDataService,
|
||||||
WorkflowActionDataService,
|
WorkflowActionDataService,
|
||||||
|
MetadataSchemaDataService,
|
||||||
|
MetadataFieldDataService,
|
||||||
// register AuthInterceptor as HttpInterceptor
|
// register AuthInterceptor as HttpInterceptor
|
||||||
{
|
{
|
||||||
provide: HTTP_INTERCEPTORS,
|
provide: HTTP_INTERCEPTORS,
|
||||||
|
@@ -45,11 +45,12 @@ import {
|
|||||||
FindListOptions,
|
FindListOptions,
|
||||||
FindListRequest,
|
FindListRequest,
|
||||||
GetRequest,
|
GetRequest,
|
||||||
PatchRequest
|
PatchRequest, PutRequest
|
||||||
} from './request.models';
|
} from './request.models';
|
||||||
import { RequestEntry } from './request.reducer';
|
import { RequestEntry } from './request.reducer';
|
||||||
import { RequestService } from './request.service';
|
import { RequestService } from './request.service';
|
||||||
import { RestRequestMethod } from './rest-request-method';
|
import { RestRequestMethod } from './rest-request-method';
|
||||||
|
import { GenericConstructor } from '../shared/generic-constructor';
|
||||||
|
|
||||||
export abstract class DataService<T extends CacheableObject> {
|
export abstract class DataService<T extends CacheableObject> {
|
||||||
protected abstract requestService: RequestService;
|
protected abstract requestService: RequestService;
|
||||||
@@ -343,7 +344,9 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
tap((href: string) => {
|
tap((href: string) => {
|
||||||
this.requestService.removeByHrefSubstring(href);
|
this.requestService.removeByHrefSubstring(href);
|
||||||
const request = new FindListRequest(this.requestService.generateRequestId(), href, options);
|
const request = new FindListRequest(this.requestService.generateRequestId(), href, options);
|
||||||
request.responseMsToLive = 10 * 1000;
|
if (hasValue(this.responseMsToLive)) {
|
||||||
|
request.responseMsToLive = this.responseMsToLive;
|
||||||
|
}
|
||||||
|
|
||||||
this.requestService.configure(request);
|
this.requestService.configure(request);
|
||||||
}
|
}
|
||||||
@@ -381,6 +384,28 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a PUT request for the specified object
|
||||||
|
*
|
||||||
|
* @param object The object to send a put request for.
|
||||||
|
*/
|
||||||
|
put(object: T): Observable<RemoteData<T>> {
|
||||||
|
const requestId = this.requestService.generateRequestId();
|
||||||
|
const serializedObject = new DSpaceSerializer(object.constructor as GenericConstructor<{}>).serialize(object);
|
||||||
|
const request = new PutRequest(requestId, object._links.self.href, serializedObject);
|
||||||
|
|
||||||
|
if (hasValue(this.responseMsToLive)) {
|
||||||
|
request.responseMsToLive = this.responseMsToLive;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.requestService.configure(request);
|
||||||
|
|
||||||
|
return this.requestService.getByUUID(requestId).pipe(
|
||||||
|
find((re: RequestEntry) => hasValue(re) && re.completed),
|
||||||
|
switchMap(() => this.findByHref(object._links.self.href))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new patch to the object cache
|
* Add a new patch to the object cache
|
||||||
* The patch is derived from the differences between the given object and its version in the object cache
|
* The patch is derived from the differences between the given object and its version in the object cache
|
||||||
|
114
src/app/core/data/metadata-field-data.service.spec.ts
Normal file
114
src/app/core/data/metadata-field-data.service.spec.ts
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
import { RequestService } from './request.service';
|
||||||
|
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { of as observableOf } from 'rxjs/internal/observable/of';
|
||||||
|
import { RestResponse } from '../cache/response.models';
|
||||||
|
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub';
|
||||||
|
import { CreateRequest, FindListOptions, PutRequest } from './request.models';
|
||||||
|
import { MetadataFieldDataService } from './metadata-field-data.service';
|
||||||
|
import { MetadataField } from '../metadata/metadata-field.model';
|
||||||
|
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||||
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
|
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||||
|
import { RequestParam } from '../cache/models/request-param.model';
|
||||||
|
|
||||||
|
describe('MetadataFieldDataService', () => {
|
||||||
|
let metadataFieldService: MetadataFieldDataService;
|
||||||
|
let requestService: RequestService;
|
||||||
|
let halService: HALEndpointService;
|
||||||
|
let notificationsService: NotificationsService;
|
||||||
|
let schema: MetadataSchema;
|
||||||
|
let rdbService: RemoteDataBuildService;
|
||||||
|
|
||||||
|
const endpoint = 'api/metadatafield/endpoint';
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
schema = Object.assign(new MetadataSchema(), {
|
||||||
|
prefix: 'dc',
|
||||||
|
namespace: 'namespace',
|
||||||
|
_links: {
|
||||||
|
self: { href: 'selflink' }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
requestService = jasmine.createSpyObj('requestService', {
|
||||||
|
generateRequestId: '34cfed7c-f597-49ef-9cbe-ea351f0023c2',
|
||||||
|
configure: {},
|
||||||
|
getByUUID: observableOf({ response: new RestResponse(true, 200, 'OK') }),
|
||||||
|
removeByHrefSubstring: {}
|
||||||
|
});
|
||||||
|
halService = Object.assign(new HALEndpointServiceStub(endpoint));
|
||||||
|
notificationsService = jasmine.createSpyObj('notificationsService', {
|
||||||
|
error: {}
|
||||||
|
});
|
||||||
|
rdbService = jasmine.createSpyObj('rdbService', {
|
||||||
|
buildSingle: createSuccessfulRemoteDataObject$(undefined)
|
||||||
|
});
|
||||||
|
metadataFieldService = new MetadataFieldDataService(requestService, rdbService, undefined, halService, undefined, undefined, undefined, notificationsService);
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
init();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('findBySchema', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(metadataFieldService, 'searchBy');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call searchBy with the correct arguments', () => {
|
||||||
|
metadataFieldService.findBySchema(schema);
|
||||||
|
const expectedOptions = Object.assign(new FindListOptions(), {
|
||||||
|
searchParams: [new RequestParam('schema', schema.prefix)]
|
||||||
|
});
|
||||||
|
expect(metadataFieldService.searchBy).toHaveBeenCalledWith('bySchema', expectedOptions);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('createOrUpdateMetadataField', () => {
|
||||||
|
let field: MetadataField;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
field = Object.assign(new MetadataField(), {
|
||||||
|
element: 'identifier',
|
||||||
|
qualifier: undefined,
|
||||||
|
schema: schema,
|
||||||
|
_links: {
|
||||||
|
self: { href: 'selflink' }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('called with a new metadata field', () => {
|
||||||
|
it('should send a CreateRequest', (done) => {
|
||||||
|
metadataFieldService.createOrUpdateMetadataField(field).subscribe(() => {
|
||||||
|
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(CreateRequest));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('called with an existing metadata field', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
field = Object.assign(field, {
|
||||||
|
id: 'id-of-existing-field'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should send a PutRequest', (done) => {
|
||||||
|
metadataFieldService.createOrUpdateMetadataField(field).subscribe(() => {
|
||||||
|
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(PutRequest));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('clearRequests', () => {
|
||||||
|
it('should remove requests on the data service\'s endpoint', (done) => {
|
||||||
|
metadataFieldService.clearRequests().subscribe(() => {
|
||||||
|
expect(requestService.removeByHrefSubstring).toHaveBeenCalledWith(`${endpoint}/${(metadataFieldService as any).linkPath}`);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
89
src/app/core/data/metadata-field-data.service.ts
Normal file
89
src/app/core/data/metadata-field-data.service.ts
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { dataService } from '../cache/builders/build-decorators';
|
||||||
|
import { DataService } from './data.service';
|
||||||
|
import { RequestService } from './request.service';
|
||||||
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
import { CoreState } from '../core.reducers';
|
||||||
|
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||||
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
|
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { METADATA_FIELD } from '../metadata/metadata-field.resource-type';
|
||||||
|
import { MetadataField } from '../metadata/metadata-field.model';
|
||||||
|
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||||
|
import { FindListOptions, FindListRequest } from './request.models';
|
||||||
|
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||||
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
|
import { hasValue } from '../../shared/empty.util';
|
||||||
|
import { find, skipWhile, switchMap, tap } from 'rxjs/operators';
|
||||||
|
import { RemoteData } from './remote-data';
|
||||||
|
import { RequestParam } from '../cache/models/request-param.model';
|
||||||
|
import { PaginatedList } from './paginated-list';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
@dataService(METADATA_FIELD)
|
||||||
|
export class MetadataFieldDataService extends DataService<MetadataField> {
|
||||||
|
protected linkPath = 'metadatafields';
|
||||||
|
protected searchBySchemaLinkPath = 'bySchema';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected requestService: RequestService,
|
||||||
|
protected rdbService: RemoteDataBuildService,
|
||||||
|
protected store: Store<CoreState>,
|
||||||
|
protected halService: HALEndpointService,
|
||||||
|
protected objectCache: ObjectCacheService,
|
||||||
|
protected comparator: DefaultChangeAnalyzer<MetadataField>,
|
||||||
|
protected http: HttpClient,
|
||||||
|
protected notificationsService: NotificationsService) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find metadata fields belonging to a metadata schema
|
||||||
|
* @param schema The metadata schema to list fields for
|
||||||
|
* @param options The options info used to retrieve the fields
|
||||||
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
|
*/
|
||||||
|
findBySchema(schema: MetadataSchema, options: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<MetadataField>>) {
|
||||||
|
const optionsWithSchema = Object.assign(new FindListOptions(), options, {
|
||||||
|
searchParams: [new RequestParam('schema', schema.prefix)]
|
||||||
|
});
|
||||||
|
return this.searchBy(this.searchBySchemaLinkPath, optionsWithSchema, ...linksToFollow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create or Update a MetadataField
|
||||||
|
* If the MetadataField contains an id, it is assumed the field already exists and is updated instead
|
||||||
|
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
||||||
|
* - On creation, a CreateRequest is used
|
||||||
|
* - On update, a PutRequest is used
|
||||||
|
* @param field The MetadataField to create or update
|
||||||
|
*/
|
||||||
|
createOrUpdateMetadataField(field: MetadataField): Observable<RemoteData<MetadataField>> {
|
||||||
|
const isUpdate = hasValue(field.id);
|
||||||
|
|
||||||
|
if (isUpdate) {
|
||||||
|
return this.put(field);
|
||||||
|
} else {
|
||||||
|
return this.create(field, new RequestParam('schemaId', field.schema.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all metadata field requests
|
||||||
|
* Used for refreshing lists after adding/updating/removing a metadata field from a metadata schema
|
||||||
|
*/
|
||||||
|
clearRequests(): Observable<string> {
|
||||||
|
return this.getBrowseEndpoint().pipe(
|
||||||
|
tap((href: string) => {
|
||||||
|
this.requestService.removeByHrefSubstring(href);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
89
src/app/core/data/metadata-schema-data.service.spec.ts
Normal file
89
src/app/core/data/metadata-schema-data.service.spec.ts
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import { RequestService } from './request.service';
|
||||||
|
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||||
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
|
import { MetadataSchemaDataService } from './metadata-schema-data.service';
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
import { RestResponse } from '../cache/response.models';
|
||||||
|
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub';
|
||||||
|
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||||
|
import { CreateRequest, PutRequest } from './request.models';
|
||||||
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
|
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||||
|
|
||||||
|
describe('MetadataSchemaDataService', () => {
|
||||||
|
let metadataSchemaService: MetadataSchemaDataService;
|
||||||
|
let requestService: RequestService;
|
||||||
|
let halService: HALEndpointService;
|
||||||
|
let notificationsService: NotificationsService;
|
||||||
|
let rdbService: RemoteDataBuildService;
|
||||||
|
|
||||||
|
const endpoint = 'api/metadataschema/endpoint';
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
requestService = jasmine.createSpyObj('requestService', {
|
||||||
|
generateRequestId: '34cfed7c-f597-49ef-9cbe-ea351f0023c2',
|
||||||
|
configure: {},
|
||||||
|
getByUUID: observableOf({ response: new RestResponse(true, 200, 'OK') }),
|
||||||
|
removeByHrefSubstring: {}
|
||||||
|
});
|
||||||
|
halService = Object.assign(new HALEndpointServiceStub(endpoint));
|
||||||
|
notificationsService = jasmine.createSpyObj('notificationsService', {
|
||||||
|
error: {}
|
||||||
|
});
|
||||||
|
rdbService = jasmine.createSpyObj('rdbService', {
|
||||||
|
buildSingle: createSuccessfulRemoteDataObject$(undefined)
|
||||||
|
});
|
||||||
|
metadataSchemaService = new MetadataSchemaDataService(requestService, rdbService, undefined, halService, undefined, undefined, undefined, notificationsService);
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
init();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('createOrUpdateMetadataSchema', () => {
|
||||||
|
let schema: MetadataSchema;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
schema = Object.assign(new MetadataSchema(), {
|
||||||
|
prefix: 'dc',
|
||||||
|
namespace: 'namespace',
|
||||||
|
_links: {
|
||||||
|
self: { href: 'selflink' }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('called with a new metadata schema', () => {
|
||||||
|
it('should send a CreateRequest', (done) => {
|
||||||
|
metadataSchemaService.createOrUpdateMetadataSchema(schema).subscribe(() => {
|
||||||
|
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(CreateRequest));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('called with an existing metadata schema', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
schema = Object.assign(schema, {
|
||||||
|
id: 'id-of-existing-schema'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should send a PutRequest', (done) => {
|
||||||
|
metadataSchemaService.createOrUpdateMetadataSchema(schema).subscribe(() => {
|
||||||
|
expect(requestService.configure).toHaveBeenCalledWith(jasmine.any(PutRequest));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('clearRequests', () => {
|
||||||
|
it('should remove requests on the data service\'s endpoint', (done) => {
|
||||||
|
metadataSchemaService.clearRequests().subscribe(() => {
|
||||||
|
expect(requestService.removeByHrefSubstring).toHaveBeenCalledWith(`${endpoint}/${(metadataSchemaService as any).linkPath}`);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@@ -9,37 +9,21 @@ import { CoreState } from '../core.reducers';
|
|||||||
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||||
import { METADATA_SCHEMA } from '../metadata/metadata-schema.resource-type';
|
import { METADATA_SCHEMA } from '../metadata/metadata-schema.resource-type';
|
||||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||||
import { ChangeAnalyzer } from './change-analyzer';
|
|
||||||
|
|
||||||
import { DataService } from './data.service';
|
import { DataService } from './data.service';
|
||||||
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
|
import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
|
||||||
import { RequestService } from './request.service';
|
import { RequestService } from './request.service';
|
||||||
|
import { Observable } from 'rxjs/internal/Observable';
|
||||||
/* tslint:disable:max-classes-per-file */
|
import { hasValue } from '../../shared/empty.util';
|
||||||
class DataServiceImpl extends DataService<MetadataSchema> {
|
import { tap } from 'rxjs/operators';
|
||||||
protected linkPath = 'metadataschemas';
|
import { RemoteData } from './remote-data';
|
||||||
|
|
||||||
constructor(
|
|
||||||
protected requestService: RequestService,
|
|
||||||
protected rdbService: RemoteDataBuildService,
|
|
||||||
protected store: Store<CoreState>,
|
|
||||||
protected objectCache: ObjectCacheService,
|
|
||||||
protected halService: HALEndpointService,
|
|
||||||
protected notificationsService: NotificationsService,
|
|
||||||
protected http: HttpClient,
|
|
||||||
protected comparator: ChangeAnalyzer<MetadataSchema>) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A service responsible for fetching/sending data from/to the REST API on the metadataschemas endpoint
|
* A service responsible for fetching/sending data from/to the REST API on the metadataschemas endpoint
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@dataService(METADATA_SCHEMA)
|
@dataService(METADATA_SCHEMA)
|
||||||
export class MetadataSchemaDataService {
|
export class MetadataSchemaDataService extends DataService<MetadataSchema> {
|
||||||
private dataService: DataServiceImpl;
|
protected linkPath = 'metadataschemas';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
@@ -50,6 +34,35 @@ export class MetadataSchemaDataService {
|
|||||||
protected comparator: DefaultChangeAnalyzer<MetadataSchema>,
|
protected comparator: DefaultChangeAnalyzer<MetadataSchema>,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected notificationsService: NotificationsService) {
|
protected notificationsService: NotificationsService) {
|
||||||
this.dataService = new DataServiceImpl(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator);
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create or Update a MetadataSchema
|
||||||
|
* If the MetadataSchema contains an id, it is assumed the schema already exists and is updated instead
|
||||||
|
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
||||||
|
* - On creation, a CreateRequest is used
|
||||||
|
* - On update, a PutRequest is used
|
||||||
|
* @param schema The MetadataSchema to create or update
|
||||||
|
*/
|
||||||
|
createOrUpdateMetadataSchema(schema: MetadataSchema): Observable<RemoteData<MetadataSchema>> {
|
||||||
|
const isUpdate = hasValue(schema.id);
|
||||||
|
|
||||||
|
if (isUpdate) {
|
||||||
|
return this.put(schema);
|
||||||
|
} else {
|
||||||
|
return this.create(schema);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all metadata schema requests
|
||||||
|
* Used for refreshing lists after adding/updating/removing a metadata schema in the registry
|
||||||
|
*/
|
||||||
|
clearRequests(): Observable<string> {
|
||||||
|
return this.getBrowseEndpoint().pipe(
|
||||||
|
tap((href: string) => this.requestService.removeByHrefSubstring(href))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { MetadatafieldSuccessResponse, RestResponse } from '../cache/response.models';
|
|
||||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
|
||||||
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
|
|
||||||
import { MetadataField } from '../metadata/metadata-field.model';
|
|
||||||
import { ResponseParsingService } from './parsing.service';
|
|
||||||
import { RestRequest } from './request.models';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A service responsible for parsing DSpaceRESTV2Response data related to a single MetadataField to a valid RestResponse
|
|
||||||
*/
|
|
||||||
@Injectable()
|
|
||||||
export class MetadatafieldParsingService implements ResponseParsingService {
|
|
||||||
|
|
||||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
|
||||||
const payload = data.payload;
|
|
||||||
|
|
||||||
const deserialized = new DSpaceSerializer(MetadataField).deserialize(payload);
|
|
||||||
return new MetadatafieldSuccessResponse(deserialized, data.statusCode, data.statusText);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,19 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { MetadataschemaSuccessResponse, RestResponse } from '../cache/response.models';
|
|
||||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
|
||||||
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
|
|
||||||
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
|
||||||
import { ResponseParsingService } from './parsing.service';
|
|
||||||
import { RestRequest } from './request.models';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class MetadataschemaParsingService implements ResponseParsingService {
|
|
||||||
|
|
||||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
|
||||||
const payload = data.payload;
|
|
||||||
|
|
||||||
const deserialized = new DSpaceSerializer(MetadataSchema).deserialize(payload);
|
|
||||||
return new MetadataschemaSuccessResponse(deserialized, data.statusCode, data.statusText);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,41 +0,0 @@
|
|||||||
import { PageInfo } from '../shared/page-info.model';
|
|
||||||
import { DSOResponseParsingService } from './dso-response-parsing.service';
|
|
||||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
|
||||||
import {
|
|
||||||
RegistryBitstreamformatsSuccessResponse
|
|
||||||
} from '../cache/response.models';
|
|
||||||
import { RegistryBitstreamformatsResponseParsingService } from './registry-bitstreamformats-response-parsing.service';
|
|
||||||
|
|
||||||
describe('RegistryBitstreamformatsResponseParsingService', () => {
|
|
||||||
let service: RegistryBitstreamformatsResponseParsingService;
|
|
||||||
|
|
||||||
const mockDSOParser = Object.assign({
|
|
||||||
processPageInfo: () => new PageInfo()
|
|
||||||
}) as DSOResponseParsingService;
|
|
||||||
|
|
||||||
const data = Object.assign({
|
|
||||||
payload: {
|
|
||||||
_embedded: {
|
|
||||||
bitstreamformats: [
|
|
||||||
{
|
|
||||||
uuid: 'uuid-1',
|
|
||||||
description: 'a description'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
uuid: 'uuid-2',
|
|
||||||
description: 'another description'
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) as DSpaceRESTV2Response;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
service = new RegistryBitstreamformatsResponseParsingService(mockDSOParser);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse the data correctly', () => {
|
|
||||||
const response = service.parse(null, data);
|
|
||||||
expect(response.constructor).toBe(RegistryBitstreamformatsSuccessResponse);
|
|
||||||
});
|
|
||||||
});
|
|
@@ -1,25 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { RegistryBitstreamformatsSuccessResponse, RestResponse } from '../cache/response.models';
|
|
||||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
|
||||||
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
|
|
||||||
import { RegistryBitstreamformatsResponse } from '../registry/registry-bitstreamformats-response.model';
|
|
||||||
import { DSOResponseParsingService } from './dso-response-parsing.service';
|
|
||||||
import { ResponseParsingService } from './parsing.service';
|
|
||||||
import { RestRequest } from './request.models';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class RegistryBitstreamformatsResponseParsingService implements ResponseParsingService {
|
|
||||||
constructor(private dsoParser: DSOResponseParsingService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
|
||||||
const payload = data.payload;
|
|
||||||
|
|
||||||
const bitstreamformats = payload._embedded.bitstreamformats;
|
|
||||||
payload.bitstreamformats = bitstreamformats;
|
|
||||||
|
|
||||||
const deserialized = new DSpaceSerializer(RegistryBitstreamformatsResponse).deserialize(payload);
|
|
||||||
return new RegistryBitstreamformatsSuccessResponse(deserialized, data.statusCode, data.statusText, this.dsoParser.processPageInfo(data.payload.page));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,68 +0,0 @@
|
|||||||
import { PageInfo } from '../shared/page-info.model';
|
|
||||||
import { DSOResponseParsingService } from './dso-response-parsing.service';
|
|
||||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
|
||||||
import {
|
|
||||||
RegistryMetadatafieldsSuccessResponse
|
|
||||||
} from '../cache/response.models';
|
|
||||||
import { RegistryMetadatafieldsResponseParsingService } from './registry-metadatafields-response-parsing.service';
|
|
||||||
|
|
||||||
describe('RegistryMetadatafieldsResponseParsingService', () => {
|
|
||||||
let service: RegistryMetadatafieldsResponseParsingService;
|
|
||||||
|
|
||||||
const mockDSOParser = Object.assign({
|
|
||||||
processPageInfo: () => new PageInfo()
|
|
||||||
}) as DSOResponseParsingService;
|
|
||||||
|
|
||||||
const data = Object.assign({
|
|
||||||
payload: {
|
|
||||||
_embedded: {
|
|
||||||
metadatafields: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
element: 'element',
|
|
||||||
qualifier: 'qualifier',
|
|
||||||
scopeNote: 'a scope note',
|
|
||||||
_embedded: {
|
|
||||||
schema: {
|
|
||||||
id: 1,
|
|
||||||
prefix: 'test',
|
|
||||||
namespace: 'test namespace'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
element: 'secondelement',
|
|
||||||
qualifier: 'secondqualifier',
|
|
||||||
scopeNote: 'a second scope note',
|
|
||||||
_embedded: {
|
|
||||||
schema: {
|
|
||||||
id: 1,
|
|
||||||
prefix: 'test',
|
|
||||||
namespace: 'test namespace'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) as DSpaceRESTV2Response;
|
|
||||||
|
|
||||||
const emptyData = Object.assign({
|
|
||||||
payload: {}
|
|
||||||
}) as DSpaceRESTV2Response;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
service = new RegistryMetadatafieldsResponseParsingService(mockDSOParser);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse the data correctly', () => {
|
|
||||||
const response = service.parse(null, data);
|
|
||||||
expect(response.constructor).toBe(RegistryMetadatafieldsSuccessResponse);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not produce an error and parse the data correctly when the data is empty', () => {
|
|
||||||
const response = service.parse(null, emptyData);
|
|
||||||
expect(response.constructor).toBe(RegistryMetadatafieldsSuccessResponse);
|
|
||||||
});
|
|
||||||
});
|
|
@@ -1,34 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { hasValue } from '../../shared/empty.util';
|
|
||||||
import { RegistryMetadatafieldsSuccessResponse, RestResponse } from '../cache/response.models';
|
|
||||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
|
||||||
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
|
|
||||||
import { RegistryMetadatafieldsResponse } from '../registry/registry-metadatafields-response.model';
|
|
||||||
import { DSOResponseParsingService } from './dso-response-parsing.service';
|
|
||||||
import { ResponseParsingService } from './parsing.service';
|
|
||||||
import { RestRequest } from './request.models';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class RegistryMetadatafieldsResponseParsingService implements ResponseParsingService {
|
|
||||||
constructor(private dsoParser: DSOResponseParsingService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
|
||||||
const payload = data.payload;
|
|
||||||
|
|
||||||
let metadatafields = [];
|
|
||||||
|
|
||||||
if (hasValue(payload._embedded)) {
|
|
||||||
metadatafields = payload._embedded.metadatafields;
|
|
||||||
metadatafields.forEach((field) => {
|
|
||||||
field.schema = field._embedded.schema;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
payload.metadatafields = metadatafields;
|
|
||||||
|
|
||||||
const deserialized = new DSpaceSerializer(RegistryMetadatafieldsResponse).deserialize(payload);
|
|
||||||
return new RegistryMetadatafieldsSuccessResponse(deserialized, data.statusCode, data.statusText, this.dsoParser.processPageInfo(data.payload));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
import { RegistryMetadataschemasResponseParsingService } from './registry-metadataschemas-response-parsing.service';
|
|
||||||
import { PageInfo } from '../shared/page-info.model';
|
|
||||||
import { DSOResponseParsingService } from './dso-response-parsing.service';
|
|
||||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
|
||||||
import { RegistryMetadataschemasSuccessResponse } from '../cache/response.models';
|
|
||||||
|
|
||||||
describe('RegistryMetadataschemasResponseParsingService', () => {
|
|
||||||
let service: RegistryMetadataschemasResponseParsingService;
|
|
||||||
|
|
||||||
const mockDSOParser = Object.assign({
|
|
||||||
processPageInfo: () => new PageInfo()
|
|
||||||
}) as DSOResponseParsingService;
|
|
||||||
|
|
||||||
const data = Object.assign({
|
|
||||||
payload: {
|
|
||||||
_embedded: {
|
|
||||||
metadataschemas: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
prefix: 'test',
|
|
||||||
namespace: 'test namespace'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
prefix: 'second',
|
|
||||||
namespace: 'second test namespace'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) as DSpaceRESTV2Response;
|
|
||||||
|
|
||||||
const emptyData = Object.assign({
|
|
||||||
payload: {}
|
|
||||||
}) as DSpaceRESTV2Response;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
service = new RegistryMetadataschemasResponseParsingService(mockDSOParser);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse the data correctly', () => {
|
|
||||||
const response = service.parse(null, data);
|
|
||||||
expect(response.constructor).toBe(RegistryMetadataschemasSuccessResponse);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not produce an error and parse the data correctly when the data is empty', () => {
|
|
||||||
const response = service.parse(null, emptyData);
|
|
||||||
expect(response.constructor).toBe(RegistryMetadataschemasSuccessResponse);
|
|
||||||
});
|
|
||||||
});
|
|
@@ -1,29 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { hasValue } from '../../shared/empty.util';
|
|
||||||
import { RegistryMetadataschemasSuccessResponse, RestResponse } from '../cache/response.models';
|
|
||||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
|
||||||
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
|
|
||||||
import { RegistryMetadataschemasResponse } from '../registry/registry-metadataschemas-response.model';
|
|
||||||
import { DSOResponseParsingService } from './dso-response-parsing.service';
|
|
||||||
import { ResponseParsingService } from './parsing.service';
|
|
||||||
import { RestRequest } from './request.models';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class RegistryMetadataschemasResponseParsingService implements ResponseParsingService {
|
|
||||||
constructor(private dsoParser: DSOResponseParsingService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
|
||||||
const payload = data.payload;
|
|
||||||
|
|
||||||
let metadataschemas = [];
|
|
||||||
if (hasValue(payload._embedded)) {
|
|
||||||
metadataschemas = payload._embedded.metadataschemas;
|
|
||||||
}
|
|
||||||
payload.metadataschemas = metadataschemas;
|
|
||||||
|
|
||||||
const deserialized = new DSpaceSerializer(RegistryMetadataschemasResponse).deserialize(payload);
|
|
||||||
return new RegistryMetadataschemasSuccessResponse(deserialized, data.statusCode, data.statusText, this.dsoParser.processPageInfo(data.payload));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -14,8 +14,6 @@ import { RestRequestMethod } from './rest-request-method';
|
|||||||
import { RequestParam } from '../cache/models/request-param.model';
|
import { RequestParam } from '../cache/models/request-param.model';
|
||||||
import { EpersonResponseParsingService } from '../eperson/eperson-response-parsing.service';
|
import { EpersonResponseParsingService } from '../eperson/eperson-response-parsing.service';
|
||||||
import { BrowseItemsResponseParsingService } from './browse-items-response-parsing-service';
|
import { BrowseItemsResponseParsingService } from './browse-items-response-parsing-service';
|
||||||
import { MetadataschemaParsingService } from './metadataschema-parsing.service';
|
|
||||||
import { MetadatafieldParsingService } from './metadatafield-parsing.service';
|
|
||||||
import { URLCombiner } from '../url-combiner/url-combiner';
|
import { URLCombiner } from '../url-combiner/url-combiner';
|
||||||
import { TaskResponseParsingService } from '../tasks/task-response-parsing.service';
|
import { TaskResponseParsingService } from '../tasks/task-response-parsing.service';
|
||||||
import { ContentSourceResponseParsingService } from './content-source-response-parsing.service';
|
import { ContentSourceResponseParsingService } from './content-source-response-parsing.service';
|
||||||
@@ -251,58 +249,6 @@ export class IntegrationRequest extends GetRequest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to create a MetadataSchema
|
|
||||||
*/
|
|
||||||
export class CreateMetadataSchemaRequest extends PostRequest {
|
|
||||||
constructor(uuid: string, href: string, public body?: any, public options?: HttpOptions) {
|
|
||||||
super(uuid, href, body, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
|
||||||
return MetadataschemaParsingService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to update a MetadataSchema
|
|
||||||
*/
|
|
||||||
export class UpdateMetadataSchemaRequest extends PutRequest {
|
|
||||||
constructor(uuid: string, href: string, public body?: any, public options?: HttpOptions) {
|
|
||||||
super(uuid, href, body, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
|
||||||
return MetadataschemaParsingService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to create a MetadataField
|
|
||||||
*/
|
|
||||||
export class CreateMetadataFieldRequest extends PostRequest {
|
|
||||||
constructor(uuid: string, href: string, public body?: any, public options?: HttpOptions) {
|
|
||||||
super(uuid, href, body, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
|
||||||
return MetadatafieldParsingService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request to update a MetadataField
|
|
||||||
*/
|
|
||||||
export class UpdateMetadataFieldRequest extends PutRequest {
|
|
||||||
constructor(uuid: string, href: string, public body?: any, public options?: HttpOptions) {
|
|
||||||
super(uuid, href, body, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
|
||||||
return MetadatafieldParsingService;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing a submission HTTP GET request object
|
* Class representing a submission HTTP GET request object
|
||||||
*/
|
*/
|
||||||
|
@@ -1,24 +0,0 @@
|
|||||||
import { autoserialize, deserialize } from 'cerialize';
|
|
||||||
import { BITSTREAM_FORMAT } from '../shared/bitstream-format.resource-type';
|
|
||||||
import { HALLink } from '../shared/hal-link.model';
|
|
||||||
import { PageInfo } from '../shared/page-info.model';
|
|
||||||
import { BitstreamFormat } from '../shared/bitstream-format.model';
|
|
||||||
import { link } from '../cache/builders/build-decorators';
|
|
||||||
|
|
||||||
export class RegistryBitstreamformatsResponse {
|
|
||||||
@autoserialize
|
|
||||||
page: PageInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link HALLink}s for this RegistryBitstreamformatsResponse
|
|
||||||
*/
|
|
||||||
@deserialize
|
|
||||||
_links: {
|
|
||||||
self: HALLink;
|
|
||||||
bitstreamformats: HALLink;
|
|
||||||
};
|
|
||||||
|
|
||||||
@link(BITSTREAM_FORMAT)
|
|
||||||
bitstreamformats?: BitstreamFormat[];
|
|
||||||
|
|
||||||
}
|
|
@@ -1,46 +0,0 @@
|
|||||||
import { autoserialize, deserialize } from 'cerialize';
|
|
||||||
import { typedObject } from '../cache/builders/build-decorators';
|
|
||||||
import { MetadataField } from '../metadata/metadata-field.model';
|
|
||||||
import { METADATA_FIELD } from '../metadata/metadata-field.resource-type';
|
|
||||||
import { HALLink } from '../shared/hal-link.model';
|
|
||||||
import { PageInfo } from '../shared/page-info.model';
|
|
||||||
import { ResourceType } from '../shared/resource-type';
|
|
||||||
import { excludeFromEquals } from '../utilities/equals.decorators';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class that represents a response with a registry's metadata fields
|
|
||||||
*/
|
|
||||||
@typedObject
|
|
||||||
export class RegistryMetadatafieldsResponse {
|
|
||||||
static type = METADATA_FIELD;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The object type
|
|
||||||
*/
|
|
||||||
@excludeFromEquals
|
|
||||||
@autoserialize
|
|
||||||
type: ResourceType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of metadata fields in the response
|
|
||||||
*/
|
|
||||||
@deserialize
|
|
||||||
metadatafields: MetadataField[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Page info of this response
|
|
||||||
*/
|
|
||||||
@autoserialize
|
|
||||||
page: PageInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The REST link to this response
|
|
||||||
*/
|
|
||||||
@autoserialize
|
|
||||||
self: string;
|
|
||||||
|
|
||||||
@deserialize
|
|
||||||
_links: {
|
|
||||||
self: HALLink,
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,14 +0,0 @@
|
|||||||
import { PageInfo } from '../shared/page-info.model';
|
|
||||||
import { autoserialize, deserialize } from 'cerialize';
|
|
||||||
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
|
||||||
|
|
||||||
export class RegistryMetadataschemasResponse {
|
|
||||||
@deserialize
|
|
||||||
metadataschemas: MetadataSchema[];
|
|
||||||
|
|
||||||
@autoserialize
|
|
||||||
page: PageInfo;
|
|
||||||
|
|
||||||
@autoserialize
|
|
||||||
self: string;
|
|
||||||
}
|
|
@@ -3,8 +3,7 @@ import { Component } from '@angular/core';
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { Store, StoreModule } from '@ngrx/store';
|
import { Store, StoreModule } from '@ngrx/store';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
|
import { Observable, of as observableOf } from 'rxjs';
|
||||||
import { map } from 'rxjs/operators';
|
|
||||||
import {
|
import {
|
||||||
MetadataRegistryCancelFieldAction,
|
MetadataRegistryCancelFieldAction,
|
||||||
MetadataRegistryCancelSchemaAction,
|
MetadataRegistryCancelSchemaAction,
|
||||||
@@ -17,30 +16,20 @@ import {
|
|||||||
MetadataRegistrySelectFieldAction,
|
MetadataRegistrySelectFieldAction,
|
||||||
MetadataRegistrySelectSchemaAction
|
MetadataRegistrySelectSchemaAction
|
||||||
} from '../../+admin/admin-registries/metadata-registry/metadata-registry.actions';
|
} from '../../+admin/admin-registries/metadata-registry/metadata-registry.actions';
|
||||||
import { getMockRequestService } from '../../shared/mocks/request.service.mock';
|
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
|
||||||
import { StoreMock } from '../../shared/testing/store.mock';
|
import { StoreMock } from '../../shared/testing/store.mock';
|
||||||
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
|
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
|
||||||
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
|
||||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
|
||||||
|
|
||||||
import {
|
import { RestResponse } from '../cache/response.models';
|
||||||
RegistryMetadatafieldsSuccessResponse,
|
|
||||||
RegistryMetadataschemasSuccessResponse,
|
|
||||||
RestResponse
|
|
||||||
} from '../cache/response.models';
|
|
||||||
import { RemoteData } from '../data/remote-data';
|
|
||||||
import { RequestEntry } from '../data/request.reducer';
|
|
||||||
import { RequestService } from '../data/request.service';
|
|
||||||
import { MetadataField } from '../metadata/metadata-field.model';
|
import { MetadataField } from '../metadata/metadata-field.model';
|
||||||
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
|
||||||
import { PageInfo } from '../shared/page-info.model';
|
|
||||||
import { RegistryMetadatafieldsResponse } from './registry-metadatafields-response.model';
|
|
||||||
import { RegistryMetadataschemasResponse } from './registry-metadataschemas-response.model';
|
|
||||||
import { RegistryService } from './registry.service';
|
import { RegistryService } from './registry.service';
|
||||||
import { storeModuleConfig } from '../../app.reducer';
|
import { storeModuleConfig } from '../../app.reducer';
|
||||||
|
import { FindListOptions } from '../data/request.models';
|
||||||
|
import { MetadataSchemaDataService } from '../data/metadata-schema-data.service';
|
||||||
|
import { MetadataFieldDataService } from '../data/metadata-field-data.service';
|
||||||
|
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||||
|
import { createPaginatedList } from '../../shared/testing/utils.test';
|
||||||
|
|
||||||
@Component({ template: '' })
|
@Component({ template: '' })
|
||||||
class DummyComponent {
|
class DummyComponent {
|
||||||
@@ -49,211 +38,169 @@ class DummyComponent {
|
|||||||
describe('RegistryService', () => {
|
describe('RegistryService', () => {
|
||||||
let registryService: RegistryService;
|
let registryService: RegistryService;
|
||||||
let mockStore;
|
let mockStore;
|
||||||
const pagination: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
|
let metadataSchemaService: MetadataSchemaDataService;
|
||||||
id: 'registry-service-spec-pagination',
|
let metadataFieldService: MetadataFieldDataService;
|
||||||
pageSize: 20
|
|
||||||
});
|
|
||||||
|
|
||||||
const mockSchemasList = [
|
let options: FindListOptions;
|
||||||
Object.assign(new MetadataSchema(), {
|
let mockSchemasList: MetadataSchema[];
|
||||||
id: 1,
|
let mockFieldsList: MetadataField[];
|
||||||
_links: {
|
|
||||||
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/1' }
|
function init() {
|
||||||
},
|
options = Object.assign(new FindListOptions(), {
|
||||||
prefix: 'dc',
|
currentPage: 1,
|
||||||
namespace: 'http://dublincore.org/documents/dcmi-terms/',
|
elementsPerPage: 20
|
||||||
type: MetadataSchema.type
|
});
|
||||||
}),
|
|
||||||
Object.assign(new MetadataSchema(), {
|
mockSchemasList = [
|
||||||
id: 2,
|
Object.assign(new MetadataSchema(), {
|
||||||
_links: {
|
|
||||||
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/2' }
|
|
||||||
},
|
|
||||||
prefix: 'mock',
|
|
||||||
namespace: 'http://dspace.org/mockschema',
|
|
||||||
type: MetadataSchema.type
|
|
||||||
})
|
|
||||||
];
|
|
||||||
const mockFieldsList = [
|
|
||||||
Object.assign(new MetadataField(),
|
|
||||||
{
|
|
||||||
id: 1,
|
id: 1,
|
||||||
_links: {
|
_links: {
|
||||||
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/8' }
|
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/1' }
|
||||||
},
|
},
|
||||||
element: 'contributor',
|
prefix: 'dc',
|
||||||
qualifier: 'advisor',
|
namespace: 'http://dublincore.org/documents/dcmi-terms/',
|
||||||
scopeNote: null,
|
type: MetadataSchema.type
|
||||||
schema: mockSchemasList[0],
|
|
||||||
type: MetadataField.type
|
|
||||||
}),
|
}),
|
||||||
Object.assign(new MetadataField(),
|
Object.assign(new MetadataSchema(), {
|
||||||
{
|
|
||||||
id: 2,
|
id: 2,
|
||||||
_links: {
|
_links: {
|
||||||
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/9' }
|
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/2' }
|
||||||
},
|
},
|
||||||
element: 'contributor',
|
prefix: 'mock',
|
||||||
qualifier: 'author',
|
namespace: 'http://dspace.org/mockschema',
|
||||||
scopeNote: null,
|
type: MetadataSchema.type
|
||||||
schema: mockSchemasList[0],
|
|
||||||
type: MetadataField.type
|
|
||||||
}),
|
|
||||||
Object.assign(new MetadataField(),
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
_links: {
|
|
||||||
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/10' }
|
|
||||||
},
|
|
||||||
element: 'contributor',
|
|
||||||
qualifier: 'editor',
|
|
||||||
scopeNote: 'test scope note',
|
|
||||||
schema: mockSchemasList[1],
|
|
||||||
type: MetadataField.type
|
|
||||||
}),
|
|
||||||
Object.assign(new MetadataField(),
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
_links: {
|
|
||||||
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/11' }
|
|
||||||
},
|
|
||||||
element: 'contributor',
|
|
||||||
qualifier: 'illustrator',
|
|
||||||
scopeNote: null,
|
|
||||||
schema: mockSchemasList[1],
|
|
||||||
type: MetadataField.type
|
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
const pageInfo = new PageInfo();
|
mockFieldsList = [
|
||||||
pageInfo.elementsPerPage = 20;
|
Object.assign(new MetadataField(),
|
||||||
pageInfo.currentPage = 1;
|
{
|
||||||
|
id: 1,
|
||||||
const endpoint = 'path';
|
_links: {
|
||||||
const endpointWithParams = `${endpoint}?size=${pageInfo.elementsPerPage}&page=${pageInfo.currentPage - 1}`;
|
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/8' }
|
||||||
const fieldEndpointWithParams = `${endpoint}?schema=${mockSchemasList[0].prefix}&size=${pageInfo.elementsPerPage}&page=${pageInfo.currentPage - 1}`;
|
},
|
||||||
|
element: 'contributor',
|
||||||
const halServiceStub = {
|
qualifier: 'advisor',
|
||||||
getEndpoint: (link: string) => observableOf(endpoint)
|
scopeNote: null,
|
||||||
};
|
schema: mockSchemasList[0],
|
||||||
|
type: MetadataField.type
|
||||||
const rdbStub = {
|
}),
|
||||||
toRemoteDataObservable: (requestEntryObs: Observable<RequestEntry>, payloadObs: Observable<any>) => {
|
Object.assign(new MetadataField(),
|
||||||
return observableCombineLatest(requestEntryObs,
|
{
|
||||||
payloadObs).pipe(map(([req, pay]) => {
|
id: 2,
|
||||||
return { req, pay };
|
_links: {
|
||||||
|
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/9' }
|
||||||
|
},
|
||||||
|
element: 'contributor',
|
||||||
|
qualifier: 'author',
|
||||||
|
scopeNote: null,
|
||||||
|
schema: mockSchemasList[0],
|
||||||
|
type: MetadataField.type
|
||||||
|
}),
|
||||||
|
Object.assign(new MetadataField(),
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
_links: {
|
||||||
|
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/10' }
|
||||||
|
},
|
||||||
|
element: 'contributor',
|
||||||
|
qualifier: 'editor',
|
||||||
|
scopeNote: 'test scope note',
|
||||||
|
schema: mockSchemasList[1],
|
||||||
|
type: MetadataField.type
|
||||||
|
}),
|
||||||
|
Object.assign(new MetadataField(),
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
_links: {
|
||||||
|
self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/11' }
|
||||||
|
},
|
||||||
|
element: 'contributor',
|
||||||
|
qualifier: 'illustrator',
|
||||||
|
scopeNote: null,
|
||||||
|
schema: mockSchemasList[1],
|
||||||
|
type: MetadataField.type
|
||||||
})
|
})
|
||||||
);
|
];
|
||||||
},
|
|
||||||
aggregate: (input: Array<Observable<RemoteData<any>>>): Observable<RemoteData<any[]>> => {
|
metadataSchemaService = jasmine.createSpyObj('metadataSchemaService', {
|
||||||
return createSuccessfulRemoteDataObject$([]);
|
findAll: createSuccessfulRemoteDataObject$(createPaginatedList(mockSchemasList)),
|
||||||
}
|
findById: createSuccessfulRemoteDataObject$(mockSchemasList[0]),
|
||||||
};
|
createOrUpdateMetadataSchema: createSuccessfulRemoteDataObject$(mockSchemasList[0]),
|
||||||
|
deleteAndReturnResponse: observableOf(new RestResponse(true, 200, 'OK')),
|
||||||
|
clearRequests: observableOf('href')
|
||||||
|
});
|
||||||
|
|
||||||
|
metadataFieldService = jasmine.createSpyObj('metadataFieldService', {
|
||||||
|
findAll: createSuccessfulRemoteDataObject$(createPaginatedList(mockFieldsList)),
|
||||||
|
findById: createSuccessfulRemoteDataObject$(mockFieldsList[0]),
|
||||||
|
createOrUpdateMetadataField: createSuccessfulRemoteDataObject$(mockFieldsList[0]),
|
||||||
|
deleteAndReturnResponse: observableOf(new RestResponse(true, 200, 'OK')),
|
||||||
|
clearRequests: observableOf('href')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
init();
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [CommonModule, StoreModule.forRoot({}, storeModuleConfig), TranslateModule.forRoot()],
|
imports: [CommonModule, StoreModule.forRoot({}, storeModuleConfig), TranslateModule.forRoot()],
|
||||||
declarations: [
|
declarations: [
|
||||||
DummyComponent
|
DummyComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: RequestService, useValue: getMockRequestService() },
|
|
||||||
{ provide: RemoteDataBuildService, useValue: rdbStub },
|
|
||||||
{ provide: HALEndpointService, useValue: halServiceStub },
|
|
||||||
{ provide: Store, useClass: StoreMock },
|
{ provide: Store, useClass: StoreMock },
|
||||||
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
|
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
|
||||||
|
{ provide: MetadataSchemaDataService, useValue: metadataSchemaService },
|
||||||
|
{ provide: MetadataFieldDataService, useValue: metadataFieldService },
|
||||||
RegistryService
|
RegistryService
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
registryService = TestBed.get(RegistryService);
|
registryService = TestBed.get(RegistryService);
|
||||||
mockStore = TestBed.get(Store);
|
mockStore = TestBed.get(Store);
|
||||||
spyOn((registryService as any).halService, 'getEndpoint').and.returnValue(observableOf(endpoint));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when requesting metadataschemas', () => {
|
describe('when requesting metadataschemas', () => {
|
||||||
const queryResponse = Object.assign(new RegistryMetadataschemasResponse(), {
|
let result;
|
||||||
metadataschemas: mockSchemasList,
|
|
||||||
page: pageInfo
|
|
||||||
});
|
|
||||||
const response = new RegistryMetadataschemasSuccessResponse(queryResponse, 200, 'OK', pageInfo);
|
|
||||||
const responseEntry = Object.assign(new RequestEntry(), { response: response });
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
(registryService as any).requestService.getByHref.and.returnValue(observableOf(responseEntry));
|
result = registryService.getMetadataSchemas(options);
|
||||||
/* tslint:disable:no-empty */
|
});
|
||||||
registryService.getMetadataSchemas(pagination).subscribe((value) => {
|
|
||||||
|
it('should call metadataSchemaService.findAll', (done) => {
|
||||||
|
result.subscribe(() => {
|
||||||
|
expect(metadataSchemaService.findAll).toHaveBeenCalled();
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
/* tslint:enable:no-empty */
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call getEndpoint on the halService', () => {
|
|
||||||
expect((registryService as any).halService.getEndpoint).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should send out the request on the request service', () => {
|
|
||||||
expect((registryService as any).requestService.configure).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call getByHref on the request service with the correct request url', () => {
|
|
||||||
expect((registryService as any).requestService.getByHref).toHaveBeenCalledWith(endpointWithParams);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when requesting metadataschema by name', () => {
|
describe('when requesting metadataschema by name', () => {
|
||||||
const queryResponse = Object.assign(new RegistryMetadataschemasResponse(), {
|
let result;
|
||||||
metadataschemas: mockSchemasList,
|
|
||||||
page: pageInfo
|
|
||||||
});
|
|
||||||
const response = new RegistryMetadataschemasSuccessResponse(queryResponse, 200, 'OK', pageInfo);
|
|
||||||
const responseEntry = Object.assign(new RequestEntry(), { response: response });
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
(registryService as any).requestService.getByHref.and.returnValue(observableOf(responseEntry));
|
result = registryService.getMetadataSchemaByName(mockSchemasList[0].prefix);
|
||||||
/* tslint:disable:no-empty */
|
});
|
||||||
registryService.getMetadataSchemaByName(mockSchemasList[0].prefix).subscribe((value) => {
|
|
||||||
|
it('should call metadataSchemaService.findById with the correct ID', (done) => {
|
||||||
|
result.subscribe(() => {
|
||||||
|
expect(metadataSchemaService.findById).toHaveBeenCalledWith(`${mockSchemasList[0].id}`);
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
/* tslint:enable:no-empty */
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call getEndpoint on the halService', () => {
|
|
||||||
expect((registryService as any).halService.getEndpoint).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should send out the request on the request service', () => {
|
|
||||||
expect((registryService as any).requestService.configure).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call getByHref on the request service with the correct request url', () => {
|
|
||||||
expect((registryService as any).requestService.getByHref.calls.argsFor(0)[0]).toContain(endpoint);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when requesting metadatafields', () => {
|
describe('when requesting metadatafields', () => {
|
||||||
const queryResponse = Object.assign(new RegistryMetadatafieldsResponse(), {
|
let result;
|
||||||
metadatafields: mockFieldsList,
|
|
||||||
page: pageInfo
|
|
||||||
});
|
|
||||||
const response = new RegistryMetadatafieldsSuccessResponse(queryResponse, 200, 'OK', pageInfo);
|
|
||||||
const responseEntry = Object.assign(new RequestEntry(), { response: response });
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
(registryService as any).requestService.getByHref.and.returnValue(observableOf(responseEntry));
|
result = registryService.getAllMetadataFields();
|
||||||
/* tslint:disable:no-empty */
|
});
|
||||||
registryService.getMetadataFieldsBySchema(mockSchemasList[0], pagination).subscribe((value) => {
|
|
||||||
|
it('should call metadataFieldService.findAll', (done) => {
|
||||||
|
result.subscribe(() => {
|
||||||
|
expect(metadataFieldService.findAll).toHaveBeenCalled();
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
/* tslint:enable:no-empty */
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call getEndpoint on the halService', () => {
|
|
||||||
expect((registryService as any).halService.getEndpoint).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should send out the request on the request service', () => {
|
|
||||||
expect((registryService as any).requestService.configure).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call getByHref on the request service with the correct request url', () => {
|
|
||||||
expect((registryService as any).requestService.getByHref).toHaveBeenCalledWith(fieldEndpointWithParams);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -370,9 +317,10 @@ describe('RegistryService', () => {
|
|||||||
result = registryService.createOrUpdateMetadataSchema(mockSchemasList[0]);
|
result = registryService.createOrUpdateMetadataSchema(mockSchemasList[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the created/updated metadata schema', () => {
|
it('should return the created/updated metadata schema', (done) => {
|
||||||
result.subscribe((schema: MetadataSchema) => {
|
result.subscribe((schema: MetadataSchema) => {
|
||||||
expect(schema).toEqual(mockSchemasList[0]);
|
expect(schema).toEqual(mockSchemasList[0]);
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -384,9 +332,10 @@ describe('RegistryService', () => {
|
|||||||
result = registryService.createOrUpdateMetadataField(mockFieldsList[0]);
|
result = registryService.createOrUpdateMetadataField(mockFieldsList[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the created/updated metadata field', () => {
|
it('should return the created/updated metadata field', (done) => {
|
||||||
result.subscribe((field: MetadataField) => {
|
result.subscribe((field: MetadataField) => {
|
||||||
expect(field).toEqual(mockFieldsList[0]);
|
expect(field).toEqual(mockFieldsList[0]);
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -425,7 +374,7 @@ describe('RegistryService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should remove the requests related to metadata schemas from cache', () => {
|
it('should remove the requests related to metadata schemas from cache', () => {
|
||||||
expect((registryService as any).requestService.removeByHrefSubstring).toHaveBeenCalled();
|
expect(metadataSchemaService.clearRequests).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -435,7 +384,7 @@ describe('RegistryService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should remove the requests related to metadata fields from cache', () => {
|
it('should remove the requests related to metadata fields from cache', () => {
|
||||||
expect((registryService as any).requestService.removeByHrefSubstring).toHaveBeenCalled();
|
expect(metadataFieldService.clearRequests).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -2,37 +2,18 @@ import { combineLatest as observableCombineLatest, Observable } from 'rxjs';
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { RemoteData } from '../data/remote-data';
|
import { RemoteData } from '../data/remote-data';
|
||||||
import { PaginatedList } from '../data/paginated-list';
|
import { PaginatedList } from '../data/paginated-list';
|
||||||
import { DSpaceSerializer } from '../dspace-rest-v2/dspace.serializer';
|
|
||||||
import { PageInfo } from '../shared/page-info.model';
|
import { PageInfo } from '../shared/page-info.model';
|
||||||
import {
|
import { FindListOptions } from '../data/request.models';
|
||||||
CreateMetadataFieldRequest,
|
|
||||||
CreateMetadataSchemaRequest,
|
|
||||||
DeleteRequest,
|
|
||||||
GetRequest,
|
|
||||||
RestRequest,
|
|
||||||
UpdateMetadataFieldRequest,
|
|
||||||
UpdateMetadataSchemaRequest
|
|
||||||
} from '../data/request.models';
|
|
||||||
import { GenericConstructor } from '../shared/generic-constructor';
|
|
||||||
import { ResponseParsingService } from '../data/parsing.service';
|
|
||||||
import { RegistryMetadataschemasResponseParsingService } from '../data/registry-metadataschemas-response-parsing.service';
|
|
||||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
import { RequestService } from '../data/request.service';
|
import { RequestService } from '../data/request.service';
|
||||||
import { RegistryMetadataschemasResponse } from './registry-metadataschemas-response.model';
|
|
||||||
import {
|
import {
|
||||||
MetadatafieldSuccessResponse,
|
MetadatafieldSuccessResponse,
|
||||||
MetadataschemaSuccessResponse,
|
MetadataschemaSuccessResponse,
|
||||||
RegistryMetadatafieldsSuccessResponse,
|
|
||||||
RegistryMetadataschemasSuccessResponse,
|
|
||||||
RestResponse
|
RestResponse
|
||||||
} from '../cache/response.models';
|
} from '../cache/response.models';
|
||||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||||
import { RegistryMetadatafieldsResponseParsingService } from '../data/registry-metadatafields-response-parsing.service';
|
import { hasNoValue, hasValue, hasValueOperator, isNotEmpty, isNotEmptyOperator } from '../../shared/empty.util';
|
||||||
import { RegistryMetadatafieldsResponse } from './registry-metadatafields-response.model';
|
import { getAllSucceededRemoteDataPayload, getFirstSucceededRemoteDataPayload } from '../shared/operators';
|
||||||
import { hasNoValue, hasValue, isNotEmpty, isNotEmptyOperator } from '../../shared/empty.util';
|
|
||||||
import { URLCombiner } from '../url-combiner/url-combiner';
|
|
||||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
|
||||||
import { configureRequest, getResponseFromEntry } from '../shared/operators';
|
|
||||||
import { createSelector, select, Store } from '@ngrx/store';
|
import { createSelector, select, Store } from '@ngrx/store';
|
||||||
import { AppState } from '../../app.reducer';
|
import { AppState } from '../../app.reducer';
|
||||||
import { MetadataRegistryState } from '../../+admin/admin-registries/metadata-registry/metadata-registry.reducers';
|
import { MetadataRegistryState } from '../../+admin/admin-registries/metadata-registry/metadata-registry.reducers';
|
||||||
@@ -48,15 +29,14 @@ import {
|
|||||||
MetadataRegistrySelectFieldAction,
|
MetadataRegistrySelectFieldAction,
|
||||||
MetadataRegistrySelectSchemaAction
|
MetadataRegistrySelectSchemaAction
|
||||||
} from '../../+admin/admin-registries/metadata-registry/metadata-registry.actions';
|
} from '../../+admin/admin-registries/metadata-registry/metadata-registry.actions';
|
||||||
import { distinctUntilChanged, flatMap, map, take, tap } from 'rxjs/operators';
|
import { flatMap, map, tap } from 'rxjs/operators';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { NotificationOptions } from '../../shared/notifications/models/notification-options.model';
|
|
||||||
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
|
|
||||||
import { HttpHeaders } from '@angular/common/http';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
import { MetadataSchema } from '../metadata/metadata-schema.model';
|
||||||
import { MetadataField } from '../metadata/metadata-field.model';
|
import { MetadataField } from '../metadata/metadata-field.model';
|
||||||
import { getClassForType } from '../cache/builders/build-decorators';
|
import { MetadataSchemaDataService } from '../data/metadata-schema-data.service';
|
||||||
|
import { MetadataFieldDataService } from '../data/metadata-field-data.service';
|
||||||
|
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||||
|
|
||||||
const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry;
|
const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry;
|
||||||
const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema);
|
const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema);
|
||||||
@@ -70,221 +50,64 @@ const selectedMetadataFieldsSelector = createSelector(metadataRegistryStateSelec
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class RegistryService {
|
export class RegistryService {
|
||||||
|
|
||||||
private metadataSchemasPath = 'metadataschemas';
|
constructor(private store: Store<AppState>,
|
||||||
private metadataFieldsPath = 'metadatafields';
|
|
||||||
|
|
||||||
// private bitstreamFormatsPath = 'bitstreamformats';
|
|
||||||
|
|
||||||
constructor(protected requestService: RequestService,
|
|
||||||
private rdb: RemoteDataBuildService,
|
|
||||||
private halService: HALEndpointService,
|
|
||||||
private store: Store<AppState>,
|
|
||||||
private notificationsService: NotificationsService,
|
private notificationsService: NotificationsService,
|
||||||
private translateService: TranslateService) {
|
private translateService: TranslateService,
|
||||||
|
private metadataSchemaService: MetadataSchemaDataService,
|
||||||
|
private metadataFieldService: MetadataFieldDataService) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all metadata schemas
|
* Retrieves all metadata schemas
|
||||||
* @param pagination The pagination info used to retrieve the schemas
|
* @param options The options used to retrieve the schemas
|
||||||
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
*/
|
*/
|
||||||
public getMetadataSchemas(pagination: PaginationComponentOptions): Observable<RemoteData<PaginatedList<MetadataSchema>>> {
|
public getMetadataSchemas(options: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<MetadataSchema>>): Observable<RemoteData<PaginatedList<MetadataSchema>>> {
|
||||||
const requestObs = this.getMetadataSchemasRequestObs(pagination);
|
return this.metadataSchemaService.findAll(options, ...linksToFollow);
|
||||||
|
|
||||||
const requestEntryObs = requestObs.pipe(
|
|
||||||
flatMap((request: RestRequest) => this.requestService.getByHref(request.href))
|
|
||||||
);
|
|
||||||
|
|
||||||
const rmrObs: Observable<RegistryMetadataschemasResponse> = requestEntryObs.pipe(
|
|
||||||
getResponseFromEntry(),
|
|
||||||
map((response: RegistryMetadataschemasSuccessResponse) => response.metadataschemasResponse)
|
|
||||||
);
|
|
||||||
|
|
||||||
const metadataschemasObs: Observable<MetadataSchema[]> = rmrObs.pipe(
|
|
||||||
map((rmr: RegistryMetadataschemasResponse) => rmr.metadataschemas)
|
|
||||||
);
|
|
||||||
|
|
||||||
const pageInfoObs: Observable<PageInfo> = requestEntryObs.pipe(
|
|
||||||
getResponseFromEntry(),
|
|
||||||
map((response: RegistryMetadataschemasSuccessResponse) => response.pageInfo)
|
|
||||||
);
|
|
||||||
|
|
||||||
const payloadObs = observableCombineLatest(metadataschemasObs, pageInfoObs).pipe(
|
|
||||||
map(([metadataschemas, pageInfo]) => {
|
|
||||||
return new PaginatedList(pageInfo, metadataschemas);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return this.rdb.toRemoteDataObservable(requestEntryObs, payloadObs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a metadata schema by its name
|
* Retrieves a metadata schema by its name
|
||||||
* @param schemaName The name of the schema to find
|
* @param schemaName The name of the schema to find
|
||||||
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
*/
|
*/
|
||||||
public getMetadataSchemaByName(schemaName: string): Observable<RemoteData<MetadataSchema>> {
|
public getMetadataSchemaByName(schemaName: string, ...linksToFollow: Array<FollowLinkConfig<MetadataSchema>>): Observable<RemoteData<MetadataSchema>> {
|
||||||
// Temporary pagination to get ALL metadataschemas until there's a rest api endpoint for fetching a specific schema
|
// Temporary options to get ALL metadataschemas until there's a rest api endpoint for fetching a specific schema
|
||||||
const pagination: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
|
const options: FindListOptions = Object.assign(new FindListOptions(), {
|
||||||
id: 'all-metadatafields-pagination',
|
elementsPerPage: 10000
|
||||||
pageSize: 10000
|
|
||||||
});
|
});
|
||||||
const requestObs = this.getMetadataSchemasRequestObs(pagination);
|
return this.getMetadataSchemas(options).pipe(
|
||||||
|
getFirstSucceededRemoteDataPayload(),
|
||||||
const requestEntryObs = requestObs.pipe(
|
map((schemas: PaginatedList<MetadataSchema>) => schemas.page),
|
||||||
flatMap((request: RestRequest) => this.requestService.getByHref(request.href))
|
isNotEmptyOperator(),
|
||||||
|
map((schemas: MetadataSchema[]) => schemas.filter((schema) => schema.prefix === schemaName)[0]),
|
||||||
|
flatMap((schema: MetadataSchema) => this.metadataSchemaService.findById(`${schema.id}`, ...linksToFollow))
|
||||||
);
|
);
|
||||||
|
|
||||||
const rmrObs: Observable<RegistryMetadataschemasResponse> = requestEntryObs.pipe(
|
|
||||||
getResponseFromEntry(),
|
|
||||||
map((response: RegistryMetadataschemasSuccessResponse) => response.metadataschemasResponse)
|
|
||||||
);
|
|
||||||
|
|
||||||
const metadataschemaObs: Observable<MetadataSchema> = rmrObs.pipe(
|
|
||||||
map((rmr: RegistryMetadataschemasResponse) => rmr.metadataschemas),
|
|
||||||
map((metadataSchemas: MetadataSchema[]) => metadataSchemas.filter((value) => value.prefix === schemaName)[0])
|
|
||||||
);
|
|
||||||
|
|
||||||
return this.rdb.toRemoteDataObservable(requestEntryObs, metadataschemaObs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieves all metadata fields that belong to a certain metadata schema
|
* retrieves all metadata fields that belong to a certain metadata schema
|
||||||
* @param schema The schema to filter by
|
* @param schema The schema to filter by
|
||||||
* @param pagination The pagination info used to retrieve the fields
|
* @param options The options info used to retrieve the fields
|
||||||
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
*/
|
*/
|
||||||
public getMetadataFieldsBySchema(schema: MetadataSchema, pagination: PaginationComponentOptions): Observable<RemoteData<PaginatedList<MetadataField>>> {
|
public getMetadataFieldsBySchema(schema: MetadataSchema, options: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<MetadataField>>): Observable<RemoteData<PaginatedList<MetadataField>>> {
|
||||||
const requestObs = this.getMetadataFieldsBySchemaRequestObs(pagination, schema);
|
return this.metadataFieldService.findBySchema(schema, options, ...linksToFollow);
|
||||||
|
|
||||||
const requestEntryObs = requestObs.pipe(
|
|
||||||
flatMap((request: RestRequest) => this.requestService.getByHref(request.href))
|
|
||||||
);
|
|
||||||
|
|
||||||
const rmrObs: Observable<RegistryMetadatafieldsResponse> = requestEntryObs.pipe(
|
|
||||||
getResponseFromEntry(),
|
|
||||||
map((response: RegistryMetadatafieldsSuccessResponse) => response.metadatafieldsResponse)
|
|
||||||
);
|
|
||||||
|
|
||||||
const metadatafieldsObs: Observable<MetadataField[]> = rmrObs.pipe(
|
|
||||||
map((rmr: RegistryMetadatafieldsResponse) => rmr.metadatafields)
|
|
||||||
);
|
|
||||||
|
|
||||||
const pageInfoObs: Observable<PageInfo> = requestEntryObs.pipe(
|
|
||||||
getResponseFromEntry(),
|
|
||||||
|
|
||||||
map((response: RegistryMetadatafieldsSuccessResponse) => response.pageInfo)
|
|
||||||
);
|
|
||||||
|
|
||||||
const payloadObs = observableCombineLatest(metadatafieldsObs, pageInfoObs).pipe(
|
|
||||||
map(([metadatafields, pageInfo]) => {
|
|
||||||
return new PaginatedList(pageInfo, metadatafields);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return this.rdb.toRemoteDataObservable(requestEntryObs, payloadObs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve all existing metadata fields as a paginated list
|
* Retrieve all existing metadata fields as a paginated list
|
||||||
* @param pagination Pagination options to determine which page of metadata fields should be requested
|
* @param options Options to determine which page of metadata fields should be requested
|
||||||
* When no pagination is provided, all metadata fields are requested in one large page
|
* When no options are provided, all metadata fields are requested in one large page
|
||||||
|
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
|
||||||
* @returns an observable that emits a remote data object with a page of metadata fields
|
* @returns an observable that emits a remote data object with a page of metadata fields
|
||||||
*/
|
*/
|
||||||
public getAllMetadataFields(pagination?: PaginationComponentOptions): Observable<RemoteData<PaginatedList<MetadataField>>> {
|
public getAllMetadataFields(options?: FindListOptions, ...linksToFollow: Array<FollowLinkConfig<MetadataField>>): Observable<RemoteData<PaginatedList<MetadataField>>> {
|
||||||
if (hasNoValue(pagination)) {
|
if (hasNoValue(options)) {
|
||||||
pagination = {currentPage: 1, pageSize: 10000} as any;
|
options = {currentPage: 1, elementsPerPage: 10000} as any;
|
||||||
}
|
}
|
||||||
const requestObs = this.getMetadataFieldsRequestObs(pagination);
|
return this.metadataFieldService.findAll(options, ...linksToFollow);
|
||||||
|
|
||||||
const requestEntryObs = requestObs.pipe(
|
|
||||||
flatMap((request: RestRequest) => this.requestService.getByHref(request.href))
|
|
||||||
);
|
|
||||||
|
|
||||||
const rmrObs: Observable<RegistryMetadatafieldsResponse> = requestEntryObs.pipe(
|
|
||||||
getResponseFromEntry(),
|
|
||||||
map((response: RegistryMetadatafieldsSuccessResponse) => response.metadatafieldsResponse)
|
|
||||||
);
|
|
||||||
|
|
||||||
const metadatafieldsObs: Observable<MetadataField[]> = rmrObs.pipe(
|
|
||||||
map((rmr: RegistryMetadatafieldsResponse) => rmr.metadatafields),
|
|
||||||
/* Make sure to explicitly cast this into a MetadataField object, on first page loads this object comes from the object cache created by the server and its prototype is unknown */
|
|
||||||
map((metadataFields: MetadataField[]) => metadataFields.map((metadataField: MetadataField) => Object.assign(new MetadataField(), metadataField)))
|
|
||||||
);
|
|
||||||
|
|
||||||
const pageInfoObs: Observable<PageInfo> = requestEntryObs.pipe(
|
|
||||||
getResponseFromEntry(),
|
|
||||||
|
|
||||||
map((response: RegistryMetadatafieldsSuccessResponse) => response.pageInfo)
|
|
||||||
);
|
|
||||||
|
|
||||||
const payloadObs = observableCombineLatest(metadatafieldsObs, pageInfoObs).pipe(
|
|
||||||
map(([metadatafields, pageInfo]) => {
|
|
||||||
return new PaginatedList(pageInfo, metadatafields);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return this.rdb.toRemoteDataObservable(requestEntryObs, payloadObs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public getMetadataSchemasRequestObs(pagination: PaginationComponentOptions): Observable<RestRequest> {
|
|
||||||
return this.halService.getEndpoint(this.metadataSchemasPath).pipe(
|
|
||||||
map((url: string) => {
|
|
||||||
const args: string[] = [];
|
|
||||||
args.push(`size=${pagination.pageSize}`);
|
|
||||||
args.push(`page=${pagination.currentPage - 1}`);
|
|
||||||
if (isNotEmpty(args)) {
|
|
||||||
url = new URLCombiner(url, `?${args.join('&')}`).toString();
|
|
||||||
}
|
|
||||||
const request = new GetRequest(this.requestService.generateRequestId(), url);
|
|
||||||
return Object.assign(request, {
|
|
||||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
|
||||||
return RegistryMetadataschemasResponseParsingService;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
tap((request: RestRequest) => this.requestService.configure(request)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private getMetadataFieldsBySchemaRequestObs(pagination: PaginationComponentOptions, schema: MetadataSchema): Observable<RestRequest> {
|
|
||||||
return this.halService.getEndpoint(this.metadataFieldsPath + '/search/bySchema').pipe(
|
|
||||||
// return this.halService.getEndpoint(this.metadataFieldsPath).pipe(
|
|
||||||
map((url: string) => {
|
|
||||||
const args: string[] = [];
|
|
||||||
args.push(`schema=${schema.prefix}`);
|
|
||||||
args.push(`size=${pagination.pageSize}`);
|
|
||||||
args.push(`page=${pagination.currentPage - 1}`);
|
|
||||||
if (isNotEmpty(args)) {
|
|
||||||
url = new URLCombiner(url, `?${args.join('&')}`).toString();
|
|
||||||
}
|
|
||||||
const request = new GetRequest(this.requestService.generateRequestId(), url);
|
|
||||||
return Object.assign(request, {
|
|
||||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
|
||||||
return RegistryMetadatafieldsResponseParsingService;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
tap((request: RestRequest) => this.requestService.configure(request)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private getMetadataFieldsRequestObs(pagination: PaginationComponentOptions): Observable<RestRequest> {
|
|
||||||
return this.halService.getEndpoint(this.metadataFieldsPath).pipe(
|
|
||||||
map((url: string) => {
|
|
||||||
const args: string[] = [];
|
|
||||||
args.push(`size=${pagination.pageSize}`);
|
|
||||||
args.push(`page=${pagination.currentPage - 1}`);
|
|
||||||
if (isNotEmpty(args)) {
|
|
||||||
url = new URLCombiner(url, `?${args.join('&')}`).toString();
|
|
||||||
}
|
|
||||||
const request = new GetRequest(this.requestService.generateRequestId(), url);
|
|
||||||
return Object.assign(request, {
|
|
||||||
getResponseParser(): GenericConstructor<ResponseParsingService> {
|
|
||||||
return RegistryMetadatafieldsResponseParsingService;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
tap((request: RestRequest) => this.requestService.configure(request)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public editMetadataSchema(schema: MetadataSchema) {
|
public editMetadataSchema(schema: MetadataSchema) {
|
||||||
@@ -386,59 +209,17 @@ export class RegistryService {
|
|||||||
* Create or Update a MetadataSchema
|
* Create or Update a MetadataSchema
|
||||||
* If the MetadataSchema contains an id, it is assumed the schema already exists and is updated instead
|
* If the MetadataSchema contains an id, it is assumed the schema already exists and is updated instead
|
||||||
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
||||||
* - On creation, a CreateMetadataSchemaRequest is used
|
* - On creation, a CreateRequest is used
|
||||||
* - On update, a UpdateMetadataSchemaRequest is used
|
* - On update, a PutRequest is used
|
||||||
* @param schema The MetadataSchema to create or update
|
* @param schema The MetadataSchema to create or update
|
||||||
*/
|
*/
|
||||||
public createOrUpdateMetadataSchema(schema: MetadataSchema): Observable<MetadataSchema> {
|
public createOrUpdateMetadataSchema(schema: MetadataSchema): Observable<MetadataSchema> {
|
||||||
const isUpdate = hasValue(schema.id);
|
const isUpdate = hasValue(schema.id);
|
||||||
const requestId = this.requestService.generateRequestId();
|
return this.metadataSchemaService.createOrUpdateMetadataSchema(schema).pipe(
|
||||||
const endpoint$ = this.halService.getEndpoint(this.metadataSchemasPath).pipe(
|
getFirstSucceededRemoteDataPayload(),
|
||||||
isNotEmptyOperator(),
|
hasValueOperator(),
|
||||||
map((endpoint: string) => (isUpdate ? `${endpoint}/${schema.id}` : endpoint)),
|
tap(() => {
|
||||||
distinctUntilChanged()
|
this.showNotifications(true, isUpdate, false, {prefix: schema.prefix});
|
||||||
);
|
|
||||||
|
|
||||||
const serializedSchema = new DSpaceSerializer(getClassForType(MetadataSchema.type)).serialize(schema);
|
|
||||||
|
|
||||||
const request$ = endpoint$.pipe(
|
|
||||||
take(1),
|
|
||||||
map((endpoint: string) => {
|
|
||||||
if (isUpdate) {
|
|
||||||
const options: HttpOptions = Object.create({});
|
|
||||||
let headers = new HttpHeaders();
|
|
||||||
headers = headers.append('Content-Type', 'application/json');
|
|
||||||
options.headers = headers;
|
|
||||||
return new UpdateMetadataSchemaRequest(requestId, endpoint, JSON.stringify(serializedSchema), options);
|
|
||||||
} else {
|
|
||||||
return new CreateMetadataSchemaRequest(requestId, endpoint, JSON.stringify(serializedSchema));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Execute the post/put request
|
|
||||||
request$.pipe(
|
|
||||||
configureRequest(this.requestService)
|
|
||||||
).subscribe();
|
|
||||||
|
|
||||||
// Return created/updated schema
|
|
||||||
return this.requestService.getByUUID(requestId).pipe(
|
|
||||||
getResponseFromEntry(),
|
|
||||||
map((response: RestResponse) => {
|
|
||||||
if (!response.isSuccessful) {
|
|
||||||
if (hasValue((response as any).errorMessage)) {
|
|
||||||
this.notificationsService.error('Server Error:', (response as any).errorMessage, new NotificationOptions(-1));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.showNotifications(true, isUpdate, false, {prefix: schema.prefix});
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
isNotEmptyOperator(),
|
|
||||||
map((response: MetadataschemaSuccessResponse) => {
|
|
||||||
if (isNotEmpty(response.metadataschema)) {
|
|
||||||
return response.metadataschema;
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -448,74 +229,32 @@ export class RegistryService {
|
|||||||
* @param id The id of the metadata schema to delete
|
* @param id The id of the metadata schema to delete
|
||||||
*/
|
*/
|
||||||
public deleteMetadataSchema(id: number): Observable<RestResponse> {
|
public deleteMetadataSchema(id: number): Observable<RestResponse> {
|
||||||
return this.delete(this.metadataSchemasPath, id);
|
return this.metadataSchemaService.deleteAndReturnResponse(`${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that clears a cached metadata schema request and returns its REST url
|
* Method that clears a cached metadata schema request and returns its REST url
|
||||||
*/
|
*/
|
||||||
public clearMetadataSchemaRequests(): Observable<string> {
|
public clearMetadataSchemaRequests(): Observable<string> {
|
||||||
return this.halService.getEndpoint(this.metadataSchemasPath).pipe(
|
return this.metadataSchemaService.clearRequests();
|
||||||
tap((href: string) => this.requestService.removeByHrefSubstring(href))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create or Update a MetadataField
|
* Create or Update a MetadataField
|
||||||
* If the MetadataField contains an id, it is assumed the field already exists and is updated instead
|
* If the MetadataField contains an id, it is assumed the field already exists and is updated instead
|
||||||
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
* Since creating or updating is nearly identical, the only real difference is the request (and slight difference in endpoint):
|
||||||
* - On creation, a CreateMetadataFieldRequest is used
|
* - On creation, a CreateRequest is used
|
||||||
* - On update, a UpdateMetadataFieldRequest is used
|
* - On update, a PutRequest is used
|
||||||
* @param field The MetadataField to create or update
|
* @param field The MetadataField to create or update
|
||||||
*/
|
*/
|
||||||
public createOrUpdateMetadataField(field: MetadataField): Observable<MetadataField> {
|
public createOrUpdateMetadataField(field: MetadataField): Observable<MetadataField> {
|
||||||
const isUpdate = hasValue(field.id);
|
const isUpdate = hasValue(field.id);
|
||||||
const requestId = this.requestService.generateRequestId();
|
return this.metadataFieldService.createOrUpdateMetadataField(field).pipe(
|
||||||
const endpoint$ = this.halService.getEndpoint(this.metadataFieldsPath).pipe(
|
getFirstSucceededRemoteDataPayload(),
|
||||||
isNotEmptyOperator(),
|
hasValueOperator(),
|
||||||
map((endpoint: string) => (isUpdate ? `${endpoint}/${field.id}` : `${endpoint}?schemaId=${field.schema.id}`)),
|
tap(() => {
|
||||||
distinctUntilChanged()
|
const fieldString = `${field.schema.prefix}.${field.element}${field.qualifier ? `.${field.qualifier}` : ''}`;
|
||||||
);
|
this.showNotifications(true, isUpdate, true, {field: fieldString});
|
||||||
|
|
||||||
const request$ = endpoint$.pipe(
|
|
||||||
take(1),
|
|
||||||
map((endpoint: string) => {
|
|
||||||
if (isUpdate) {
|
|
||||||
const options: HttpOptions = Object.create({});
|
|
||||||
let headers = new HttpHeaders();
|
|
||||||
headers = headers.append('Content-Type', 'application/json');
|
|
||||||
options.headers = headers;
|
|
||||||
return new UpdateMetadataFieldRequest(requestId, endpoint, JSON.stringify(field), options);
|
|
||||||
} else {
|
|
||||||
return new CreateMetadataFieldRequest(requestId, endpoint, JSON.stringify(field));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Execute the post/put request
|
|
||||||
request$.pipe(
|
|
||||||
configureRequest(this.requestService)
|
|
||||||
).subscribe();
|
|
||||||
|
|
||||||
// Return created/updated field
|
|
||||||
return this.requestService.getByUUID(requestId).pipe(
|
|
||||||
getResponseFromEntry(),
|
|
||||||
map((response: RestResponse) => {
|
|
||||||
if (!response.isSuccessful) {
|
|
||||||
if (hasValue((response as any).errorMessage)) {
|
|
||||||
this.notificationsService.error('Server Error:', (response as any).errorMessage, new NotificationOptions(-1));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const fieldString = `${field.schema.prefix}.${field.element}${field.qualifier ? `.${field.qualifier}` : ''}`;
|
|
||||||
this.showNotifications(true, isUpdate, true, {field: fieldString});
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
isNotEmptyOperator(),
|
|
||||||
map((response: MetadatafieldSuccessResponse) => {
|
|
||||||
if (isNotEmpty(response.metadatafield)) {
|
|
||||||
return response.metadatafield;
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -525,38 +264,13 @@ export class RegistryService {
|
|||||||
* @param id The id of the metadata field to delete
|
* @param id The id of the metadata field to delete
|
||||||
*/
|
*/
|
||||||
public deleteMetadataField(id: number): Observable<RestResponse> {
|
public deleteMetadataField(id: number): Observable<RestResponse> {
|
||||||
return this.delete(this.metadataFieldsPath, id);
|
return this.metadataFieldService.deleteAndReturnResponse(`${id}`);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Method that clears a cached metadata field request and returns its REST url
|
* Method that clears a cached metadata field request and returns its REST url
|
||||||
*/
|
*/
|
||||||
public clearMetadataFieldRequests(): Observable<string> {
|
public clearMetadataFieldRequests(): Observable<string> {
|
||||||
return this.halService.getEndpoint(this.metadataFieldsPath).pipe(
|
return this.metadataFieldService.clearRequests();
|
||||||
tap((href: string) => this.requestService.removeByHrefSubstring(href))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private delete(path: string, id: number): Observable<RestResponse> {
|
|
||||||
const requestId = this.requestService.generateRequestId();
|
|
||||||
const endpoint$ = this.halService.getEndpoint(path).pipe(
|
|
||||||
isNotEmptyOperator(),
|
|
||||||
map((endpoint: string) => `${endpoint}/${id}`),
|
|
||||||
distinctUntilChanged()
|
|
||||||
);
|
|
||||||
|
|
||||||
const request$ = endpoint$.pipe(
|
|
||||||
take(1),
|
|
||||||
map((endpoint: string) => new DeleteRequest(requestId, endpoint))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Execute the delete request
|
|
||||||
request$.pipe(
|
|
||||||
configureRequest(this.requestService)
|
|
||||||
).subscribe();
|
|
||||||
|
|
||||||
return this.requestService.getByUUID(requestId).pipe(
|
|
||||||
getResponseFromEntry()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private showNotifications(success: boolean, edited: boolean, isField: boolean, options: any) {
|
private showNotifications(success: boolean, edited: boolean, isField: boolean, options: any) {
|
||||||
|
14
src/app/shared/pagination/pagination.utils.ts
Normal file
14
src/app/shared/pagination/pagination.utils.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { PaginationComponentOptions } from './pagination-component-options.model';
|
||||||
|
import { FindListOptions } from '../../core/data/request.models';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform a PaginationComponentOptions object into a FindListOptions object
|
||||||
|
* @param pagination The PaginationComponentOptions to transform
|
||||||
|
* @param original An original FindListOptions object to start from
|
||||||
|
*/
|
||||||
|
export function toFindListOptions(pagination: PaginationComponentOptions, original?: FindListOptions): FindListOptions {
|
||||||
|
return Object.assign(new FindListOptions(), original, {
|
||||||
|
currentPage: pagination.currentPage,
|
||||||
|
elementsPerPage: pagination.pageSize
|
||||||
|
});
|
||||||
|
}
|
@@ -8,6 +8,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"admin.registries.bitstream-formats.breadcrumbs": "Format registry",
|
||||||
|
|
||||||
|
"admin.registries.bitstream-formats.create.breadcrumbs": "Bitstream format",
|
||||||
|
|
||||||
"admin.registries.bitstream-formats.create.failure.content": "An error occurred while creating the new bitstream format.",
|
"admin.registries.bitstream-formats.create.failure.content": "An error occurred while creating the new bitstream format.",
|
||||||
|
|
||||||
"admin.registries.bitstream-formats.create.failure.head": "Failure",
|
"admin.registries.bitstream-formats.create.failure.head": "Failure",
|
||||||
@@ -30,6 +34,8 @@
|
|||||||
|
|
||||||
"admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.",
|
"admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.",
|
||||||
|
|
||||||
|
"admin.registries.bitstream-formats.edit.breadcrumbs": "Bitstream format",
|
||||||
|
|
||||||
"admin.registries.bitstream-formats.edit.description.hint": "",
|
"admin.registries.bitstream-formats.edit.description.hint": "",
|
||||||
|
|
||||||
"admin.registries.bitstream-formats.edit.description.label": "Description",
|
"admin.registries.bitstream-formats.edit.description.label": "Description",
|
||||||
@@ -94,6 +100,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"admin.registries.metadata.breadcrumbs": "Metadata registry",
|
||||||
|
|
||||||
"admin.registries.metadata.description": "The metadata registry maintains a list of all metadata fields available in the repository. These fields may be divided amongst multiple schemas. However, DSpace requires the qualified Dublin Core schema.",
|
"admin.registries.metadata.description": "The metadata registry maintains a list of all metadata fields available in the repository. These fields may be divided amongst multiple schemas. However, DSpace requires the qualified Dublin Core schema.",
|
||||||
|
|
||||||
"admin.registries.metadata.form.create": "Create metadata schema",
|
"admin.registries.metadata.form.create": "Create metadata schema",
|
||||||
@@ -120,6 +128,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"admin.registries.schema.breadcrumbs": "Metadata schema",
|
||||||
|
|
||||||
"admin.registries.schema.description": "This is the metadata schema for \"{{namespace}}\".",
|
"admin.registries.schema.description": "This is the metadata schema for \"{{namespace}}\".",
|
||||||
|
|
||||||
"admin.registries.schema.fields.head": "Schema metadata fields",
|
"admin.registries.schema.fields.head": "Schema metadata fields",
|
||||||
|
Reference in New Issue
Block a user