@angular/animations#useAnimation TypeScript Examples

The following examples show how to use @angular/animations#useAnimation. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: matx-animations.ts    From matx-angular with MIT License 6 votes vote down vote up
matxAnimations = [
  trigger("animate", [transition("void => *", [useAnimation(reusable)])]),

  trigger("fadeInOut", [
    state(
      "0",
      style({
        opacity: 0,
        display: "none"
      })
    ),
    state(
      "1",
      style({
        opacity: 1,
        display: "block"
      })
    ),
    transition("0 => 1", animate("300ms")),
    transition("1 => 0", animate("300ms"))
  ])
]
Example #2
Source File: dashboard.component.ts    From IntelOwl-ng with GNU Affero General Public License v3.0 4 votes vote down vote up
@Component({
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss'],
  animations: [
    trigger('dashboardAnimation', [
      transition('false => true', useAnimation(flash)),
    ]),
  ],
})
export class DashboardComponent implements OnDestroy {
  // animations
  flashAnimBool: boolean = false;
  private toggleAnimation = () => (this.flashAnimBool = !this.flashAnimBool);
  // RxJS subscriptions
  private jobSub: Subscription;
  private tagSub: Subscription;
  private jobs: Job[];
  filterEl: string = null;
  filterField: string = null;
  iconRotateBool: boolean = false;

  // Pie Chart Data
  pieChartData: any = {};

  // ng2-smart-table data source
  source: LocalDataSource = new LocalDataSource();

  // ng2-smart-table settings
  settings = {
    actions: {
      add: false,
      edit: false,
      delete: false,
    },
    pager: {
      display: true,
      perPage: 10,
    },
    columns: {
      result: {
        title: 'Result',
        type: 'custom',
        width: '3%',
        filter: false,
        sort: false,
        renderComponent: ViewResultButtonComponent,
      },
      id: {
        title: 'id',
        width: '3%',
      },
      observable_name: {
        title: 'Name',
        valuePrepareFunction: (c, r) => r.observable_name || r.file_name,
      },
      tags: {
        title: 'Tags',
        type: 'custom',
        filter: false,
        sort: false,
        renderComponent: TagsRenderComponent,
        onComponentInitFunction: (instance: any) =>
          this.filterJobsByTag(instance),
      },
      observable_classification: {
        title: 'Type',
        width: '20%',
        filter: false,
        valuePrepareFunction: (c, r) =>
          r.observable_classification || r.file_mimetype,
      },
      no_of_analyzers_executed: {
        title: 'Analyzers Called',
        width: '10%',
        filter: false,
      },
      process_time: {
        title: 'Process Time (s)',
        width: '10%',
        filter: false,
      },
      status: {
        title: 'Success',
        type: 'custom',
        width: '5%',
        filter: false,
        renderComponent: JobStatusIconRenderComponent,
      },
      no_of_connectors_executed: {
        title: 'Connectors Called',
        width: '10%',
        filter: false,
      },
    },
  };

  constructor(
    private readonly jobService: JobService,
    private readonly toastr: ToastService
  ) {
    this.jobSub = this.jobService.jobs$.subscribe(
      (res: Job[]) => this.initData(res),
      async (err: any) =>
        this.toastr.showToast(
          err.message,
          'Failed to fetch Data. Are you online ?',
          'error'
        )
    );
  }

  private async initData(res: Job[]): Promise<void> {
    this.jobs = res;
    if (this.jobs) {
      // load data into table
      this.source.load(this.jobs);
      // construct visualization data
      this.pieChartData['status'] = await this.constructPieData(
        this.jobs,
        'status'
      );
      this.pieChartData['type'] = await this.constructPieData(
        this.jobs,
        'type'
      );
      this.pieChartData[
        'observable_classification'
      ] = await this.constructPieData(this.jobs, 'observable_classification');
      this.pieChartData['file_mimetype'] = await this.constructPieData(
        this.jobs,
        'file_mimetype'
      );
    }
  }

