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