File

src/app/tasks/task-definition-create/task-definition-create.component.ts

Description

Component handling a creation of a composed task.

Implements

OnInit OnDestroy

Example

Metadata

encapsulation ViewEncapsulation.None
selector app-task-definitin-create
styleUrls .../shared/flo/flo.scss
templateUrl ./task-definition-create.component.html

Index

Properties
Methods
HostListeners
Accessors

Constructor

constructor(metamodelService: MetamodelService, renderService: RenderService, editorService: EditorService, renderer: Renderer2, notificationService: NotificationService, bsModalService: BsModalService, toolsService: ToolsService, loggerService: LoggerService, router: Router)
Parameters :
Name Type Optional Description
metamodelService MetamodelService
renderService RenderService
editorService EditorService
renderer Renderer2
notificationService NotificationService
bsModalService BsModalService
toolsService ToolsService
loggerService LoggerService
router Router

HostListeners

window:resize
Arguments : '$event'
window:resize(event: )

Methods

arrangeAll
arrangeAll()
Returns : void
clearGraph
clearGraph()
Returns : void
createTaskDefs
createTaskDefs()
Returns : void
lint
lint(dsl: string, updateLintingCallback: CodeMirror.UpdateLintingCallback, editor: CodeMirror.Editor)
Parameters :
Name Type Optional Description
dsl string
updateLintingCallback CodeMirror.UpdateLintingCallback
editor CodeMirror.Editor
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
resizeFloGraph
resizeFloGraph(height?: number)
Parameters :
Name Type Optional Description
height number true
Returns : void
setEditorContext
setEditorContext(editorContext: Flo.EditorContext)
Parameters :
Name Type Optional Description
editorContext Flo.EditorContext
Returns : void

Properties

contentValidated
contentValidated:
Default value : false
dsl
dsl: string
Type : string
editorContext
editorContext: Flo.EditorContext
Type : Flo.EditorContext
Public editorService
editorService: EditorService
Type : EditorService
flo
flo:
Decorators : ViewChild
initSubject
initSubject: Subject<void>
Type : Subject<void>
lintOptions
lintOptions: CodeMirror.LintOptions
Type : CodeMirror.LintOptions
Public metamodelService
metamodelService: MetamodelService
Type : MetamodelService
paletteSize
paletteSize:
Default value : 310
parseErrors
parseErrors: any[]
Type : any[]
Public renderService
renderService: RenderService
Type : RenderService
validationMarkers
validationMarkers: Map<string | []>
Type : Map<string | []>

Accessors

isCreateComposedTaskDisabled
getisCreateComposedTaskDisabled()
Returns : boolean
gridOn
getgridOn()
Returns : boolean
setgridOn(on: boolean)
Parameters :
Name Type Optional Description
on boolean
Returns : void
import { Component, HostListener, OnDestroy, OnInit, Renderer2, ViewChild, ViewEncapsulation } from '@angular/core';
import { EditorComponent, Flo } from 'spring-flo';
import { Subject, Subscription } from 'rxjs';
import { BsModalService } from 'ngx-bootstrap';
import { MetamodelService } from '../components/flo/metamodel.service';
import { RenderService } from '../components/flo/render.service';
import { EditorService } from '../components/flo/editor.service';
import * as CodeMirror from 'codemirror';
import { ToolsService } from '../components/flo/tools.service';
import { TaskDefinitionCreateDialogComponent } from './create-dialog/create-dialog.component';
import { Router } from '@angular/router';
import { LoggerService } from '../../shared/services/logger.service';
import { arrangeAll } from '../components/flo/support/layout';
import { NotificationService } from '../../shared/services/notification.service';

/**
 * Component handling a creation of a composed task.
 *
 * @author Janne Valkealahti
 */
@Component({
  selector: 'app-task-definitin-create',
  templateUrl: './task-definition-create.component.html',
  styleUrls: ['../../shared/flo/flo.scss'],
  encapsulation: ViewEncapsulation.None
})
export class TaskDefinitionCreateComponent implements OnInit, OnDestroy {

  dsl: string;
  paletteSize = 310;
  editorContext: Flo.EditorContext;

  contentValidated = false;
  lintOptions: CodeMirror.LintOptions;
  validationMarkers: Map<string, Flo.Marker[]>;
  parseErrors: any[];

  initSubject: Subject<void>;

  @ViewChild(EditorComponent, { static: true }) flo;

  constructor(public metamodelService: MetamodelService,
              public renderService: RenderService,
              public editorService: EditorService,
              private renderer: Renderer2,
              private notificationService: NotificationService,
              private bsModalService: BsModalService,
              private toolsService: ToolsService,
              private loggerService: LoggerService,
              private router: Router) {

    this.validationMarkers = new Map();
    this.parseErrors = [];

    this.lintOptions = {
      async: true,
      hasGutters: true,
      getAnnotations: (content: string,
                       updateLintingCallback: CodeMirror.UpdateLintingCallback,
                       options: CodeMirror.LintStateOptions,
                       editor: CodeMirror.Editor) => this.lint(content, updateLintingCallback, editor)
    };

    this.initSubject = new Subject();
    this.initSubject.subscribe();
  }

  ngOnInit() {
    this.resizeFloGraph();
  }

