diff --git a/package-lock.json b/package-lock.json index a4c7e98..bed88e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11734,9 +11734,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sartography-workflow-lib": { - "version": "0.0.58", - "resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.58.tgz", - "integrity": "sha512-y0TyRb0LiiLWo3uA9HV91ZIct2tIDoRBAUtwoTi2Kynj4eH0ui2Y4d/pllbC2GFKrfbmmw2NqMP8ZcsCnkuJgA==" + "version": "0.0.59", + "resolved": "https://registry.npmjs.org/sartography-workflow-lib/-/sartography-workflow-lib-0.0.59.tgz", + "integrity": "sha512-Aylrdco6fei7P4VAF+ZG+q3F3TJLkyobPmzGJDe+8vfZ5jlUJ+EffWKFV6LKCdLdkaV3oYRpo4voPnm1OvuRSA==" }, "sass": { "version": "1.23.3", diff --git a/package.json b/package.json index 54e48a2..94d1ad2 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "dmn-js-properties-panel": "^0.3.4", "file-saver": "^2.0.2", "rxjs": "~6.5.4", - "sartography-workflow-lib": "^0.0.58", + "sartography-workflow-lib": "^0.0.59", "tslib": "^1.10.0", "uuid": "^7.0.0", "zone.js": "~0.10.2" diff --git a/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.html b/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.html new file mode 100644 index 0000000..bbca394 --- /dev/null +++ b/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.html @@ -0,0 +1,14 @@ +
+

Workflow Specification