  private async constructPieData(
    jobs: Job[],
    field: string
  ): Promise<Array<{ name: string; value: number }>> {
    const fieldValuesMap: Map<string, number> = new Map();

    jobs.forEach((job) => {
      let keys: string[] = [];

      if (job[field] === null || job[field] === '') {
        return; // jump to next iteration
      } else if (job[field] instanceof Object && job[field].length > 0) {
        keys = job[field];
      } else {
        keys.push(job[field]);
      }

      keys.forEach((k) => {
        if (fieldValuesMap.get(k) === undefined) {
          fieldValuesMap.set(k, 0);
        }
        fieldValuesMap.set(k, fieldValuesMap.get(k) + 1);
      });
    });

    const pieData: Array<{ name: string; value: number }> = [];

    fieldValuesMap.forEach((v, k) => {
      pieData.push({ name: k, value: v });
    });

    return pieData;
  }

  filterJobsByField(el: any, field: string): void {
    const filteredJobs = this.jobs.filter((job) => el.name === job[field]);
    this.filterField = field;
    this.filterEl = el.name;
    this.source.load(filteredJobs);
  }

  private filterJobsByTag(tagComponentInst: any) {
    this.tagSub = tagComponentInst.onTagClick.subscribe((t: Tag) => {
      const filteredJobs = this.jobs.filter((job) =>
        job.tags.some((o) => o.label === t.label)
      );
      this.filterField = 'Tag';
      this.filterEl = t.label;
      this.source.load(filteredJobs);
    });
  }

  async debouncedSync() {
    // this function is debounced by 2 seconds
    this.iconRotateBool = false;
    // reset filters
    this.filterField = null;
    this.filterEl = null;
    this.toggleAnimation();
    this.jobService.initOrRefresh().then(
      () =>
        this.toastr.showToast(
          'Dashboard is updated with latest data',
          'Sync successful!',
          'success'
        ),
      (err) => this.toastr.showToast(err.message, 'Sync failed!', 'error')
    );
  }

  resetFilters(): void {
    this.filterField = null;
    this.filterEl = null;
    this.source.load(this.jobs);
    this.source.reset();
  }

  ngOnDestroy(): void {
    this.jobSub && this.jobSub.unsubscribe();
    this.tagSub && this.tagSub.unsubscribe();
  }
}
Example #3
Source File: job-result.component.ts    From IntelOwl-ng with GNU Affero General Public License v3.0 4 votes vote down vote up
@Component({
  selector: 'intelowl-job-result',
  templateUrl: './job-result.component.html',
  styleUrls: ['./job-result.component.scss'],
  animations: [
    trigger('refreshAnimation', [
      transition('false => true', useAnimation(flash)),
    ]),
  ],
})
export class JobResultComponent implements OnInit, OnDestroy {
  // Animation
  flashAnimBool: boolean = false;
  private toggleAnimation = () => (this.flashAnimBool = !this.flashAnimBool);
  // if true, shows error template
  public isError: boolean = false;
  // RxJS Subscription
  private sub: Subscription;

  // interval var
  private pollInterval: any;

  // image viewer var
  public imageResult: string = '';

  // base ng2-smart-table settings for analyzer and connector reports
  private baseTableSettings = {
    actions: {
      add: false,
      edit: false,
      delete: false,
    },
    pager: {
      display: true,
      perPage: 7,
    },
    columns: {
      pluginActions: {
        title: 'Actions',
        width: '15%',
        filter: false,
        sort: false,
        type: 'custom',
        renderComponent: PluginActionsRenderComponent,
      },
      name: {
        title: 'Name',
      },
      status: {
        title: 'Status',
        type: 'custom',
        filter: false,
        width: '3%',
        compareFunction: this.compareReportStatus,
        renderComponent: JobStatusIconRenderComponent,
      },
      process_time: {
        title: 'Process Time (s)',
        filter: false,
        valuePrepareFunction: (c) => parseFloat(c).toFixed(2),
      },
      start_time: {
        title: 'Start Time',
        filter: false,
        valuePrepareFunction: (c, r) => new Date(r.start_time).toLocaleString(),
      },
    },
    rowClassFunction: (row) => {
      return 'cursor-pointer';
    },
  };

