mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
92187: Keep version creation modal opened till POST request finishes
This commit is contained in:
@@ -21,7 +21,7 @@ import {
|
||||
import { isEqual } from 'lodash';
|
||||
import { BehaviorSubject, Observable, of } from 'rxjs';
|
||||
import { select, Store } from '@ngrx/store';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { NgbModal, NgbModalConfig } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Angulartics2GoogleAnalytics } from 'angulartics2/ga';
|
||||
|
||||
@@ -48,6 +48,7 @@ import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
|
||||
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
|
||||
import { getDefaultThemeConfig } from '../config/config.util';
|
||||
import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface';
|
||||
import { ModalBeforeDismiss } from './shared/interfaces/modal-before-dismiss.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-app',
|
||||
@@ -105,6 +106,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||
private localeService: LocaleService,
|
||||
private breadcrumbsService: BreadcrumbsService,
|
||||
private modalService: NgbModal,
|
||||
private modalConfig: NgbModalConfig,
|
||||
@Optional() private cookiesService: KlaroService,
|
||||
@Optional() private googleAnalyticsService: GoogleAnalyticsService,
|
||||
) {
|
||||
@@ -165,6 +167,16 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
/** Implement behavior for interface {@link ModalBeforeDismiss} */
|
||||
this.modalConfig.beforeDismiss = async function () {
|
||||
if (typeof this?.componentInstance?.beforeDismiss === 'function') {
|
||||
return this.componentInstance.beforeDismiss()
|
||||
}
|
||||
|
||||
// fall back to default behavior
|
||||
return true;
|
||||
}
|
||||
|
||||
this.isAuthBlocking$ = this.store.pipe(select(isAuthenticationBlocking)).pipe(
|
||||
distinctUntilChanged()
|
||||
);
|
||||
|
@@ -62,6 +62,8 @@ export class VersionedItemComponent extends ItemComponent {
|
||||
activeModal.componentInstance.createVersionEvent.pipe(
|
||||
switchMap((summary: string) => this.versionHistoryService.createVersion(item._links.self.href, summary)),
|
||||
getFirstCompletedRemoteData(),
|
||||
// close model (should be displaying loading/waiting indicator) when version creation failed/succeeded
|
||||
tap(() => activeModal.close()),
|
||||
// show success/failure notification
|
||||
tap((res: RemoteData<Version>) => { this.itemVersionShared.notifyCreateNewVersion(res); }),
|
||||
// get workspace item
|
||||
|
25
src/app/shared/interfaces/modal-before-dismiss.interface.ts
Normal file
25
src/app/shared/interfaces/modal-before-dismiss.interface.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { NgbModalConfig, NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
|
||||
/**
|
||||
* If a component implementing this interface is used to create a modal (i.e. it is passed to {@link NgbModal#open}),
|
||||
* and that modal is dismissed, then {@link #beforeDismiss} will be called.
|
||||
*
|
||||
* This behavior is implemented for the whole app, by setting a default value for {@link NgbModalConfig#beforeDismiss}
|
||||
* in {@link AppComponent}.
|
||||
*
|
||||
* Docs: https://ng-bootstrap.github.io/#/components/modal/api
|
||||
*/
|
||||
export interface ModalBeforeDismiss {
|
||||
|
||||
/**
|
||||
* Callback right before the modal will be dismissed.
|
||||
* If this function returns:
|
||||
* - false
|
||||
* - a promise resolved with false
|
||||
* - a promise that is rejected
|
||||
* then the modal won't be dismissed.
|
||||
* Docs: https://ng-bootstrap.github.io/#/components/modal/api#NgbModalOptions
|
||||
*/
|
||||
beforeDismiss(): boolean | Promise<boolean>
|
||||
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
<div>
|
||||
<div *ngIf="!(this.submitted$ | async); else waiting">
|
||||
<div class="modal-header">{{'item.version.create.modal.header' | translate}}
|
||||
<button type="button" class="close" (click)="onModalClose()" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
@@ -34,3 +34,13 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #waiting>
|
||||
<div class="modal-header">{{'item.version.create.modal.submitted.header' | translate}}</div>
|
||||
<div class="modal-body">
|
||||
<p>{{'item.version.create.modal.submitted.text' | translate}}</p>
|
||||
<div class="d-flex justify-content-center">
|
||||
<ds-loading [showMessage]="false"></ds-loading>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
@@ -1,16 +1,19 @@
|
||||
import { Component, EventEmitter, Output } from '@angular/core';
|
||||
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { ModalBeforeDismiss } from '../../../interfaces/modal-before-dismiss.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-versions-summary-modal',
|
||||
templateUrl: './item-versions-summary-modal.component.html',
|
||||
styleUrls: ['./item-versions-summary-modal.component.scss']
|
||||
})
|
||||
export class ItemVersionsSummaryModalComponent {
|
||||
export class ItemVersionsSummaryModalComponent implements OnInit, ModalBeforeDismiss {
|
||||
|
||||
versionNumber: number;
|
||||
newVersionSummary: string;
|
||||
firstVersion = true;
|
||||
submitted$: BehaviorSubject<boolean>
|
||||
|
||||
@Output() createVersionEvent: EventEmitter<string> = new EventEmitter<string>();
|
||||
|
||||
@@ -19,13 +22,24 @@ export class ItemVersionsSummaryModalComponent {
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.submitted$ = new BehaviorSubject<boolean>(false);
|
||||
}
|
||||
|
||||
onModalClose() {
|
||||
this.activeModal.dismiss();
|
||||
}
|
||||
|
||||
beforeDismiss(): boolean | Promise<boolean> {
|
||||
// prevent the modal from being dismissed after version creation is initiated
|
||||
return !this.submitted$.getValue()
|
||||
}
|
||||
|
||||
onModalSubmit() {
|
||||
this.createVersionEvent.emit(this.newVersionSummary);
|
||||
this.activeModal.close();
|
||||
this.submitted$.next(true);
|
||||
// NOTE: the caller of this modal is responsible for closing it,
|
||||
// e.g. after the version creation POST request completed.
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -342,6 +342,9 @@ export class ItemVersionsComponent implements OnInit {
|
||||
version.item.pipe(getFirstSucceededRemoteDataPayload())
|
||||
])),
|
||||
mergeMap(([summary, item]: [string, Item]) => this.versionHistoryService.createVersion(item._links.self.href, summary)),
|
||||
getFirstCompletedRemoteData(),
|
||||
// close model (should be displaying loading/waiting indicator) when version creation failed/succeeded
|
||||
tap(() => activeModal.close()),
|
||||
// show success/failure notification
|
||||
tap((newVersionRD: RemoteData<Version>) => {
|
||||
this.itemVersionShared.notifyCreateNewVersion(newVersionRD);
|
||||
|
@@ -2232,6 +2232,10 @@
|
||||
|
||||
"item.version.create.modal.form.summary.placeholder": "Insert the summary for the new version",
|
||||
|
||||
"item.version.create.modal.submitted.header": "Creating new version...",
|
||||
|
||||
"item.version.create.modal.submitted.text": "The new version is being created. This may take some time if the item has a lot of relationships.",
|
||||
|
||||
"item.version.create.notification.success" : "New version has been created with version number {{version}}",
|
||||
|
||||
"item.version.create.notification.failure" : "New version has not been created",
|
||||
|
Reference in New Issue
Block a user