+
+ +
+
+ +
+
+ +
+ + +
diff --git a/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.scss b/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.scss new file mode 100644 index 0000000..6c284f0 --- /dev/null +++ b/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.scss @@ -0,0 +1,3 @@ +::ng-deep formly-field mat-form-field { + margin-bottom: 40px; +} diff --git a/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.spec.ts b/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.spec.ts new file mode 100644 index 0000000..ae0261a --- /dev/null +++ b/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.spec.ts @@ -0,0 +1,70 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; +import {FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {MAT_DIALOG_DATA, MatDialogModule, MatDialogRef} from '@angular/material/dialog'; +import {MatFormFieldModule} from '@angular/material/form-field'; +import {MatIconModule} from '@angular/material/icon'; +import {MatInputModule} from '@angular/material/input'; +import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations'; +import {FormlyModule} from '@ngx-formly/core'; +import {FormlyMaterialModule} from '@ngx-formly/material'; +import {mockWorkflowSpec0} from 'sartography-workflow-lib'; +import {WorkflowSpecCategoryDialogData} from '../../_interfaces/dialog-data'; +import {WorkflowSpecCategoryDialogComponent} from './workflow-spec-category-dialog.component'; + +describe('WorkflowSpecDialogComponent', () => { + let component: WorkflowSpecCategoryDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + BrowserAnimationsModule, + FormlyModule.forRoot(), + FormlyMaterialModule, + FormsModule, + MatDialogModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + NoopAnimationsModule, + ReactiveFormsModule, + ], + declarations: [WorkflowSpecCategoryDialogComponent], + providers: [ + { + provide: MatDialogRef, + useValue: { + close: (dialogResult: any) => { + } + } + }, + {provide: MAT_DIALOG_DATA, useValue: []}, + ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(WorkflowSpecCategoryDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should save data on submit', () => { + const closeSpy = spyOn(component.dialogRef, 'close').and.stub(); + const expectedData: WorkflowSpecCategoryDialogData = mockWorkflowSpec0 as WorkflowSpecCategoryDialogData; + component.model = expectedData; + component.onSubmit(); + expect(closeSpy).toHaveBeenCalledWith(expectedData); + }); + + it('should not change data on cancel', () => { + const closeSpy = spyOn(component.dialogRef, 'close').and.stub(); + component.onNoClick(); + expect(closeSpy).toHaveBeenCalledWith(); + }); +}); diff --git a/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.ts b/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.ts new file mode 100644 index 0000000..6506d61 --- /dev/null +++ b/src/app/_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component.ts @@ -0,0 +1,83 @@ +import {Component, Inject} from '@angular/core'; +import {FormGroup} from '@angular/forms'; +import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; +import {FormlyFieldConfig, FormlyFormOptions} from '@ngx-formly/core'; +import {v4 as uuidv4} from 'uuid'; +import {WorkflowSpecDialogData} from '../../_interfaces/dialog-data'; +import {toSnakeCase} from '../../_util/string-clean'; + +@Component({ + selector: 'app-workflow-spec-category-dialog', + templateUrl: './workflow-spec-category-dialog.component.html', + styleUrls: ['./workflow-spec-category-dialog.component.scss'] +}) +export class WorkflowSpecCategoryDialogComponent { + form: FormGroup = new FormGroup({}); + model: any = {}; + options: FormlyFormOptions = {}; + fields: FormlyFieldConfig[] = [ + { + key: 'id', + type: 'input', + defaultValue: this.data.id || uuidv4(), + templateOptions: { + label: 'ID', + placeholder: 'UUID of workflow specification', + description: 'This is an autogenerated unique ID and is not editable.', + required: true, + disabled: true, + }, + }, + { + key: 'name', + type: 'input', + defaultValue: this.data.name, + templateOptions: { + label: 'Name', + placeholder: 'Name of workflow specification', + description: 'Enter a name, in lowercase letters, separated by underscores, that is easy for you to remember.' + + 'It will be converted to all_lowercase_with_underscores when you save.', + required: true, + }, + }, + { + key: 'display_name', + type: 'input', + defaultValue: this.data.display_name, + templateOptions: { + label: 'Display Name', + placeholder: 'Title of the workflow specification', + description: 'This is a human readable title for the workflow specification,' + + 'which should be easy for others to read and remember.', + required: true, + }, + }, + { + key: 'description', + type: 'textarea', + defaultValue: this.data.description, + templateOptions: { + label: 'Description', + placeholder: 'Description of workflow specification', + description: 'Write a few sentences explaining to users why this workflow exists and what it should be used for.', + required: true, + }, + }, + ]; + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: WorkflowSpecDialogData, + ) { + } + + onNoClick() { + this.dialogRef.close(); + } + + onSubmit() { + this.model.name = toSnakeCase(this.model.name); + this.dialogRef.close(this.model); + } + +} diff --git a/src/app/_interfaces/dialog-data.ts b/src/app/_interfaces/dialog-data.ts index 5e84179..79b061a 100644 --- a/src/app/_interfaces/dialog-data.ts +++ b/src/app/_interfaces/dialog-data.ts @@ -20,6 +20,12 @@ export interface WorkflowSpecDialogData { description: string; } +export interface WorkflowSpecCategoryDialogData { + id: string; + name: string; + display_name: string; +} + export interface DeleteFileDialogData { confirm: boolean; fileMeta: FileMeta; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 478eca3..1b815b6 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -26,6 +26,7 @@ import {DeleteWorkflowSpecDialogComponent} from './_dialogs/delete-workflow-spec import {FileMetaDialogComponent} from './_dialogs/file-meta-dialog/file-meta-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 {WorkflowSpecCategoryDialogComponent} from './_dialogs/workflow-spec-category-dialog/workflow-spec-category-dialog.component'; import {WorkflowSpecDialogComponent} from './_dialogs/workflow-spec-dialog/workflow-spec-dialog.component'; import {EmailValidator, EmailValidatorMessage, ShowError} from './_forms/validators/formly.validator'; import {GetIconCodePipe} from './_pipes/get-icon-code.pipe'; @@ -81,6 +82,7 @@ export class AppFormlyConfig { OpenFileDialogComponent, SignInComponent, SignOutComponent, + WorkflowSpecCategoryDialogComponent, WorkflowSpecDialogComponent, WorkflowSpecListComponent, HomeComponent, @@ -116,6 +118,7 @@ export class AppFormlyConfig { FileMetaDialogComponent, NewFileDialogComponent, OpenFileDialogComponent, + WorkflowSpecCategoryDialogComponent, WorkflowSpecDialogComponent, ], providers: [ diff --git a/src/app/workflow-spec-list/workflow-spec-list.component.html b/src/app/workflow-spec-list/workflow-spec-list.component.html index a3b2a84..5a961d4 100644 --- a/src/app/workflow-spec-list/workflow-spec-list.component.html +++ b/src/app/workflow-spec-list/workflow-spec-list.component.html @@ -1,23 +1,30 @@

Workflow Specifications

- +
+ + +
-
- +
+

{{cat.display_name}}

+ -

+

{{wfs.display_name}} -

+
-

{{wfs.name}}

-

{{wfs.id}}

+

{{wfs.name}}

+
{{wfs.id}}