  // ng2-smart-table settings for analyzer reports
  public analyzerTableSettings = {
    ...this.baseTableSettings,
    columns: {
      ...this.baseTableSettings.columns,
      pluginActions: {
        ...this.baseTableSettings.columns.pluginActions,
        onComponentInitFunction: (instance: any) => {
          instance.killEmitter.subscribe((analyzerName) =>
            this.analyzerService.killAnalyzer(this.jobId, analyzerName)
          );
          instance.retryEmitter.subscribe(async (analyzerName) => {
            const success = await this.analyzerService.retryAnalyzer(
              this.jobId,
              analyzerName
            );
            if (success) {
              // instant polling for an update and then at intervals
              this.jobService.pollForJob(this.jobId);
              this.startJobPollingWithInterval();
            }
          });
        },
      },
    },
  };

  // ng2-smart-table settings for connector reports
  public connectorTableSettings = {
    ...this.baseTableSettings,
    columns: {
      ...this.baseTableSettings.columns,
      pluginActions: {
        ...this.baseTableSettings.columns.pluginActions,
        onComponentInitFunction: (instance: any) => {
          instance.killEmitter.subscribe((connectorName) =>
            this.connectorService.killConnector(this.jobId, connectorName)
          );
          instance.retryEmitter.subscribe(async (connectorName) => {
            const success = await this.connectorService.retryConnector(
              this.jobId,
              connectorName
            );
            if (success) {
              // instant polling for an update and then at intervals
              this.jobService.pollForJob(this.jobId, ['connector_reports']);
              this.startJobPollingWithInterval();
            }
          });
        },
      },
    },
  };

  // ng2-smart-table data source
  public analyzerTableDataSource: LocalDataSource = new LocalDataSource();
  public connectorTableDataSource: LocalDataSource = new LocalDataSource();

  // Job ID whose result is being displayed
  public jobId: number;

  // Job Data for current jobId
  public jobObj: Job;

  // row whose report/error is currently being shown
  public selectedRowName: string;

  // boolean to track if connectors are running
  public connectorsRunningBool: boolean;

  // JSON Editor
  public editorOptions: JsonEditorOptions;
  @ViewChild(JsonEditorComponent, { static: false })
  editor: JsonEditorComponent;

  constructor(
    private readonly activateRoute: ActivatedRoute,
    private readonly jobService: JobService,
    private readonly analyzerService: AnalyzerConfigService,
    private readonly connectorService: ConnectorConfigService
  ) {
    this.sub = this.activateRoute.params.subscribe(
      (res) => (this.jobId = res.jobId)
    );
    this.editorOptions = new JsonEditorOptions();
    this.editorOptions.modes = ['text', 'tree'];
    this.editorOptions.onEditable = () => false;
  }

  ngOnInit(): void {
    // set sorting for data sources
    const sortingConf = [
      { field: 'name', direction: 'asc' }, // secondary sort
      { field: 'status', direction: 'asc', compare: this.compareReportStatus }, // primary sort
    ];
    this.analyzerTableDataSource.setSort(sortingConf);
    this.connectorTableDataSource.setSort(sortingConf);

    // subscribe to jobResult
    this.jobService
      .pollForJob(this.jobId)
      .then(() => {
        this.sub.add(
          this.jobService.jobResult$.subscribe((res: Job) =>
            this.updateJobData(res)
          )
        );
        // only called once
        this.initData();
      })
      .catch(() => (this.isError = true));
  }

  private startJobPollingWithInterval(): void {
    // avoid multiple pollings
    clearInterval(this.pollInterval);
    const interval = this.connectorsRunningBool ? 15000 : 5000;
    this.pollInterval = setInterval(() => {
      const jobFields = this.connectorsRunningBool ? ['connector_reports'] : []; // [] means all
      this.jobService.pollForJob(this.jobId, jobFields);
    }, interval);
  }

  private initData(): void {
    // poll for changes to job result if status=running or connectors are running
    this.connectorsRunningBool = this.checkConnectorsRunning();
    if (this.jobObj.status === 'running' || this.connectorsRunningBool) {
      this.startJobPollingWithInterval();
    }
    // simulate click event to select the first row of the table as the default one on
    setTimeout(
      () => this.onRowSelect({ data: this.jobObj.analyzer_reports[0] }, false),
      500
    );
  }

