mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
70834: Metadata schema component refactoring and caching issue fix
This commit is contained in:
@@ -177,6 +177,7 @@ export class MetadataFieldFormComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}
|
||||
this.clearFields();
|
||||
this.registryService.cancelEditMetadataField();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@@ -1,36 +1,37 @@
|
||||
<div class="container">
|
||||
<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
|
||||
[metadataSchema]="(metadataSchema | async)?.payload"
|
||||
[metadataSchema]="schema"
|
||||
(submitForm)="forceUpdateFields()"></ds-metadata-field-form>
|
||||
|
||||
<h3>{{'admin.registries.schema.fields.head' | translate}}</h3>
|
||||
|
||||
<ds-pagination
|
||||
*ngIf="(metadataFields | async)?.payload?.totalElements > 0"
|
||||
[paginationOptions]="config"
|
||||
[pageInfoState]="(metadataFields | async)?.payload"
|
||||
[collectionSize]="(metadataFields | async)?.payload?.totalElements"
|
||||
[hideGear]="false"
|
||||
[hidePagerWhenSinglePage]="true"
|
||||
(pageChange)="onPageChange($event)">
|
||||
<div class="table-responsive">
|
||||
<table id="metadata-fields" class="table table-striped table-hover">
|
||||
<thead>
|
||||
<ng-container *ngVar="(metadataFields$ | async)?.payload as fields">
|
||||
<ds-pagination
|
||||
*ngIf="fields?.totalElements > 0"
|
||||
[paginationOptions]="config"
|
||||
[pageInfoState]="fields"
|
||||
[collectionSize]="fields?.totalElements"
|
||||
[hideGear]="false"
|
||||
[hidePagerWhenSinglePage]="true"
|
||||
(pageChange)="onPageChange($event)">
|
||||
<div class="table-responsive">
|
||||
<table id="metadata-fields" class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th scope="col">{{'admin.registries.schema.fields.table.field' | translate}}</th>
|
||||
<th scope="col">{{'admin.registries.schema.fields.table.scopenote' | translate}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let field of (metadataFields | async)?.payload?.page"
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let field of fields?.page"
|
||||
[ngClass]="{'table-primary' : isActive(field) | async}">
|
||||
<td>
|
||||
<label>
|
||||
@@ -39,22 +40,23 @@
|
||||
(change)="selectMetadataField(field, $event)">
|
||||
</label>
|
||||
</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>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</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>
|
||||
</ds-pagination>
|
||||
|
||||
<div *ngIf="(metadataFields | async)?.payload?.totalElements == 0" class="alert alert-info w-100 mb-2" role="alert">
|
||||
{{'admin.registries.schema.fields.no-items' | translate}}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<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>
|
||||
<button [routerLink]="['/admin/registries/metadata']" class="btn btn-primary">{{'admin.registries.schema.return' | translate}}</button>
|
||||
<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>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -5,7 +5,7 @@ import { Observable, combineLatest as observableCombineLatest } from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list';
|
||||
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 { RestResponse } from '../../../core/cache/response.models';
|
||||
import { zip } from 'rxjs/internal/observable/zip';
|
||||
@@ -13,8 +13,10 @@ import { NotificationsService } from '../../../shared/notifications/notification
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MetadataField } from '../../../core/metadata/metadata-field.model';
|
||||
import { MetadataSchema } from '../../../core/metadata/metadata-schema.model';
|
||||
import { getSucceededRemoteData } from '../../../core/shared/operators';
|
||||
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({
|
||||
selector: 'ds-metadata-schema',
|
||||
@@ -26,21 +28,15 @@ import { toFindListOptions } from '../../../shared/pagination/pagination.utils';
|
||||
* The admin can create, edit or delete metadata fields here.
|
||||
*/
|
||||
export class MetadataSchemaComponent implements OnInit {
|
||||
|
||||
/**
|
||||
* The namespace of the metadata schema
|
||||
*/
|
||||
namespace;
|
||||
|
||||
/**
|
||||
* The metadata schema
|
||||
*/
|
||||
metadataSchema: Observable<RemoteData<MetadataSchema>>;
|
||||
metadataSchema$: Observable<MetadataSchema>;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -51,6 +47,11 @@ export class MetadataSchemaComponent implements OnInit {
|
||||
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,
|
||||
private route: ActivatedRoute,
|
||||
private notificationsService: NotificationsService,
|
||||
@@ -70,7 +71,7 @@ export class MetadataSchemaComponent implements OnInit {
|
||||
* @param params
|
||||
*/
|
||||
initialize(params) {
|
||||
this.metadataSchema = this.registryService.getMetadataSchemaByName(params.schemaName);
|
||||
this.metadataSchema$ = this.registryService.getMetadataSchemaByName(params.schemaName).pipe(getFirstSucceededRemoteDataPayload());
|
||||
this.updateFields();
|
||||
}
|
||||
|
||||
@@ -80,18 +81,21 @@ export class MetadataSchemaComponent implements OnInit {
|
||||
*/
|
||||
onPageChange(event) {
|
||||
this.config.currentPage = event;
|
||||
this.updateFields();
|
||||
this.needsUpdate.next(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the list of fields by fetching it from the rest api or cache
|
||||
*/
|
||||
private updateFields() {
|
||||
this.metadataSchema.pipe(getSucceededRemoteData()).subscribe((schemaData) => {
|
||||
const schema = schemaData.payload;
|
||||
this.metadataFields = this.registryService.getMetadataFieldsBySchema(schema, toFindListOptions(this.config));
|
||||
this.namespace = {namespace: schemaData.payload.namespace};
|
||||
});
|
||||
this.metadataFields$ = combineLatest(this.metadataSchema$, this.needsUpdate).pipe(
|
||||
switchMap(([schema, update]: [MetadataSchema, boolean]) => {
|
||||
if (update) {
|
||||
console.log('reloaded list');
|
||||
return this.registryService.getMetadataFieldsBySchema(schema, toFindListOptions(this.config));
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,8 +103,7 @@ export class MetadataSchemaComponent implements OnInit {
|
||||
* a new REST call
|
||||
*/
|
||||
public forceUpdateFields() {
|
||||
this.registryService.clearMetadataFieldRequests().subscribe();
|
||||
this.updateFields();
|
||||
this.registryService.clearMetadataFieldRequests().subscribe(() => this.needsUpdate.next(true));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -45,6 +45,12 @@ export class MetadataFieldDataService extends DataService<MetadataField> {
|
||||
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 SearchParam('schema', schema.prefix)]
|
||||
@@ -52,6 +58,14 @@ export class MetadataFieldDataService extends DataService<MetadataField> {
|
||||
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 CreateMetadataFieldRequest is used
|
||||
* - On update, a UpdateMetadataFieldRequest is used
|
||||
* @param field The MetadataField to create or update
|
||||
*/
|
||||
createOrUpdateMetadataField(field: MetadataField): Observable<RestResponse> {
|
||||
const isUpdate = hasValue(field.id);
|
||||
const requestId = this.requestService.generateRequestId();
|
||||
@@ -97,9 +111,15 @@ export class MetadataFieldDataService extends DataService<MetadataField> {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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))
|
||||
tap((href: string) => {
|
||||
this.requestService.removeByHrefSubstring(href);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user