  ngOnDestroy() {
    // Invalidate cached metamodel, thus it's reloaded next time page is opened
    this.metamodelService.clearCachedData();
  }

  @HostListener('window:resize', ['$event'])
  onResize(event) {
    this.resizeFloGraph();
  }

  resizeFloGraph(height?: number) {
    const viewEditor = this.flo.element.nativeElement.children[2];
    if (height) {
      height = height - 330;
    } else {
      height = document.documentElement.clientHeight - 330;
    }
    this.renderer.setStyle(viewEditor, 'height', `${Math.max(height, 300)}px`);
  }

  setEditorContext(editorContext: Flo.EditorContext) {
    this.editorContext = editorContext;
    if (this.editorContext) {
      const subscription = this.editorContext.paletteReady.subscribe(ready => {
        if (ready) {
          subscription.unsubscribe();
          this.initSubject.next();
          this.initSubject.complete();
        }
      });
    }
  }

  arrangeAll() {
    arrangeAll(this.editorContext);
  }

  clearGraph() {
    this.editorContext.clearGraph();
  }

  createTaskDefs() {
    if (this.isCreateComposedTaskDisabled) {
      this.notificationService.error('Some field(s) are missing or invalid.');
    } else {
      this.loggerService.log('createTaskDefs');
      const bsModalRef = this.bsModalService.show(TaskDefinitionCreateDialogComponent, { class: 'modal-lg' });
      bsModalRef.content.setDsl(this.dsl);
      bsModalRef.content.successCallback = () => {
        this.router.navigate([`tasks/definitions`]);
      };
    }
  }

  lint(dsl: string, updateLintingCallback: CodeMirror.UpdateLintingCallback, editor: CodeMirror.Editor): void {
    const annotations: CodeMirror.Annotation[] = [];
    Array.from(this.validationMarkers.values())
      .filter(markers => Array.isArray(markers))
      .forEach(markers => markers
        .filter(m => m.range && m.hasOwnProperty('severity'))
        .forEach(m => annotations.push({
          message: m.message,
          from: m.range.start,
          to: m.range.end,
          severity: Flo.Severity[m.severity].toLowerCase()
        }))
      );
    const doc = editor.getDoc();
    const dslText = this.dsl;
    this.parseErrors = [];
    if (dslText) {
      this.toolsService.parseTaskTextToGraph(dslText).toPromise().then(taskConversion => {
        if (taskConversion.errors) {
          this.parseErrors = taskConversion.errors;
          taskConversion.errors.forEach(e => annotations.push({
            from: doc.posFromIndex(e.position),
            to: e['length'] ? doc.posFromIndex(e.position + e.length)
              : doc.posFromIndex(e.position + 1),
            message: e.message,
            severity: 'error'
          }));
        }
        updateLintingCallback(editor, annotations);
      }).catch(error => updateLintingCallback(editor, annotations));
    } else {
      // Don't parse empty DSL. It'll produce an error: "Ran out of input"
      updateLintingCallback(editor, annotations);
    }
  }

  get isCreateComposedTaskDisabled(): boolean {
    if (this.dsl && this.contentValidated && this.parseErrors.length === 0) {
      return Array.from(this.validationMarkers.values())
        .find(markers => markers
          .find(m => m.severity === Flo.Severity.Error) !== undefined) !== undefined;
    }
    return true;
  }

  get gridOn(): boolean {
    return this.editorContext.gridSize !== 1;
  }

  set gridOn(on: boolean) {
    this.editorContext.gridSize = on ? 20 : 1;
  }

}
<app-page>

  <app-page-head>
    <app-page-head-back [defaultUrl]="'/tasks/definitions'"></app-page-head-back>
    <app-page-head-title><strong>Create a task</strong></app-page-head-title>
  </app-page-head>

  <p> Create a task using text based input or the visual editor.</p>

  <div id="flo-container" class="stream-editor">
    <flo-editor (floApi)="setEditorContext($event)" [metamodel]="metamodelService" [renderer]="renderService"
                [editor]="editorService" [paletteSize]="paletteSize" [paperPadding]="55" [(dsl)]="dsl"
                (contentValidated)="contentValidated=$event" (validationMarkers)="validationMarkers = $event">

      <div class="flow-definition-container">
        <dsl-editor [(dsl)]="dsl" line-numbers="true" line-wrapping="true"
                    (focus)="editorContext.graphToTextSync=false" placeholder="Enter task definitions here..."
                    [lintOptions]="lintOptions"></dsl-editor>
      </div>

      <div class="flow-actions">
        <button (click)="clearGraph()" class="btn btn-default" type="button">Clear</button>
        <button (click)="arrangeAll()" class="btn btn-default" type="button">Layout</button>
        <button class="btn" (click)="gridOn = !gridOn"
                [ngClass]="{'btn-default-alt': !gridOn, 'btn-default': gridOn}">Grid
        </button>

      </div>
    </flo-editor>
  </div>

  <app-page-actions>
    <button id="back-button" type="button" class="btn btn-default" routerLink="/tasks">
      Cancel
    </button>
    <button (click)="createTaskDefs()" class="btn btn-primary" type="button">
      Create Task
    </button>
  </app-page-actions>

</app-page>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""