Performance refactor, largely around assuring that we only download files when we need the data, and using file-meta information at all other times.
Clarifying in the [open] dialog that you can open up any other file related to the current workflow.
This commit is contained in:
parent
bf9fcb533a
commit
9b40f2de2f
|
@ -7321,8 +7321,7 @@
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"inquirer": {
|
"inquirer": {
|
||||||
"version": "3.0.6",
|
"version": "3.0.6",
|
||||||
|
@ -8863,8 +8862,7 @@
|
||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
|
@ -11921,9 +11919,9 @@
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
},
|
},
|
||||||
"sartography-workflow-lib": {
|
"sartography-workflow-lib": {
|
||||||
"version": "0.0.447",
|
"version": "0.0.469",
|
||||||
"resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.447.tgz",
|
"resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.469.tgz",
|
||||||
"integrity": "sha512-xGBS1YQbXKj3O3I8bK58m7D2NApUpZUuzE3FxLTjS52Q1FL6Hgw2GY8urTJ/BF0a4ROEIHUaPm/4BN9yuzx33w=="
|
"integrity": "sha512-enqTBvU829XGjCpW7kvnWOYj4caslc86cozrCgeTqZhiJhDfzpYlBaP0BXqx+j2BQ4hXq4q12wzZmY2lZYJXDA=="
|
||||||
},
|
},
|
||||||
"sass": {
|
"sass": {
|
||||||
"version": "1.26.3",
|
"version": "1.26.3",
|
||||||
|
@ -15423,8 +15421,7 @@
|
||||||
"y18n": {
|
"y18n": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
"ngx-markdown": "^9.1.1",
|
"ngx-markdown": "^9.1.1",
|
||||||
"protractor": "^7.0.0",
|
"protractor": "^7.0.0",
|
||||||
"rxjs": "~6.5.4",
|
"rxjs": "~6.5.4",
|
||||||
"sartography-workflow-lib": "0.0.447",
|
"sartography-workflow-lib": "0.0.469",
|
||||||
"tslib": "^1.13.0",
|
"tslib": "^1.13.0",
|
||||||
"uuid": "^7.0.2",
|
"uuid": "^7.0.2",
|
||||||
"zone.js": "^0.10.3"
|
"zone.js": "^0.10.3"
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {MatInputModule} from '@angular/material/input';
|
||||||
import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations';
|
import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations';
|
||||||
import {Router} from '@angular/router';
|
import {Router} from '@angular/router';
|
||||||
import {RouterTestingModule} from '@angular/router/testing';
|
import {RouterTestingModule} from '@angular/router/testing';
|
||||||
import {ApiService, MockEnvironment, mockFileMeta0} from 'sartography-workflow-lib';
|
import {ApiService, MockEnvironment, mockFile0, mockFileMeta0} from 'sartography-workflow-lib';
|
||||||
import {OpenFileDialogData} from '../../_interfaces/dialog-data';
|
import {OpenFileDialogData} from '../../_interfaces/dialog-data';
|
||||||
|
|
||||||
import { OpenFileDialogComponent } from './open-file-dialog.component';
|
import { OpenFileDialogComponent } from './open-file-dialog.component';
|
||||||
|
@ -78,14 +78,14 @@ describe('OpenFileDialogComponent', () => {
|
||||||
|
|
||||||
it('should save data on submit', () => {
|
it('should save data on submit', () => {
|
||||||
const closeSpy = spyOn(component.dialogRef, 'close').and.stub();
|
const closeSpy = spyOn(component.dialogRef, 'close').and.stub();
|
||||||
component.data.file = mockFileMeta0.file;
|
component.data.file = mockFile0;
|
||||||
component.onSubmit();
|
component.onSubmit();
|
||||||
expect(closeSpy).toHaveBeenCalledWith(component.data);
|
expect(closeSpy).toHaveBeenCalledWith(component.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change data on cancel', () => {
|
it('should not change data on cancel', () => {
|
||||||
const closeSpy = spyOn(component.dialogRef, 'close').and.stub();
|
const closeSpy = spyOn(component.dialogRef, 'close').and.stub();
|
||||||
const expectedData: OpenFileDialogData = { file: mockFileMeta0.file };
|
const expectedData: OpenFileDialogData = { file: mockFile0 };
|
||||||
|
|
||||||
component.data.file = expectedData.file;
|
component.data.file = expectedData.file;
|
||||||
component.onNoClick();
|
component.onNoClick();
|
||||||
|
@ -111,14 +111,14 @@ describe('OpenFileDialogComponent', () => {
|
||||||
component.data.file = undefined;
|
component.data.file = undefined;
|
||||||
expect(component.getFileName()).toEqual('Click to select a file');
|
expect(component.getFileName()).toEqual('Click to select a file');
|
||||||
|
|
||||||
component.data.file = mockFileMeta0.file;
|
component.data.file = mockFile0;
|
||||||
expect(component.getFileName()).toEqual(mockFileMeta0.file.name);
|
expect(component.getFileName()).toEqual(mockFile0.name);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get a file from the file input field event', () => {
|
it('should get a file from the file input field event', () => {
|
||||||
const event = {target: {files: [mockFileMeta0.file]}};
|
const event = {target: {files: [mockFile0]}};
|
||||||
(component as any).onFileSelected(event);
|
(component as any).onFileSelected(event);
|
||||||
expect(component.data.file).toEqual(mockFileMeta0.file);
|
expect(component.data.file).toEqual(mockFile0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should determine if a string is a valid URL', () => {
|
it('should determine if a string is a valid URL', () => {
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
Primary process
|
Primary process
|
||||||
</button>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<h4 (click)="editFile(fm)" mat-line>{{fm.file.name}}</h4>
|
<h4 (click)="editFile(fm)" mat-line>{{fm.name}}</h4>
|
||||||
<p (click)="editFile(fm)" mat-line> Updated: {{fm.file.lastModified | date}}</p>
|
<p (click)="editFile(fm)" mat-line> Updated: {{fm.last_modified | date:'medium'}}</p>
|
||||||
<button (click)="downloadFile(fm)" class="mat-elevation-z0" color="primary" mat-icon-button>
|
<button (click)="downloadFile(fm)" class="mat-elevation-z0" color="primary" mat-icon-button>
|
||||||
<mat-icon>save_alt</mat-icon>
|
<mat-icon>save_alt</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -15,9 +15,9 @@ import {
|
||||||
ApiService,
|
ApiService,
|
||||||
FileMeta,
|
FileMeta,
|
||||||
FileType,
|
FileType,
|
||||||
MockEnvironment,
|
MockEnvironment, mockFile0,
|
||||||
mockFileMeta0,
|
mockFileMeta0,
|
||||||
mockFileMetas,
|
mockFileMetas, mockFiles,
|
||||||
mockWorkflowSpec0
|
mockWorkflowSpec0
|
||||||
} from 'sartography-workflow-lib';
|
} from 'sartography-workflow-lib';
|
||||||
import {DeleteFileDialogComponent} from '../_dialogs/delete-file-dialog/delete-file-dialog.component';
|
import {DeleteFileDialogComponent} from '../_dialogs/delete-file-dialog/delete-file-dialog.component';
|
||||||
|
@ -30,6 +30,9 @@ describe('FileListComponent', () => {
|
||||||
let httpMock: HttpTestingController;
|
let httpMock: HttpTestingController;
|
||||||
let component: FileListComponent;
|
let component: FileListComponent;
|
||||||
let fixture: ComponentFixture<FileListComponent>;
|
let fixture: ComponentFixture<FileListComponent>;
|
||||||
|
const timeString = '2020-01-23T12:34:12.345Z';
|
||||||
|
const timeCode = new Date(timeString).getTime();
|
||||||
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
|
@ -77,31 +80,12 @@ describe('FileListComponent', () => {
|
||||||
component.workflowSpec = mockWorkflowSpec0;
|
component.workflowSpec = mockWorkflowSpec0;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
const justFiles: File[] = [];
|
|
||||||
const fmsNoFiles: FileMeta[] = mockFileMetas.map(fm => {
|
|
||||||
justFiles.push(fm.file);
|
|
||||||
delete fm['file'];
|
|
||||||
return fm;
|
|
||||||
});
|
|
||||||
expect(justFiles.length).toEqual(mockFileMetas.length);
|
|
||||||
expect(fmsNoFiles.every(fm => !fm.file)).toEqual(true);
|
|
||||||
expect(justFiles.every(f => !!f.name)).toEqual(true);
|
|
||||||
|
|
||||||
const fmsReq = httpMock.expectOne(`apiRoot/file?workflow_spec_id=${mockWorkflowSpec0.id}`);
|
const fmsReq = httpMock.expectOne(`apiRoot/file?workflow_spec_id=${mockWorkflowSpec0.id}`);
|
||||||
expect(fmsReq.request.method).toEqual('GET');
|
expect(fmsReq.request.method).toEqual('GET');
|
||||||
fmsReq.flush(fmsNoFiles);
|
fmsReq.flush(mockFileMetas);
|
||||||
expect(component.fileMetas.length).toBeGreaterThan(0);
|
expect(component.fileMetas.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
fmsNoFiles.forEach((fm, i) => {
|
|
||||||
const fReq = httpMock.expectOne(`apiRoot/file/${fm.id}/data`);
|
|
||||||
const mockHeaders = new HttpHeaders()
|
|
||||||
.append('last-modified', justFiles[i].lastModified.toString())
|
|
||||||
.append('content-type', justFiles[i].type);
|
|
||||||
fReq.flush(new ArrayBuffer(8), {headers: mockHeaders});
|
|
||||||
|
|
||||||
expect(fReq.request.method).toEqual('GET');
|
|
||||||
expect(component.fileMetas[i].file).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -195,7 +179,7 @@ describe('FileListComponent', () => {
|
||||||
|
|
||||||
const expectedFile = new File([], mockDocMeta.name, {
|
const expectedFile = new File([], mockDocMeta.name, {
|
||||||
type: mockDocMeta.content_type,
|
type: mockDocMeta.content_type,
|
||||||
lastModified: mockDocMeta.file.lastModified
|
lastModified: timeCode
|
||||||
});
|
});
|
||||||
const fReq = httpMock.expectOne(`apiRoot/file/${mockDocMeta.id}/data`);
|
const fReq = httpMock.expectOne(`apiRoot/file/${mockDocMeta.id}/data`);
|
||||||
|
|
||||||
|
@ -215,7 +199,7 @@ describe('FileListComponent', () => {
|
||||||
|
|
||||||
it('should upload new file from file dialog', () => {
|
it('should upload new file from file dialog', () => {
|
||||||
const openDialogSpy = spyOn(component.dialog, 'open')
|
const openDialogSpy = spyOn(component.dialog, 'open')
|
||||||
.and.returnValue({afterClosed: () => of({file: mockFileMeta0.file})} as any);
|
.and.returnValue({afterClosed: () => of({file: mockFile0})} as any);
|
||||||
const _loadFileMetasSpy = spyOn((component as any), '_loadFileMetas').and.stub();
|
const _loadFileMetasSpy = spyOn((component as any), '_loadFileMetas').and.stub();
|
||||||
component.workflowSpec = mockWorkflowSpec0;
|
component.workflowSpec = mockWorkflowSpec0;
|
||||||
|
|
||||||
|
@ -230,11 +214,11 @@ describe('FileListComponent', () => {
|
||||||
|
|
||||||
it('should update existing file from file dialog', () => {
|
it('should update existing file from file dialog', () => {
|
||||||
const openDialogSpy = spyOn(component.dialog, 'open')
|
const openDialogSpy = spyOn(component.dialog, 'open')
|
||||||
.and.returnValue({afterClosed: () => of({fileMetaId: mockFileMeta0.id, file: mockFileMeta0.file})} as any);
|
.and.returnValue({afterClosed: () => of({fileMetaId: mockFileMeta0.id, file: mockFile0})} as any);
|
||||||
const _loadFileMetasSpy = spyOn((component as any), '_loadFileMetas').and.stub();
|
const _loadFileMetasSpy = spyOn((component as any), '_loadFileMetas').and.stub();
|
||||||
component.workflowSpec = mockWorkflowSpec0;
|
component.workflowSpec = mockWorkflowSpec0;
|
||||||
|
|
||||||
(component as any)._openFileDialog(mockFileMeta0, mockFileMeta0.file);
|
(component as any)._openFileDialog(mockFileMeta0, mockFile0);
|
||||||
const updateReq = httpMock.expectOne(`apiRoot/file/${mockFileMeta0.id}/data`);
|
const updateReq = httpMock.expectOne(`apiRoot/file/${mockFileMeta0.id}/data`);
|
||||||
expect(updateReq.request.method).toEqual('PUT');
|
expect(updateReq.request.method).toEqual('PUT');
|
||||||
updateReq.flush(mockFileMeta0);
|
updateReq.flush(mockFileMeta0);
|
||||||
|
@ -251,7 +235,6 @@ describe('FileListComponent', () => {
|
||||||
|
|
||||||
expect(updateFileMetaSpy).toHaveBeenCalledTimes(mockFileMetas.length);
|
expect(updateFileMetaSpy).toHaveBeenCalledTimes(mockFileMetas.length);
|
||||||
expect(component.fileMetas.length).toEqual(mockFileMetas.length);
|
expect(component.fileMetas.length).toEqual(mockFileMetas.length);
|
||||||
expect(component.fileMetas.every(fm => !!fm.file)).toEqual(true);
|
|
||||||
expect(component.fileMetas.reduce((sum, fm) => fm.primary ? sum + 1 : sum, 0)).toEqual(1);
|
expect(component.fileMetas.reduce((sum, fm) => fm.primary ? sum + 1 : sum, 0)).toEqual(1);
|
||||||
expect(_loadFileMetasSpy).toHaveBeenCalled();
|
expect(_loadFileMetasSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
|
@ -112,13 +112,12 @@ export class FileListComponent implements OnInit, OnChanges {
|
||||||
content_type: data.file.type,
|
content_type: data.file.type,
|
||||||
name: data.file.name,
|
name: data.file.name,
|
||||||
type: getFileType(data.file),
|
type: getFileType(data.file),
|
||||||
file: data.file,
|
|
||||||
workflow_spec_id: this.workflowSpec.id,
|
workflow_spec_id: this.workflowSpec.id,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isNumberDefined(data.fileMetaId)) {
|
if (isNumberDefined(data.fileMetaId)) {
|
||||||
// Update existing file
|
// Update existing file
|
||||||
this.api.updateFileData(newFileMeta).subscribe(() => {
|
this.api.updateFileData(newFileMeta, data.file).subscribe(() => {
|
||||||
this._loadFileMetas();
|
this._loadFileMetas();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -127,7 +126,7 @@ export class FileListComponent implements OnInit, OnChanges {
|
||||||
workflow_spec_id: this.workflowSpec.id,
|
workflow_spec_id: this.workflowSpec.id,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.api.addFileMeta(fileParams, newFileMeta).subscribe(dbFm => {
|
this.api.addFile(fileParams, newFileMeta, data.file).subscribe(dbFm => {
|
||||||
this._loadFileMetas();
|
this._loadFileMetas();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -146,15 +145,6 @@ export class FileListComponent implements OnInit, OnChanges {
|
||||||
private _loadFileMetas() {
|
private _loadFileMetas() {
|
||||||
this.api.getFileMetas({workflow_spec_id: this.workflowSpec.id}).subscribe(fms => {
|
this.api.getFileMetas({workflow_spec_id: this.workflowSpec.id}).subscribe(fms => {
|
||||||
this.fileMetas = fms.sort((a, b) => (a.name > b.name) ? 1 : -1);
|
this.fileMetas = fms.sort((a, b) => (a.name > b.name) ? 1 : -1);
|
||||||
this._loadFileData();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private _loadFileData() {
|
|
||||||
this.fileMetas.forEach(fm => {
|
|
||||||
this.api.getFileData(fm.id).subscribe(response => {
|
|
||||||
fm.file = newFileFromResponse(fm, response);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<mat-menu #importMenu="matMenu">
|
<mat-menu #importMenu="matMenu">
|
||||||
<button mat-menu-item (click)="openMethod = 'db'" [matMenuTriggerFor]="dbMenu" title="Open diagram from database">
|
<button mat-menu-item (click)="openMethod = 'db'" [matMenuTriggerFor]="dbMenu" title="Open diagram from database">
|
||||||
<mat-icon>cloud</mat-icon>
|
<mat-icon>cloud</mat-icon>
|
||||||
Open previously saved...
|
Open related BPMN/DMN File ...
|
||||||
</button>
|
</button>
|
||||||
<mat-menu #dbMenu="matMenu">
|
<mat-menu #dbMenu="matMenu">
|
||||||
<a
|
<a
|
||||||
|
|
|
@ -24,12 +24,13 @@ import {
|
||||||
FileMeta,
|
FileMeta,
|
||||||
FileType,
|
FileType,
|
||||||
MockEnvironment,
|
MockEnvironment,
|
||||||
|
mockFile0,
|
||||||
mockFileMeta0,
|
mockFileMeta0,
|
||||||
mockFileMetas,
|
mockFileMetas,
|
||||||
mockWorkflowSpec0,
|
mockWorkflowSpec0,
|
||||||
mockWorkflowSpecs
|
mockWorkflowSpecs
|
||||||
} from 'sartography-workflow-lib';
|
} from 'sartography-workflow-lib';
|
||||||
import {BPMN_DIAGRAM, BPMN_DIAGRAM_EMPTY, BPMN_DIAGRAM_WITH_WARNINGS} from '../../testing/mocks/diagram.mocks';
|
import {BPMN_DIAGRAM, BPMN_DIAGRAM_EMPTY} from '../../testing/mocks/diagram.mocks';
|
||||||
import {FileMetaDialogComponent} from '../_dialogs/file-meta-dialog/file-meta-dialog.component';
|
import {FileMetaDialogComponent} from '../_dialogs/file-meta-dialog/file-meta-dialog.component';
|
||||||
import {NewFileDialogComponent} from '../_dialogs/new-file-dialog/new-file-dialog.component';
|
import {NewFileDialogComponent} from '../_dialogs/new-file-dialog/new-file-dialog.component';
|
||||||
import {OpenFileDialogComponent} from '../_dialogs/open-file-dialog/open-file-dialog.component';
|
import {OpenFileDialogComponent} from '../_dialogs/open-file-dialog/open-file-dialog.component';
|
||||||
|
@ -132,14 +133,10 @@ describe('ModelerComponent', () => {
|
||||||
expect(req.request.method).toEqual('GET');
|
expect(req.request.method).toEqual('GET');
|
||||||
req.flush(mockFileMetas);
|
req.flush(mockFileMetas);
|
||||||
|
|
||||||
mockFileMetas.forEach((fm, i) => {
|
const fmReq = httpMock.expectOne(`apiRoot/file/${mockFileMeta0.id}/data`);
|
||||||
const fmReq = httpMock.expectOne(`apiRoot/file/${fm.id}/data`);
|
|
||||||
const mockHeaders = new HttpHeaders()
|
|
||||||
.append('last-modified', mockFileMetas[i].file.lastModified.toString())
|
|
||||||
.append('content-type', mockFileMetas[i].content_type);
|
|
||||||
expect(fmReq.request.method).toEqual('GET');
|
|
||||||
fmReq.flush(new ArrayBuffer(8), {headers: mockHeaders});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -225,8 +222,8 @@ describe('ModelerComponent', () => {
|
||||||
it('should get the diagram file name', () => {
|
it('should get the diagram file name', () => {
|
||||||
expect(component.getFileName()).toEqual(mockFileMeta0.name);
|
expect(component.getFileName()).toEqual(mockFileMeta0.name);
|
||||||
|
|
||||||
const filename = 'expected_file_name.jpg';
|
const filename = 'one-fish.bpmn';
|
||||||
component.diagramFile = new File([], filename, {type: 'image/jpeg'});
|
component.diagramFileMeta.name = filename;
|
||||||
expect(component.getFileName()).toEqual(filename);
|
expect(component.getFileName()).toEqual(filename);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -291,7 +288,7 @@ describe('ModelerComponent', () => {
|
||||||
component.diagramComponent.writeValue(BPMN_DIAGRAM_EMPTY.replace(/REPLACE_ME/g, 'cream_colored_ponies'));
|
component.diagramComponent.writeValue(BPMN_DIAGRAM_EMPTY.replace(/REPLACE_ME/g, 'cream_colored_ponies'));
|
||||||
component.saveFileChanges();
|
component.saveFileChanges();
|
||||||
|
|
||||||
expect(updateFileDataSpy).toHaveBeenCalledWith(mockFileMeta0);
|
expect(updateFileDataSpy).toHaveBeenCalledWith(mockFileMeta0, mockFile0);
|
||||||
expect(snackBarOpenSpy).toHaveBeenCalled();
|
expect(snackBarOpenSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -318,12 +315,11 @@ describe('ModelerComponent', () => {
|
||||||
const updateFileMetaSpy = spyOn(component.api, 'updateFileMeta')
|
const updateFileMetaSpy = spyOn(component.api, 'updateFileMeta')
|
||||||
.and.returnValue(of(mockFileMeta0));
|
.and.returnValue(of(mockFileMeta0));
|
||||||
const updateFileDataSpy = spyOn(component.api, 'updateFileData')
|
const updateFileDataSpy = spyOn(component.api, 'updateFileData')
|
||||||
.and.returnValue(of(mockFileMeta0.file));
|
.and.returnValue(of(mockFile0));
|
||||||
const loadFilesFromDbSpy = spyOn(component, 'loadFilesFromDb').and.stub();
|
const loadFilesFromDbSpy = spyOn(component, 'loadFilesFromDb').and.stub();
|
||||||
const snackBarSpy = spyOn(component.snackBar, 'open').and.stub();
|
const snackBarSpy = spyOn(component.snackBar, 'open').and.stub();
|
||||||
const noDateOrVersion: FileMeta = {
|
const noDateOrVersion: FileMeta = {
|
||||||
content_type: mockFileMeta0.content_type,
|
content_type: mockFileMeta0.content_type,
|
||||||
file: mockFileMeta0.file,
|
|
||||||
id: mockFileMeta0.id,
|
id: mockFileMeta0.id,
|
||||||
name: mockFileMeta0.name,
|
name: mockFileMeta0.name,
|
||||||
type: mockFileMeta0.type,
|
type: mockFileMeta0.type,
|
||||||
|
@ -334,7 +330,7 @@ describe('ModelerComponent', () => {
|
||||||
component._upsertFileMeta(data);
|
component._upsertFileMeta(data);
|
||||||
expect(component.xml).toEqual(newXml);
|
expect(component.xml).toEqual(newXml);
|
||||||
expect(updateFileMetaSpy).toHaveBeenCalledWith(noDateOrVersion);
|
expect(updateFileMetaSpy).toHaveBeenCalledWith(noDateOrVersion);
|
||||||
expect(updateFileDataSpy).toHaveBeenCalledWith(noDateOrVersion);
|
expect(updateFileDataSpy).toHaveBeenCalledWith(noDateOrVersion, mockFile0);
|
||||||
expect(loadFilesFromDbSpy).toHaveBeenCalled();
|
expect(loadFilesFromDbSpy).toHaveBeenCalled();
|
||||||
expect(snackBarSpy).toHaveBeenCalled();
|
expect(snackBarSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
@ -349,13 +345,12 @@ describe('ModelerComponent', () => {
|
||||||
const noDateOrVersion: FileMeta = {
|
const noDateOrVersion: FileMeta = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
content_type: mockFileMeta0.content_type,
|
content_type: mockFileMeta0.content_type,
|
||||||
file: mockFileMeta0.file,
|
|
||||||
name: mockFileMeta0.name,
|
name: mockFileMeta0.name,
|
||||||
type: mockFileMeta0.type,
|
type: mockFileMeta0.type,
|
||||||
workflow_spec_id: mockFileMeta0.workflow_spec_id,
|
workflow_spec_id: mockFileMeta0.workflow_spec_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
const addFileMetaSpy = spyOn(component.api, 'addFileMeta')
|
const addFileMetaSpy = spyOn(component.api, 'addFile')
|
||||||
.and.returnValue(of(mockFileMeta0));
|
.and.returnValue(of(mockFileMeta0));
|
||||||
const loadFilesFromDbSpy = spyOn(component, 'loadFilesFromDb').and.stub();
|
const loadFilesFromDbSpy = spyOn(component, 'loadFilesFromDb').and.stub();
|
||||||
const routerNavigateSpy = spyOn(component.router, 'navigate').and.stub();
|
const routerNavigateSpy = spyOn(component.router, 'navigate').and.stub();
|
||||||
|
@ -367,7 +362,7 @@ describe('ModelerComponent', () => {
|
||||||
component.draftXml = newXml;
|
component.draftXml = newXml;
|
||||||
component._upsertFileMeta(data);
|
component._upsertFileMeta(data);
|
||||||
expect(component.xml).toEqual(newXml);
|
expect(component.xml).toEqual(newXml);
|
||||||
expect(addFileMetaSpy).toHaveBeenCalledWith({workflow_spec_id: mockWorkflowSpec0.id}, noDateOrVersion);
|
expect(addFileMetaSpy).toHaveBeenCalledWith({workflow_spec_id: mockWorkflowSpec0.id}, noDateOrVersion, mockFile0);
|
||||||
expect(loadFilesFromDbSpy).not.toHaveBeenCalled();
|
expect(loadFilesFromDbSpy).not.toHaveBeenCalled();
|
||||||
expect(routerNavigateSpy).toHaveBeenCalled();
|
expect(routerNavigateSpy).toHaveBeenCalled();
|
||||||
expect(snackBarSpy).toHaveBeenCalled();
|
expect(snackBarSpy).toHaveBeenCalled();
|
||||||
|
@ -375,7 +370,7 @@ describe('ModelerComponent', () => {
|
||||||
|
|
||||||
it('should load files from the database', () => {
|
it('should load files from the database', () => {
|
||||||
const mockHeaders = new HttpHeaders()
|
const mockHeaders = new HttpHeaders()
|
||||||
.append('last-modified', mockFileMeta0.file.lastModified.toString())
|
.append('last-modified', mockFileMeta0.last_modified.toString())
|
||||||
.append('content-type', mockFileMeta0.content_type);
|
.append('content-type', mockFileMeta0.content_type);
|
||||||
const mockResponse = new HttpResponse<ArrayBuffer>({
|
const mockResponse = new HttpResponse<ArrayBuffer>({
|
||||||
body: new ArrayBuffer(8),
|
body: new ArrayBuffer(8),
|
||||||
|
@ -394,9 +389,6 @@ describe('ModelerComponent', () => {
|
||||||
expect(component.workflowSpec).toEqual(mockWorkflowSpec0);
|
expect(component.workflowSpec).toEqual(mockWorkflowSpec0);
|
||||||
expect(getFileMetasSpy).toHaveBeenCalledWith({workflow_spec_id: mockWorkflowSpec0.id});
|
expect(getFileMetasSpy).toHaveBeenCalledWith({workflow_spec_id: mockWorkflowSpec0.id});
|
||||||
|
|
||||||
mockFileMetas.forEach(fm => {
|
|
||||||
expect(getFileDataSpy).toHaveBeenCalledWith(fm.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(component.bpmnFiles.length).toEqual(mockFileMetas.length);
|
expect(component.bpmnFiles.length).toEqual(mockFileMetas.length);
|
||||||
});
|
});
|
||||||
|
@ -404,8 +396,8 @@ describe('ModelerComponent', () => {
|
||||||
it('should load a database file', () => {
|
it('should load a database file', () => {
|
||||||
const onSubmitFileToOpenSpy = spyOn(component, 'onSubmitFileToOpen').and.stub();
|
const onSubmitFileToOpenSpy = spyOn(component, 'onSubmitFileToOpen').and.stub();
|
||||||
component.workflowSpecs = mockWorkflowSpecs;
|
component.workflowSpecs = mockWorkflowSpecs;
|
||||||
component.loadDbFile(mockFileMeta0);
|
component.loadDbFile(mockFileMeta0, mockFile0);
|
||||||
expect(component.diagramFile).toEqual(mockFileMeta0.file);
|
expect(component.diagramFile).toEqual(mockFile0);
|
||||||
expect(component.diagramFileMeta).toEqual(mockFileMeta0);
|
expect(component.diagramFileMeta).toEqual(mockFileMeta0);
|
||||||
expect(component.workflowSpec).toEqual(mockWorkflowSpec0);
|
expect(component.workflowSpec).toEqual(mockWorkflowSpec0);
|
||||||
expect(onSubmitFileToOpenSpy).toHaveBeenCalled();
|
expect(onSubmitFileToOpenSpy).toHaveBeenCalled();
|
||||||
|
@ -415,7 +407,7 @@ describe('ModelerComponent', () => {
|
||||||
component.xml = BPMN_DIAGRAM_EMPTY.replace(/REPLACE_ME/g, 'sleigh_bells');
|
component.xml = BPMN_DIAGRAM_EMPTY.replace(/REPLACE_ME/g, 'sleigh_bells');
|
||||||
component.draftXml = BPMN_DIAGRAM_EMPTY.replace(/REPLACE_ME/g, 'schnitzel_with_noodles');
|
component.draftXml = BPMN_DIAGRAM_EMPTY.replace(/REPLACE_ME/g, 'schnitzel_with_noodles');
|
||||||
component.diagramFileMeta = mockFileMeta0;
|
component.diagramFileMeta = mockFileMeta0;
|
||||||
component.diagramFile = mockFileMeta0.file;
|
component.diagramFile = mockFile0;
|
||||||
component.workflowSpec = mockWorkflowSpec0;
|
component.workflowSpec = mockWorkflowSpec0;
|
||||||
component.newDiagram();
|
component.newDiagram();
|
||||||
|
|
||||||
|
@ -430,13 +422,9 @@ describe('ModelerComponent', () => {
|
||||||
|
|
||||||
it('should get a file metadata display string', () => {
|
it('should get a file metadata display string', () => {
|
||||||
expect(component.getFileMetaDisplayString(undefined)).toEqual('Loading...');
|
expect(component.getFileMetaDisplayString(undefined)).toEqual('Loading...');
|
||||||
const expectedString = 'one-fish.bpmn - v1.0 (Jan 23, 2020)';
|
const expectedString = 'one-fish.bpmn';
|
||||||
|
mockFileMeta0.type = FileType.BPMN;
|
||||||
const file = new File([], 'one-fish.bpmn', {
|
mockFileMeta0.last_modified = '2020-01-23T12:34:12.345Z';
|
||||||
type: 'text/xml',
|
|
||||||
lastModified: new Date('2020-01-23T12:34:12.345Z').getTime(),
|
|
||||||
});
|
|
||||||
mockFileMeta0.file = file;
|
|
||||||
expect(component.getFileMetaDisplayString(mockFileMeta0)).toEqual(expectedString);
|
expect(component.getFileMetaDisplayString(mockFileMeta0)).toEqual(expectedString);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -446,20 +434,12 @@ describe('ModelerComponent', () => {
|
||||||
|
|
||||||
component.workflowSpec = mockWorkflowSpec0;
|
component.workflowSpec = mockWorkflowSpec0;
|
||||||
const expectedString = `
|
const expectedString = `
|
||||||
Workflow spec ID: all_things
|
|
||||||
Workflow name: all_things
|
|
||||||
Display name: Everything
|
|
||||||
Description: Do all the things
|
|
||||||
File name: one-fish.bpmn
|
File name: one-fish.bpmn
|
||||||
Last updated: Jan 23, 2020
|
Last updated: Jan 23, 2020, 7:34:12 AM
|
||||||
Version: 1.0
|
Version: 1.0
|
||||||
`;
|
`;
|
||||||
|
mockFileMeta0.type = FileType.BPMN;
|
||||||
const file = new File([], 'one-fish.bpmn', {
|
mockFileMeta0.last_modified = '2020-01-23T12:34:12.345Z';
|
||||||
type: 'text/xml',
|
|
||||||
lastModified: new Date('2020-01-23T12:34:12.345Z').getTime(),
|
|
||||||
});
|
|
||||||
mockFileMeta0.file = file;
|
|
||||||
expect(component.getFileMetaTooltipText(mockFileMeta0)).toEqual(expectedString);
|
expect(component.getFileMetaTooltipText(mockFileMeta0)).toEqual(expectedString);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -478,7 +458,7 @@ describe('ModelerComponent', () => {
|
||||||
|
|
||||||
it('should display open file dialog', () => {
|
it('should display open file dialog', () => {
|
||||||
const data: OpenFileDialogData = {
|
const data: OpenFileDialogData = {
|
||||||
file: mockFileMeta0.file
|
file: mockFile0
|
||||||
};
|
};
|
||||||
const expectedFile = new File([], mockFileMeta0.name, {type: mockFileMeta0.content_type});
|
const expectedFile = new File([], mockFileMeta0.name, {type: mockFileMeta0.content_type});
|
||||||
const event = {target: {files: [expectedFile]}};
|
const event = {target: {files: [expectedFile]}};
|
||||||
|
|
|
@ -139,7 +139,8 @@ export class ModelerComponent implements AfterViewInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
getFileName() {
|
getFileName() {
|
||||||
return this.diagramFile ? this.diagramFile.name : this.fileName || 'No file selected';
|
// return this.diagramFile ? this.diagramFile.name : this.fileName || 'No file selected';
|
||||||
|
return this.diagramFileMeta ? this.diagramFileMeta.name : this.fileName || 'No file selected';
|
||||||
}
|
}
|
||||||
|
|
||||||
checkSaved() {
|
checkSaved() {
|
||||||
|
@ -206,8 +207,8 @@ export class ModelerComponent implements AfterViewInit {
|
||||||
return (this.xml !== this.draftXml) || this.isNew;
|
return (this.xml !== this.draftXml) || this.isNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDbFile(bf: FileMeta) {
|
loadDbFile(bf: FileMeta, f: File) {
|
||||||
this.diagramFile = bf.file;
|
this.diagramFile = f;
|
||||||
this.diagramFileMeta = bf;
|
this.diagramFileMeta = bf;
|
||||||
this.onSubmitFileToOpen();
|
this.onSubmitFileToOpen();
|
||||||
}
|
}
|
||||||
|
@ -263,10 +264,7 @@ export class ModelerComponent implements AfterViewInit {
|
||||||
|
|
||||||
getFileMetaDisplayString(fileMeta: FileMeta) {
|
getFileMetaDisplayString(fileMeta: FileMeta) {
|
||||||
if (fileMeta) {
|
if (fileMeta) {
|
||||||
const lastUpdated = new DatePipe('en-us').transform(fileMeta.file.lastModified);
|
return fileMeta.name;
|
||||||
return fileMeta.name +
|
|
||||||
(fileMeta.latest_version ? ` - v${fileMeta.latest_version}` : '') +
|
|
||||||
(lastUpdated ? ` (${lastUpdated})` : '');
|
|
||||||
} else {
|
} else {
|
||||||
return 'Loading...';
|
return 'Loading...';
|
||||||
}
|
}
|
||||||
|
@ -276,13 +274,9 @@ export class ModelerComponent implements AfterViewInit {
|
||||||
const spec = this.workflowSpec;
|
const spec = this.workflowSpec;
|
||||||
|
|
||||||
if (spec) {
|
if (spec) {
|
||||||
const lastUpdatedDate = new Date(fileMeta.file.lastModified);
|
const lastUpdatedDate = new Date(fileMeta.last_modified);
|
||||||
const lastUpdated = new DatePipe('en-us').transform(lastUpdatedDate);
|
const lastUpdated = new DatePipe('en-us').transform(lastUpdatedDate, 'medium');
|
||||||
return `
|
return `
|
||||||
Workflow spec ID: ${spec.id}
|
|
||||||
Workflow name: ${spec.name}
|
|
||||||
Display name: ${spec.display_name}
|
|
||||||
Description: ${spec.description}
|
|
||||||
File name: ${fileMeta.name}
|
File name: ${fileMeta.name}
|
||||||
Last updated: ${lastUpdated}
|
Last updated: ${lastUpdated}
|
||||||
Version: ${fileMeta.latest_version}
|
Version: ${fileMeta.latest_version}
|
||||||
|
@ -298,19 +292,18 @@ export class ModelerComponent implements AfterViewInit {
|
||||||
this.api.getFileMetas({workflow_spec_id: wfs.id}).subscribe(files => {
|
this.api.getFileMetas({workflow_spec_id: wfs.id}).subscribe(files => {
|
||||||
this.bpmnFiles = [];
|
this.bpmnFiles = [];
|
||||||
files.forEach(f => {
|
files.forEach(f => {
|
||||||
this.api.getFileData(f.id).subscribe(response => {
|
if ((f.type === FileType.BPMN) || (f.type === FileType.DMN)) {
|
||||||
if ((f.type === FileType.BPMN) || (f.type === FileType.DMN)) {
|
f.content_type = 'text/xml';
|
||||||
f.content_type = 'text/xml';
|
this.bpmnFiles.push(f);
|
||||||
f.file = newFileFromResponse(f, response);
|
|
||||||
this.bpmnFiles.push(f);
|
|
||||||
|
|
||||||
if (f.id === this.fileMetaId) {
|
if (f.id === this.fileMetaId) {
|
||||||
this.diagramFileMeta = f;
|
this.diagramFileMeta = f;
|
||||||
this.diagramFile = f.file;
|
this.api.getFileData(f.id).subscribe(response => {
|
||||||
|
this.diagramFile = newFileFromResponse(f, response);
|
||||||
this.onSubmitFileToOpen();
|
this.onSubmitFileToOpen();
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -326,13 +319,14 @@ export class ModelerComponent implements AfterViewInit {
|
||||||
content_type: 'text/xml',
|
content_type: 'text/xml',
|
||||||
name: data.fileName,
|
name: data.fileName,
|
||||||
type: fileType,
|
type: fileType,
|
||||||
file: new File([this.xml], data.fileName, {type: 'text/xml'}),
|
|
||||||
workflow_spec_id: this.workflowSpec.id,
|
workflow_spec_id: this.workflowSpec.id,
|
||||||
};
|
};
|
||||||
|
this.diagramFile = new File([this.xml], data.fileName, {type: 'text/xml'});
|
||||||
|
|
||||||
|
|
||||||
if (this.workflowSpec && isNumberDefined(fileMetaId)) {
|
if (this.workflowSpec && isNumberDefined(fileMetaId)) {
|
||||||
// Update existing file meta
|
// Update existing file meta
|
||||||
this.api.updateFileData(this.diagramFileMeta).subscribe(() => {
|
this.api.updateFileData(this.diagramFileMeta, this.diagramFile).subscribe(() => {
|
||||||
this.api.updateFileMeta(this.diagramFileMeta).subscribe(() => {
|
this.api.updateFileMeta(this.diagramFileMeta).subscribe(() => {
|
||||||
this.loadFilesFromDb();
|
this.loadFilesFromDb();
|
||||||
this.snackBar.open(`Saved changes to file ${this.diagramFileMeta.name}.`, 'Ok', {duration: 5000});
|
this.snackBar.open(`Saved changes to file ${this.diagramFileMeta.name}.`, 'Ok', {duration: 5000});
|
||||||
|
@ -340,7 +334,7 @@ export class ModelerComponent implements AfterViewInit {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Add new file meta
|
// Add new file meta
|
||||||
this.api.addFileMeta({workflow_spec_id: this.workflowSpec.id}, this.diagramFileMeta).subscribe(fileMeta => {
|
this.api.addFile({workflow_spec_id: this.workflowSpec.id}, this.diagramFileMeta, this.diagramFile).subscribe(fileMeta => {
|
||||||
this.router.navigate(['/modeler', this.workflowSpec.id, fileMeta.id]);
|
this.router.navigate(['/modeler', this.workflowSpec.id, fileMeta.id]);
|
||||||
this.snackBar.open(`Saved new file ${fileMeta.name} to workflow spec ${this.workflowSpec.name}.`, 'Ok', {duration: 5000});
|
this.snackBar.open(`Saved new file ${fileMeta.name} to workflow spec ${this.workflowSpec.name}.`, 'Ok', {duration: 5000});
|
||||||
}, () => {
|
}, () => {
|
||||||
|
@ -355,7 +349,7 @@ export class ModelerComponent implements AfterViewInit {
|
||||||
|
|
||||||
private saveFileChanges() {
|
private saveFileChanges() {
|
||||||
this.xml = this.draftXml;
|
this.xml = this.draftXml;
|
||||||
this.diagramFileMeta.file = new File([this.xml], this.diagramFileMeta.name, {type: 'text/xml'});
|
this.diagramFile = new File([this.xml], this.diagramFileMeta.name, {type: 'text/xml'});
|
||||||
|
|
||||||
// Propose removal
|
// Propose removal
|
||||||
// if (this.svg && this.svg !== '') {
|
// if (this.svg && this.svg !== '') {
|
||||||
|
@ -363,7 +357,7 @@ export class ModelerComponent implements AfterViewInit {
|
||||||
// // this.api.updateFileData();
|
// // this.api.updateFileData();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
this.api.updateFileData(this.diagramFileMeta).subscribe(newFileMeta => {
|
this.api.updateFileData(this.diagramFileMeta, this.diagramFile).subscribe(newFileMeta => {
|
||||||
this.diagramFileMeta = newFileMeta;
|
this.diagramFileMeta = newFileMeta;
|
||||||
this.snackBar.open(`Saved changes to file metadata ${this.diagramFileMeta.name}.`, 'Ok', {duration: 5000});
|
this.snackBar.open(`Saved changes to file metadata ${this.diagramFileMeta.name}.`, 'Ok', {duration: 5000});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {RouterTestingModule} from '@angular/router/testing';
|
||||||
import * as FileSaver from 'file-saver';
|
import * as FileSaver from 'file-saver';
|
||||||
import createClone from 'rfdc';
|
import createClone from 'rfdc';
|
||||||
import {of} from 'rxjs';
|
import {of} from 'rxjs';
|
||||||
import {ApiService, FileMeta, FileType, MockEnvironment, mockFileMetaReference0} from 'sartography-workflow-lib';
|
import {ApiService, FileMeta, FileType, MockEnvironment, mockFileMetaReference0, mockFileReference0} from 'sartography-workflow-lib';
|
||||||
import {OpenFileDialogComponent} from '../_dialogs/open-file-dialog/open-file-dialog.component';
|
import {OpenFileDialogComponent} from '../_dialogs/open-file-dialog/open-file-dialog.component';
|
||||||
import {ReferenceFilesComponent} from './reference-files.component';
|
import {ReferenceFilesComponent} from './reference-files.component';
|
||||||
|
|
||||||
|
@ -26,9 +26,12 @@ describe('ReferenceFilesComponent', () => {
|
||||||
const mockDocMeta: FileMeta = createClone()(mockFileMetaReference0);
|
const mockDocMeta: FileMeta = createClone()(mockFileMetaReference0);
|
||||||
mockDocMeta.type = FileType.XLSX;
|
mockDocMeta.type = FileType.XLSX;
|
||||||
|
|
||||||
|
const timeString = '2020-01-23T12:34:12.345Z';
|
||||||
|
const timeCode = new Date(timeString).getTime();
|
||||||
|
|
||||||
const expectedFile = new File([], mockDocMeta.name, {
|
const expectedFile = new File([], mockDocMeta.name, {
|
||||||
type: mockDocMeta.content_type,
|
type: mockDocMeta.content_type,
|
||||||
lastModified: mockDocMeta.file.lastModified
|
lastModified: timeCode
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockHeaders = new HttpHeaders()
|
const mockHeaders = new HttpHeaders()
|
||||||
|
@ -101,7 +104,7 @@ describe('ReferenceFilesComponent', () => {
|
||||||
.and.returnValue({
|
.and.returnValue({
|
||||||
afterClosed: () => of({
|
afterClosed: () => of({
|
||||||
fileMetaId: mockFileMetaReference0.id,
|
fileMetaId: mockFileMetaReference0.id,
|
||||||
file: mockFileMetaReference0.file
|
file: mockFileReference0
|
||||||
})
|
})
|
||||||
} as any);
|
} as any);
|
||||||
const _loadReferenceFilesSpy = spyOn((component as any), '_loadReferenceFiles').and.stub();
|
const _loadReferenceFilesSpy = spyOn((component as any), '_loadReferenceFiles').and.stub();
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
<div *ngIf="!(searchField.value && cat.workflow_specs.length === 0)">
|
<div *ngIf="!(searchField.value && cat.workflow_specs.length === 0)">
|
||||||
<ng-container *ngIf="!(cat.id === null && cat.workflow_specs.length === 0)">
|
<ng-container *ngIf="!(cat.id === null && cat.workflow_specs.length === 0)">
|
||||||
<mat-expansion-panel hideToggle (opened)="selectCat(cat)" [expanded]="selectedSpec.category_id == cat.id">
|
<mat-expansion-panel hideToggle (opened)="selectCat(cat)" [expanded]="isSelected(cat)">
|
||||||
<mat-expansion-panel-header>
|
<mat-expansion-panel-header>
|
||||||
<mat-panel-title>
|
<mat-panel-title>
|
||||||
{{cat.display_name}}
|
{{cat.display_name}}
|
||||||
|
|
|
@ -91,6 +91,10 @@ export class WorkflowSpecListComponent implements OnInit {
|
||||||
this.selectedCat = selectedCat;
|
this.selectedCat = selectedCat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isSelected(cat: WorkflowSpecCategory) {
|
||||||
|
return this.selectedCat && this.selectedCat === cat;
|
||||||
|
}
|
||||||
|
|
||||||
selectSpec(selectedSpec?: WorkflowSpec) {
|
selectSpec(selectedSpec?: WorkflowSpec) {
|
||||||
this.selectedSpec = selectedSpec;
|
this.selectedSpec = selectedSpec;
|
||||||
this.location.replaceState(environment.homeRoute + '/' + selectedSpec.name);
|
this.location.replaceState(environment.homeRoute + '/' + selectedSpec.name);
|
||||||
|
|
Loading…
Reference in New Issue