  private compareReportStatus(direction: number, a: string, b: string) {
    a = a.toLowerCase();
    b = b.toLowerCase();
    const priority = {
      success: 0,
      failed: 1,
      killed: 2,
      running: 3,
      pending: 4,
    };

    return priority[a] < priority[b] ? -1 * direction : direction;
  }

  private updateJobData(res: Job): void {
    // update job object (with partial update)
    this.jobObj = { ...this.jobObj, ...res };
    // load data into the analysis table data source
    this.analyzerTableDataSource.load(this.jobObj.analyzer_reports);
    // load data into connectors table data source
    this.connectorTableDataSource.load(this.jobObj.connector_reports);
    // toggle animation
    this.toggleAnimation();
    // check if connectors are running
    this.connectorsRunningBool = this.checkConnectorsRunning();
    if (this.jobObj.status !== 'running' && !this.connectorsRunningBool) {
      // stop polling
      clearInterval(this.pollInterval);
      // converting date time to locale string
      const date1 = new Date(this.jobObj.received_request_time);
      const date2 = new Date(this.jobObj.finished_analysis_time);
      this.jobObj.received_request_time = date1.toString();
      this.jobObj.finished_analysis_time = date2.toString();
      // calculate job process time
      this.jobObj.job_process_time = (date2.getTime() - date1.getTime()) / 1000;
    }
  }

  private checkConnectorsRunning() {
    let connectorsRunning = false,
      status;
    if (this.jobObj.status === 'reported_without_fails')
      // connectors run only after this status is set
      for (const conn_report of this.jobObj.connector_reports) {
        status = conn_report.status.toLowerCase();
        if (status === 'running' || status === 'pending') {
          connectorsRunning = true;
          break;
        }
      }
    return connectorsRunning;
  }

  generateAlertMsgForConnectorReports() {
    // call only if job status != reported_without_fails
    const jobStatus = this.jobObj.status;
    if (jobStatus === 'running' || jobStatus === 'pending')
      return 'Connectors will be triggered when job analysis finishes without fails.';
    else if (['failed', 'reported_with_fails', 'killed'].includes(jobStatus))
      return 'No connectors were triggered because job analysis failed or was killed';
  }

  generateReportTableMetrics(pluginType: string) {
    let pluginReports: any[],
      numpluginsToExecute: number,
      running = 0,
      completed = 0;
    if (pluginType === 'analyzer') {
      pluginReports = this.jobObj.analyzer_reports;
      numpluginsToExecute = this.jobObj.analyzers_to_execute.length;
    } else {
      pluginReports = this.jobObj.connector_reports;
      numpluginsToExecute = this.jobObj.connectors_to_execute.length;
    }
    for (const report of pluginReports) {
      const status = report.status.toLowerCase();
      if (status === 'running') running++;
      else if (status !== 'pending') completed++;
    }
    return `Started: ${pluginReports.length}/${numpluginsToExecute}, ${
      running > 0 ? `Running: ${running}/${numpluginsToExecute},` : ``
    } Completed: ${completed}/${numpluginsToExecute}`;
  }

  // event emitted when user clicks on a row in table
  onRowSelect(event, shouldScroll: boolean = true): void {
    this.selectedRowName = event.data.name;
    if (shouldScroll)
      this.editor.jsonEditorContainer.nativeElement.scrollIntoView({
        behavior: 'smooth',
        block: 'start',
      });
    // if `report` exists shows report, otherwise the `errors`
    const json = Object.entries(event.data.report).length
      ? event.data.report
      : event.data.errors;
    this.editor.update(json);

    if (
      Object.prototype.hasOwnProperty.call(json, 'screenshot') &&
      json['screenshot'].length
    )
      this.imageResult = json.screenshot;
    else this.imageResult = '';
  }

  ngOnDestroy(): void {
    // cancel job result polling
    this.pollInterval && clearInterval(this.pollInterval);
    // unsubscribe to observables to prevent memory leakage
    this.sub && this.sub.unsubscribe();
  }
}