From dee799f9f47ab0c9093d69310361829149922a81 Mon Sep 17 00:00:00 2001 From: karolina-siemieniuk-morawska <55505399+karolina-siemieniuk-morawska@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:22:48 +0200 Subject: [PATCH] record-editor: open backoffice workflows in editor * ref: cern-sis/issues-inspire#538 --- backend/data/records/jobs/1813119.json | 2 +- record-editor/src/app/app.module.ts | 2 - record-editor/src/app/app.router.ts | 5 + .../backoffice-editor.component.html | 46 +++++ .../backoffice-editor.component.ts | 104 +++++++++++ .../backoffice-editor.module.ts | 36 ++++ .../backoffice-editor/backoffice.router.ts | 14 ++ .../services/backoffice-api-auth.service.ts | 19 ++ .../core/services/backoffice-api.service.ts | 170 ++++++++++++++++++ record-editor/src/app/core/services/index.ts | 6 + .../backoffice-save-button.component.html | 3 + .../backoffice-save-button.component.ts | 152 ++++++++++++++++ .../backoffice-save-button/index.ts | 3 + .../holdingpen-editor.module.ts | 3 + .../holdingpen-save-button.component.ts | 1 - .../holdingpen-toolbar.component.html | 7 +- .../holdingpen-toolbar.component.ts | 26 ++- .../src/app/shared/config/api.config.ts | 2 + .../app/shared/interfaces/workflow-object.ts | 15 +- .../src/environments/environment.prod.ts | 2 + record-editor/src/environments/environment.ts | 2 + .../AuthorDetailPageContainer.tsx | 17 +- .../AuthorDetailPageContainer.test.tsx.snap | 2 +- 23 files changed, 624 insertions(+), 15 deletions(-) create mode 100644 record-editor/src/app/backoffice-editor/backoffice-editor.component.html create mode 100644 record-editor/src/app/backoffice-editor/backoffice-editor.component.ts create mode 100644 record-editor/src/app/backoffice-editor/backoffice-editor.module.ts create mode 100644 record-editor/src/app/backoffice-editor/backoffice.router.ts create mode 100644 record-editor/src/app/core/services/backoffice-api-auth.service.ts create mode 100644 record-editor/src/app/core/services/backoffice-api.service.ts create mode 100644 record-editor/src/app/holdingpen-editor/backoffice-save-button/backoffice-save-button.component.html create mode 100644 record-editor/src/app/holdingpen-editor/backoffice-save-button/backoffice-save-button.component.ts create mode 100644 record-editor/src/app/holdingpen-editor/backoffice-save-button/index.ts diff --git a/backend/data/records/jobs/1813119.json b/backend/data/records/jobs/1813119.json index ca7cac4055..195733d796 100644 --- a/backend/data/records/jobs/1813119.json +++ b/backend/data/records/jobs/1813119.json @@ -25,7 +25,7 @@ } } ], - "deadline_date": "2024-09-20", + "deadline_date": "2025-09-20", "control_number": 1813119, "contact_details": [ { diff --git a/record-editor/src/app/app.module.ts b/record-editor/src/app/app.module.ts index d2e48e9b09..8e0ce3ad72 100644 --- a/record-editor/src/app/app.module.ts +++ b/record-editor/src/app/app.module.ts @@ -5,11 +5,9 @@ import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { APP_BASE_HREF } from '@angular/common'; import { HttpModule } from '@angular/http'; -import { FormsModule } from '@angular/forms'; import { AccordionModule } from 'ngx-bootstrap/accordion'; import { ToastrModule } from 'ngx-toastr'; -import { JsonEditorModule } from 'ng2-json-editor'; import { environment } from '../environments/environment'; import { AppRouter } from './app.router'; diff --git a/record-editor/src/app/app.router.ts b/record-editor/src/app/app.router.ts index 990164adf7..79968576c0 100644 --- a/record-editor/src/app/app.router.ts +++ b/record-editor/src/app/app.router.ts @@ -7,6 +7,11 @@ const appRoutes: Routes = [ loadChildren: './holdingpen-editor/holdingpen-editor.module#HoldingpenEditorModule', }, + { + path: 'backoffice', + loadChildren: + './backoffice-editor/backoffice-editor.module#BackofficeEditorModule', + }, { path: 'record', loadChildren: './record-editor/record-editor.module#RecordEditorModule', diff --git a/record-editor/src/app/backoffice-editor/backoffice-editor.component.html b/record-editor/src/app/backoffice-editor/backoffice-editor.component.html new file mode 100644 index 0000000000..d83fae86db --- /dev/null +++ b/record-editor/src/app/backoffice-editor/backoffice-editor.component.html @@ -0,0 +1,46 @@ + + + + + + + + + + + + + +
+
+ +
+
+ +
+
+
+ + + + + + + + + + +
+ + +
diff --git a/record-editor/src/app/backoffice-editor/backoffice-editor.component.ts b/record-editor/src/app/backoffice-editor/backoffice-editor.component.ts new file mode 100644 index 0000000000..7921e6c62a --- /dev/null +++ b/record-editor/src/app/backoffice-editor/backoffice-editor.component.ts @@ -0,0 +1,104 @@ +/* + * This file is part of record-editor. + * Copyright (C) 2016 CERN. + * + * record-editor is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * record-editor is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with record-editor; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * In applying this license, CERN does not + * waive the privileges and immunities granted to it by virtue of its status + * as an Intergovernmental Organization or submit itself to any jurisdiction. + */ + +import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { SchemaValidationProblems } from 'ng2-json-editor'; + +import { + BackofficeApiService, + AppConfigService, + GlobalAppStateService, + WorkflowErrorConverterService, +} from '../core/services'; +import { SubscriberComponent } from '../shared/classes'; +import { WorkflowObject } from '../shared/interfaces'; + +@Component({ + templateUrl: './backoffice-editor.component.html', + styleUrls: [ + '../record-editor/json-editor-wrapper/json-editor-wrapper.component.scss', + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class BackofficeEditorComponent + extends SubscriberComponent + implements OnInit { + workflowObject: WorkflowObject; + schema: Object; + config: Object; + workflowProblems: SchemaValidationProblems; + uuid: string; + + constructor( + private route: ActivatedRoute, + private apiService: BackofficeApiService, + private appConfigService: AppConfigService, + private globalAppStateService: GlobalAppStateService, + private workflowErrorConverterService: WorkflowErrorConverterService + ) { + super(); + } + + ngOnInit(): void { + this.route.params.takeUntil(this.isDestroyed).subscribe(async (params) => { + this.uuid = params['uuid']; + + this.workflowObject = await this.apiService.fetchWorkflowObject( + this.uuid + ) as WorkflowObject; + this.schema = await this.apiService.fetchSchema(); + this.setWorkflowProblems(); + this.globalAppStateService.jsonBeingEdited$.next(this.workflowObject); + this.globalAppStateService.isJsonUpdated$.next(false); + this.config = this.appConfigService.getConfigForRecord( + this.workflowObject.metadata + ); + }); + } + + private setWorkflowProblems() { + const errors = this.workflowExtraData.validation_errors; + if (errors && errors.length > 0) { + this.workflowProblems = + this.workflowErrorConverterService.toValidationProblems(errors); + } else { + this.workflowProblems = {}; + } + } + + get workflowExtraData() { + return this.workflowObject._extra_data || {}; + } + + onValidationProblems(problems: SchemaValidationProblems) { + this.globalAppStateService.validationProblems$.next(problems); + } + + onWorkflowMetadataChange(metadata: object) { + const workflowObject = Object.assign({}, this.workflowObject, { + metadata, + }); + this.globalAppStateService.jsonBeingEdited$.next(workflowObject); + this.globalAppStateService.isJsonUpdated$.next(true); + } +} diff --git a/record-editor/src/app/backoffice-editor/backoffice-editor.module.ts b/record-editor/src/app/backoffice-editor/backoffice-editor.module.ts new file mode 100644 index 0000000000..3a0a16af0b --- /dev/null +++ b/record-editor/src/app/backoffice-editor/backoffice-editor.module.ts @@ -0,0 +1,36 @@ +/* + * This file is part of record-editor. + * Copyright (C) 2017 CERN. + * + * record-editor is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * record-editor is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with record-editor; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * In applying this license, CERN does not + * waive the privileges and immunities granted to it by virtue of its status + * as an Intergovernmental Organization or submit itself to any jurisdiction. + */ + +import { NgModule } from '@angular/core'; + +import { BackofficeEditorRouter } from './backoffice.router'; + +import { BackofficeEditorComponent } from './backoffice-editor.component'; + +import { SharedModule } from '../shared'; +import { HoldingpenEditorModule } from '../holdingpen-editor/holdingpen-editor.module'; + +@NgModule({ + imports: [SharedModule, BackofficeEditorRouter, HoldingpenEditorModule], + declarations: [BackofficeEditorComponent], +}) +export class BackofficeEditorModule {} diff --git a/record-editor/src/app/backoffice-editor/backoffice.router.ts b/record-editor/src/app/backoffice-editor/backoffice.router.ts new file mode 100644 index 0000000000..15983935eb --- /dev/null +++ b/record-editor/src/app/backoffice-editor/backoffice.router.ts @@ -0,0 +1,14 @@ +import { Routes, RouterModule } from '@angular/router'; +import { NgModule } from '@angular/core'; + +import { BackofficeEditorComponent } from './backoffice-editor.component'; + +const backofficeEditorRoutes: Routes = [ + { path: ':uuid', component: BackofficeEditorComponent }, +]; + +@NgModule({ + imports: [RouterModule.forChild(backofficeEditorRoutes)], + exports: [RouterModule], +}) +export class BackofficeEditorRouter {} diff --git a/record-editor/src/app/core/services/backoffice-api-auth.service.ts b/record-editor/src/app/core/services/backoffice-api-auth.service.ts new file mode 100644 index 0000000000..072320c1bd --- /dev/null +++ b/record-editor/src/app/core/services/backoffice-api-auth.service.ts @@ -0,0 +1,19 @@ +import { Http } from '@angular/http'; +import { Injectable } from '@angular/core'; + +import { CommonApiService } from './common-api.service'; +import { backofficeApiUrl } from '../../shared/config'; + +@Injectable() +export class BackofficeApiAuthService extends CommonApiService { + constructor(protected http: Http) { + super(http); + } + + refreshToken(refreshToken: string): Promise<{ access: string }> { + return this.http + .post(`${backofficeApiUrl}/token/refresh/`, { refresh: refreshToken }) + .map((res) => res.json()) + .toPromise(); + } +} diff --git a/record-editor/src/app/core/services/backoffice-api.service.ts b/record-editor/src/app/core/services/backoffice-api.service.ts new file mode 100644 index 0000000000..f2d29b5ae3 --- /dev/null +++ b/record-editor/src/app/core/services/backoffice-api.service.ts @@ -0,0 +1,170 @@ +/* + * This file is part of record-editor. + * Copyright (C) 2016 CERN. + * + * record-editor is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * record-editor is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with record-editor; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * In applying this license, CERN does not + * waive the privileges and immunities granted to it by virtue of its status + * as an Intergovernmental Organization or submit itself to any jurisdiction. + */ + +import { Injectable } from '@angular/core'; +import { Http, Headers } from '@angular/http'; + +import { Observable } from 'rxjs/Observable'; + +import { CommonApiService } from './common-api.service'; +import { backofficeApiUrl, hepSchemaUrl } from '../../shared/config'; +import { ApiError } from '../../shared/classes'; +import { WorkflowObject } from '../../shared/interfaces'; +import { BackofficeApiAuthService } from '../services/backoffice-api-auth.service'; + +export interface BackofficeWorkflow { + id: number; + workflow_type: string; + status: string; + core: boolean; + data: { + name: { + value: string; + preferred_name?: string; + }; + status?: string; + $schema: string; + _collections: ['Authors']; + control_number?: number; + acquisition_source: { + email: string | null; + orcid: string | null; + method: string | null; + source: string | null; + datetime: string | null; + internal_uid: string | number; + }; + }; + is_update: boolean; + _created_at: string; + _updated_at: string; + tickets: { + ticket_id: string; + ticket_url: string; + }[]; + [key: string]: any; +} + +@Injectable() +export class BackofficeApiService extends CommonApiService { + private currentWorkflowObjectApiUrl: string; + + constructor( + protected http: Http, + private authService: BackofficeApiAuthService + ) { + super(http); + } + + fetchSchema(): Promise { + return this.fetchUrl(`${hepSchemaUrl}`); + } + + async fetchWorkflowObject( + objectId: string, + getFullObject?: boolean + ): Promise { + return this.handleRequest(async () => { + this.currentWorkflowObjectApiUrl = `${backofficeApiUrl}/workflows/${objectId}`; + const token = localStorage.getItem('backoffice.token'); + const response = await this.fetchUrl( + this.currentWorkflowObjectApiUrl, + { + headers: new Headers({ + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }), + } + ); + + if (getFullObject) { + return response; + } else { + return { + id: response.id, + metadata: { + $schema: this.fetchSchema(), + ...response.data, + }, + _extra_data: {}, + }; + } + }); + } + + validateWorkflowObject(object: WorkflowObject): Observable { + const token = localStorage.getItem('backoffice.token'); + + return this.http + .post(`${backofficeApiUrl}/workflows/authors/validate/`, object.metadata, { + headers: new Headers({ + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }), + }) + .catch((error) => Observable.throw(new ApiError(error))) + .map((res) => res.json()); + } + + saveWorkflowObject(object: WorkflowObject, request_data): Observable { + const token = localStorage.getItem('backoffice.token'); + + return this.http + .put( + this.currentWorkflowObjectApiUrl, + { ...request_data, data: object.metadata }, + { + headers: new Headers({ + 'Content-Type': 'application/json', + Authorization: `Bearer ${token}`, + }), + } + ) + .catch((error) => Observable.throw(new ApiError(error))) + .map((res) => res.json()); + } + + private handleRequest(requestFn: () => Promise): Promise { + return requestFn().catch((error) => { + if (error.status === 403) { + const refreshToken = localStorage.getItem('backoffice.refresh'); + + if (!refreshToken) { + return Promise.reject(error); + } + + return this.authService + .refreshToken(refreshToken) + .then((response) => { + localStorage.setItem('backoffice.token', response.access); + + return requestFn(); + }) + .catch((refreshError) => { + return Promise.reject(refreshError); + }); + } + + return Promise.reject(error); + }); + } +} diff --git a/record-editor/src/app/core/services/index.ts b/record-editor/src/app/core/services/index.ts index 74f591003a..22b93b154b 100644 --- a/record-editor/src/app/core/services/index.ts +++ b/record-editor/src/app/core/services/index.ts @@ -10,10 +10,14 @@ import { GlobalAppStateService } from './global-app-state.service'; import { WorkflowErrorConverterService } from './workflow-error-converter.service'; import { ReleaseLockService } from './release-lock-service'; import { EditorErrorConverterService } from './editor-error-converter.service'; +import { BackofficeApiService } from './backoffice-api.service'; +import { BackofficeApiAuthService } from './backoffice-api-auth.service'; export { CommonApiService, HoldingpenApiService, + BackofficeApiService, + BackofficeApiAuthService, RecordApiService, AppConfigService, RecordCleanupService, @@ -29,6 +33,8 @@ export { export const CORE_SERVICES = [ CommonApiService, HoldingpenApiService, + BackofficeApiService, + BackofficeApiAuthService, RecordApiService, AppConfigService, RecordCleanupService, diff --git a/record-editor/src/app/holdingpen-editor/backoffice-save-button/backoffice-save-button.component.html b/record-editor/src/app/holdingpen-editor/backoffice-save-button/backoffice-save-button.component.html new file mode 100644 index 0000000000..29caa54e94 --- /dev/null +++ b/record-editor/src/app/holdingpen-editor/backoffice-save-button/backoffice-save-button.component.html @@ -0,0 +1,3 @@ + diff --git a/record-editor/src/app/holdingpen-editor/backoffice-save-button/backoffice-save-button.component.ts b/record-editor/src/app/holdingpen-editor/backoffice-save-button/backoffice-save-button.component.ts new file mode 100644 index 0000000000..59ec73e16a --- /dev/null +++ b/record-editor/src/app/holdingpen-editor/backoffice-save-button/backoffice-save-button.component.ts @@ -0,0 +1,152 @@ +/* + * This file is part of record-editor. + * Copyright (C) 2016 CERN. + * + * record-editor is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * record-editor is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with record-editor; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * In applying this license, CERN does not + * waive the privileges and immunities granted to it by virtue of its status + * as an Intergovernmental Organization or submit itself to any jurisdiction. + */ + +import { + Component, + OnInit, + ChangeDetectionStrategy, + ChangeDetectorRef, +} from '@angular/core'; +import { ToastrService, ActiveToast } from 'ngx-toastr'; +import { ActivatedRoute } from '@angular/router'; + +import { + RecordCleanupService, + DomUtilsService, + GlobalAppStateService, + BackofficeApiService, +} from '../../core/services'; +import { SubscriberComponent, ApiError } from '../../shared/classes'; +import { WorkflowObject } from '../../shared/interfaces'; +import { BackofficeWorkflow } from '../../core/services/backoffice-api.service'; +import { HOVER_TO_DISMISS_INDEFINITE_TOAST } from '../../shared/constants'; + +@Component({ + selector: 're-backoffice-save-button', + templateUrl: './backoffice-save-button.component.html', + styleUrls: [ + '../../record-editor/json-editor-wrapper/json-editor-wrapper.component.scss', + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class BackofficeSaveButtonComponent + extends SubscriberComponent + implements OnInit { + private workflowObject: WorkflowObject; + + private hasAnyValidationProblem = false; + private savingInfoToast: ActiveToast; + + uuid: string; + fullWorkflowObject: BackofficeWorkflow; + + constructor( + private changeDetectorRef: ChangeDetectorRef, + private apiService: BackofficeApiService, + private recordCleanupService: RecordCleanupService, + private domUtilsService: DomUtilsService, + private globalAppStateService: GlobalAppStateService, + private toastrService: ToastrService, + private route: ActivatedRoute, + ) { + super(); + } + + get jsonBeingEdited$() { + return this.globalAppStateService.jsonBeingEdited$; + } + + ngOnInit() { + this.route.params.takeUntil(this.isDestroyed).subscribe(async (params) => { + this.uuid = params['uuid']; + }); + this.apiService.fetchWorkflowObject(this.uuid, true).then( + (data) => { this.fullWorkflowObject = data as BackofficeWorkflow; } + ); + this.globalAppStateService.hasAnyValidationProblem$ + .takeUntil(this.isDestroyed) + .subscribe((hasAnyValidationProblem) => { + this.hasAnyValidationProblem = hasAnyValidationProblem; + this.changeDetectorRef.markForCheck(); + }); + + this.jsonBeingEdited$ + .takeUntil(this.isDestroyed) + .subscribe((jsonBeingEdited) => { + this.workflowObject = jsonBeingEdited as WorkflowObject; + this.changeDetectorRef.markForCheck(); + }); + } + + get saveButtonDisabledAttribute(): string { + return this.hasAnyValidationProblem ? 'disabled' : ''; + } + + onClickSave() { + this.savingInfoToast = this.toastrService.info( + 'Saving workflow object', + 'Loading', + HOVER_TO_DISMISS_INDEFINITE_TOAST + ); + + this.cleanupAndSave(); + } + + private cleanupAndSave() { + this.recordCleanupService.cleanup(this.workflowObject.metadata); + this.apiService.validateWorkflowObject(this.workflowObject).subscribe( + (data) => { + delete this.workflowObject._extra_data['validation_errors']; + this.jsonBeingEdited$.next(this.workflowObject); + }, + (error) => { + this.workflowObject._extra_data['validation_errors'] = error.body; + this.jsonBeingEdited$.next(this.workflowObject); + this.displayErrorToast(error); + }, + () => { + this.save(); + } + ); + } + + private save() { + this.apiService + .saveWorkflowObject(this.workflowObject, this.fullWorkflowObject) + .do(() => this.domUtilsService.unregisterBeforeUnloadPrompt()) + .subscribe( + () => { + this.toastrService.clear(this.savingInfoToast.toastId); + this.toastrService.success(`Workflow object is saved`, 'Success'); + }, + (error) => { + this.displayErrorToast(error); + } + ); + } + + private displayErrorToast(error: ApiError) { + this.toastrService.clear(this.savingInfoToast.toastId); + const errorMessage = error.message || 'Could not save the workflow object'; + this.toastrService.error(errorMessage, 'Error'); + } +} diff --git a/record-editor/src/app/holdingpen-editor/backoffice-save-button/index.ts b/record-editor/src/app/holdingpen-editor/backoffice-save-button/index.ts new file mode 100644 index 0000000000..df738ce2dc --- /dev/null +++ b/record-editor/src/app/holdingpen-editor/backoffice-save-button/index.ts @@ -0,0 +1,3 @@ +export { + BackofficeSaveButtonComponent, +} from './backoffice-save-button.component'; diff --git a/record-editor/src/app/holdingpen-editor/holdingpen-editor.module.ts b/record-editor/src/app/holdingpen-editor/holdingpen-editor.module.ts index a3a0a203fb..9bf07065e4 100644 --- a/record-editor/src/app/holdingpen-editor/holdingpen-editor.module.ts +++ b/record-editor/src/app/holdingpen-editor/holdingpen-editor.module.ts @@ -29,6 +29,7 @@ import { HoldingpenToolbarComponent } from './holdingpen-toolbar'; import { HoldingpenSaveButtonComponent } from './holdingpen-save-button'; import { SharedModule } from '../shared'; +import { BackofficeSaveButtonComponent } from './backoffice-save-button'; @NgModule({ imports: [SharedModule, HoldingpenEditorRouter], @@ -36,6 +37,8 @@ import { SharedModule } from '../shared'; HoldingpenEditorComponent, HoldingpenToolbarComponent, HoldingpenSaveButtonComponent, + BackofficeSaveButtonComponent ], + exports: [HoldingpenToolbarComponent, HoldingpenSaveButtonComponent], }) export class HoldingpenEditorModule {} diff --git a/record-editor/src/app/holdingpen-editor/holdingpen-save-button/holdingpen-save-button.component.ts b/record-editor/src/app/holdingpen-editor/holdingpen-save-button/holdingpen-save-button.component.ts index 66e8e8f8ca..8d1d5b45b1 100644 --- a/record-editor/src/app/holdingpen-editor/holdingpen-save-button/holdingpen-save-button.component.ts +++ b/record-editor/src/app/holdingpen-editor/holdingpen-save-button/holdingpen-save-button.component.ts @@ -22,7 +22,6 @@ import { Component, - Input, OnInit, ChangeDetectionStrategy, ChangeDetectorRef, diff --git a/record-editor/src/app/holdingpen-editor/holdingpen-toolbar/holdingpen-toolbar.component.html b/record-editor/src/app/holdingpen-editor/holdingpen-toolbar/holdingpen-toolbar.component.html index 0dbe45f9a5..97c9cdd335 100644 --- a/record-editor/src/app/holdingpen-editor/holdingpen-toolbar/holdingpen-toolbar.component.html +++ b/record-editor/src/app/holdingpen-editor/holdingpen-toolbar/holdingpen-toolbar.component.html @@ -2,7 +2,12 @@
diff --git a/record-editor/src/app/holdingpen-editor/holdingpen-toolbar/holdingpen-toolbar.component.ts b/record-editor/src/app/holdingpen-editor/holdingpen-toolbar/holdingpen-toolbar.component.ts index 8b74520337..6b165d9485 100644 --- a/record-editor/src/app/holdingpen-editor/holdingpen-toolbar/holdingpen-toolbar.component.ts +++ b/record-editor/src/app/holdingpen-editor/holdingpen-toolbar/holdingpen-toolbar.component.ts @@ -22,11 +22,16 @@ import { Component, + OnInit, + Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef, } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; + +import { GlobalAppStateService } from '../../core/services'; @Component({ selector: 're-holdingpen-toolbar', @@ -36,11 +41,28 @@ import { ], changeDetection: ChangeDetectionStrategy.OnPush, }) -export class HoldingpenToolbarComponent { +export class HoldingpenToolbarComponent implements OnInit { + @Input() backoffice: boolean; @Output() revisionChange = new EventEmitter(); + displayingRevision = false; + recordId: number; - constructor(private changeDetectorRef: ChangeDetectorRef) {} + constructor( + private changeDetectorRef: ChangeDetectorRef, + private globalAppStateService: GlobalAppStateService + ) {} + + ngOnInit() { + Observable.combineLatest( + this.globalAppStateService.pidValueBeingEdited$, + (pidValue) => ({ pidValue }) + ) + .filter(({ pidValue }) => Boolean(pidValue)) + .subscribe(({ pidValue }) => { + this.recordId = pidValue; + }); + } onRevisionChange(revision: object | undefined) { this.revisionChange.emit(revision); diff --git a/record-editor/src/app/shared/config/api.config.ts b/record-editor/src/app/shared/config/api.config.ts index de6d600284..97ba935da4 100644 --- a/record-editor/src/app/shared/config/api.config.ts +++ b/record-editor/src/app/shared/config/api.config.ts @@ -26,3 +26,5 @@ export const apiUrl = `${environment.baseUrl}/api`; export const editorApiUrl = `${apiUrl}/editor`; export const matcherApiUrl = `${apiUrl}/matcher`; export const holdingpenApiUrl = `${apiUrl}/holdingpen`; +export const backofficeApiUrl = `${environment.backofficeApiUrl}`; +export const hepSchemaUrl = `${environment.schemaUrl}`; diff --git a/record-editor/src/app/shared/interfaces/workflow-object.ts b/record-editor/src/app/shared/interfaces/workflow-object.ts index 2b63e673f3..42f98317ab 100644 --- a/record-editor/src/app/shared/interfaces/workflow-object.ts +++ b/record-editor/src/app/shared/interfaces/workflow-object.ts @@ -1,12 +1,23 @@ import { ValidationError } from './validation-error'; import { JsonPatch } from './json-patch'; -export interface WorkflowObject { +export interface WorkflowObject { id: number; _extra_data?: { validation_errors?: Array; callback_url?: string; conflicts?: Array; + ticket_id?: string; + ticket_url?: string; + }; + metadata: { + $schema: string; + _collections: ['Authors']; + acquisition_source: T; + name: { + value: string; + preferred_name?: string; + }; + status?: string; }; - metadata: object; } diff --git a/record-editor/src/environments/environment.prod.ts b/record-editor/src/environments/environment.prod.ts index 60ad8c90bf..ca96184ef3 100644 --- a/record-editor/src/environments/environment.prod.ts +++ b/record-editor/src/environments/environment.prod.ts @@ -6,4 +6,6 @@ export const environment = { sentryPublicDSN: 'https://ac471ee3b1ef4d1f884bfeaebaf6d007@sentry.siscern.org/7', version, + schemaUrl: 'https://inspirebeta.net/schemas/records/authors.json', + backofficeApiUrl: 'https://backoffice.dev.inspirebeta.net/api', }; diff --git a/record-editor/src/environments/environment.ts b/record-editor/src/environments/environment.ts index 777608e754..a5741f9ab7 100644 --- a/record-editor/src/environments/environment.ts +++ b/record-editor/src/environments/environment.ts @@ -8,4 +8,6 @@ export const environment = { baseUrl: '', sentryPublicDSN: null, version: null, + schemaUrl: 'https://inspirebeta.net/schemas/records/authors.json', + backofficeApiUrl: 'https://backoffice.dev.inspirebeta.net/api', }; diff --git a/ui/src/backoffice/containers/DetailPageContainer/AuthorDetailPageContainer.tsx b/ui/src/backoffice/containers/DetailPageContainer/AuthorDetailPageContainer.tsx index e8ef11adec..0cf3ae6bdb 100644 --- a/ui/src/backoffice/containers/DetailPageContainer/AuthorDetailPageContainer.tsx +++ b/ui/src/backoffice/containers/DetailPageContainer/AuthorDetailPageContainer.tsx @@ -12,6 +12,7 @@ import { ActionCreator, Action } from 'redux'; import { connect, RootStateOrAny } from 'react-redux'; import { Map } from 'immutable'; import { push } from 'connected-react-router'; +import classNames from 'classnames'; import './DetailPageContainer.less'; import Breadcrumbs from '../../components/Breadcrumbs/Breadcrumbs'; @@ -129,7 +130,16 @@ const AuthorDetailPageContainer: React.FC = ({

)} {data?.get('status') && ( -

+

string }) => + id.get('schema') === 'ORCID' + ), + })} + > Status: {data?.get('status')}

)} @@ -377,10 +387,7 @@ const AuthorDetailPageContainer: React.FC = ({ Restart current step