File

src/app/cluster/cluster-detail/cluster-detail.component.ts

Implements

OnInit

Metadata

Index

Properties
Methods

Constructor

constructor(route: ActivatedRoute, router: Router, dialog: MatDialog, helperService: HelperService, clusterService: ClusterService, instanceService: InstanceService)
Parameters :
Name Type Optional
route ActivatedRoute No
router Router No
dialog MatDialog No
helperService HelperService No
clusterService ClusterService No
instanceService InstanceService No

Methods

activateCluster
activateCluster()
Returns : void
addInstance
addInstance()
Returns : void
deleteCluster
deleteCluster()
Returns : void
disableCluster
disableCluster()
Returns : void
disableMaintenanceMode
disableMaintenanceMode()
Returns : void
enableCluster
enableCluster()
Returns : void
enableMaintenanceMode
enableMaintenanceMode()
Returns : void
Protected loadCluster
loadCluster()
Returns : void
ngOnInit
ngOnInit()
Returns : void

Properties

can
Default value : false
cluster
Type : Cluster
clusterName
Type : string
isLoading
Default value : false
Readonly tabLinks
Type : []
Default value : [ { label: 'Dashboard (beta)', link: 'dashboard' }, { label: 'Resources', link: 'resources' }, { label: 'Workflows', link: 'workflows' }, { label: 'Instances', link: 'instances' }, { label: 'Configuration', link: 'configs' }, ]
import { map } from 'rxjs/operators';
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';

import { Cluster } from '../shared/cluster.model';
import { HelperService } from '../../shared/helper.service';
import { ClusterService } from '../shared/cluster.service';
import { InstanceService } from '../../instance/shared/instance.service';
import { AlertDialogComponent } from '../../shared/dialog/alert-dialog/alert-dialog.component';
import { InputDialogComponent } from '../../shared/dialog/input-dialog/input-dialog.component';

@Component({
  selector: 'hi-cluster-detail',
  templateUrl: './cluster-detail.component.html',
  styleUrls: ['./cluster-detail.component.scss'],
  providers: [InstanceService],
})
export class ClusterDetailComponent implements OnInit {
  readonly tabLinks = [
    { label: 'Dashboard (beta)', link: 'dashboard' },
    { label: 'Resources', link: 'resources' },
    { label: 'Workflows', link: 'workflows' },
    { label: 'Instances', link: 'instances' },
    { label: 'Configuration', link: 'configs' },
  ];

  isLoading = false;
  clusterName: string; // for better UX needs
  cluster: Cluster;
  can = false;

  constructor(
    protected route: ActivatedRoute,
    protected router: Router,
    protected dialog: MatDialog,
    protected helperService: HelperService,
    protected clusterService: ClusterService,
    protected instanceService: InstanceService
  ) {}

  ngOnInit() {
    this.clusterService.can().subscribe((data) => (this.can = data));
    this.route.params.pipe(map((p) => p.name)).subscribe((name) => {
      this.clusterName = name;
      this.loadCluster();
    });
  }

  protected loadCluster() {
    this.isLoading = true;
    this.clusterService.get(this.clusterName).subscribe(
      (data) => (this.cluster = data),
      (error) => this.helperService.showError(error),
      () => (this.isLoading = false)
    );
  }

  addInstance() {
    this.dialog
      .open(InputDialogComponent, {
        data: {
          title: 'Add a new Instance',
          message: 'Please enter the following information to continue:',
          values: {
            host: {
              label: 'Hostname',
            },
            port: {
              label: 'Port',
            },
            enabled: {
              label: 'Enabled',
              type: 'boolean',
            },
          },
        },
      })
      .afterClosed()
      .subscribe((result) => {
        if (result) {
          this.instanceService
            .create(
              this.cluster.name,
              result.host.value,
              result.port.value,
              result.enabled.value
            )
            .subscribe(
              (data) => {
                this.helperService.showSnackBar('New Instance added!');
                // temporarily navigate back to instance view to refresh
                // will fix this using ngrx/store
                this.router.navigate(['workflows'], { relativeTo: this.route });
                setTimeout(() => {
                  this.router.navigate(['instances'], {
                    relativeTo: this.route,
                  });
                }, 100);
              },
              (error) => this.helperService.showError(error),
              () => {}
            );
        }
      });
  }

  enableCluster() {
    this.clusterService.enable(this.clusterName).subscribe(
      () => this.loadCluster(),
      (error) => this.helperService.showError(error)
    );
  }

  disableCluster() {
    this.clusterService.disable(this.clusterName).subscribe(
      () => this.loadCluster(),
      (error) => this.helperService.showError(error)
    );
  }

  activateCluster() {
    this.dialog
      .open(InputDialogComponent, {
        data: {
          title: 'Activate this Cluster',
          message:
            'To link this cluster to a Helix super cluster (controller), please enter the super cluster name:',
          values: {
            name: {
              label: 'super cluster name',
            },
          },
        },
      })
      .afterClosed()
      .subscribe((result) => {
        if (result && result.name.value) {
          this.clusterService
            .activate(this.clusterName, result.name.value)
            .subscribe(
              () => {
                // since this action may delay a little bit, to prevent re-activation,
                // use an alert dialog to reload the data later
                this.dialog
                  .open(AlertDialogComponent, {
                    data: {
                      title: 'Cluster Activated',
                      message: `Cluster '${this.clusterName}' is linked to super cluster '${result.name.value}'.`,
                    },
                  })
                  .afterClosed()
                  .subscribe(() => {
                    this.loadCluster();
                  });
              },
              (error) => this.helperService.showError(error)
            );
        }
      });
  }

  enableMaintenanceMode() {
    this.dialog
      .open(InputDialogComponent, {
        data: {
          title: 'Enable maintenance mode',
          message:
            'What reason do you want to use to put the cluster in maintenance mode?',
          values: {
            reason: {
              label: 'reason',
            },
          },
        },
      })
      .afterClosed()
      .subscribe((result) => {
        if (result && result.reason.value) {
          this.clusterService
            .enableMaintenanceMode(this.clusterName, result.reason.value)
            .subscribe(
              () => this.loadCluster(),
              (error) => this.helperService.showError(error)
            );
        }
      });
  }

  disableMaintenanceMode() {
    this.clusterService.disableMaintenanceMode(this.clusterName).subscribe(
      () => this.loadCluster(),
      (error) => this.helperService.showError(error)
    );
  }

  deleteCluster() {
    this.helperService
      .showConfirmation(
        'Are you sure you want to delete this cluster? This cannot be undone.',
        'Confirm Cluster Deletion',
        `Delete Cluster ${this.clusterName}`
      )
      .then((result) => {
        if (result) {
          this.clusterService.remove(this.cluster.name).subscribe((data) => {
            this.helperService.showSnackBar(
              `Cluster ${this.clusterName} deleted`
            );
            // FIXME: should reload cluster list as well
            this.router.navigate(['..'], { relativeTo: this.route });
          });
        }
      });
  }
}
<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one
  ~ or more contributor license agreements.  See the NOTICE file
  ~ distributed with this work for additional information
  ~ regarding copyright ownership.  The ASF licenses this file
  ~ to you under the Apache License, Version 2.0 (the
  ~ "License"); you may not use this file except in compliance
  ~ with the License.  You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing,
  ~ software distributed under the License is distributed on an
  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  ~ KIND, either express or implied.  See the License for the
  ~ specific language governing permissions and limitations
  ~ under the License.
  -->

<section *ngIf="clusterName" class="cluster-detail" fxLayout="column" fxFill>
  <mat-toolbar class="mat-elevation-z1" fxFlex="none">
    <mat-toolbar-row>
      <hi-detail-header [cluster]="clusterName"></hi-detail-header>
      <hi-disabled-label
        *ngIf="!cluster?.enabled"
        text="DISABLED"
      ></hi-disabled-label>
      <hi-disabled-label
        *ngIf="cluster?.inMaintenance"
        text="In Maintenance Mode"
      ></hi-disabled-label>
    </mat-toolbar-row>
    <mat-toolbar-row class="information">
      <mat-spinner *ngIf="isLoading" diameter="30"></mat-spinner>
      <h6 *ngIf="!isLoading">
        Controller:
        <a mat-button color="accent" routerLink="controller">{{
          cluster.controller
        }}</a>
      </h6>
      <span fxFlex="1 1 auto"></span>
      <button mat-mini-fab *ngIf="can" [matMenuTriggerFor]="menu">
        <mat-icon>menu</mat-icon>
      </button>
      <mat-menu #menu="matMenu">
        <button
          mat-menu-item
          *ngIf="cluster?.controller === 'No Lead Controller!'"
          (click)="activateCluster()"
        >
          <mat-icon>settings_input_antenna</mat-icon>
          <span>Activate this Cluster</span>
        </button>
        <button
          mat-menu-item
          *ngIf="!cluster?.inMaintenance"
          (click)="enableMaintenanceMode()"
        >
          <mat-icon>music_off</mat-icon>
          <span>Enable maintenance mode</span>
        </button>
        <button
          mat-menu-item
          *ngIf="cluster?.inMaintenance"
          (click)="disableMaintenanceMode()"
        >
          <mat-icon>music_note</mat-icon>
          <span>Disable maintenance mode</span>
        </button>
        <button
          mat-menu-item
          *ngIf="cluster?.enabled"
          (click)="disableCluster()"
        >
          <mat-icon>not_interested</mat-icon>
          <span>Disable this Cluster</span>
        </button>
        <button
          mat-menu-item
          *ngIf="!cluster?.enabled"
          (click)="enableCluster()"
        >
          <mat-icon>play_circle_outline</mat-icon>
          <span>Enable this Cluster</span>
        </button>
        <button mat-menu-item *ngIf="false" (click)="addResource()">
          <mat-icon>note_add</mat-icon>
          <span>Add a Resource</span>
        </button>
        <button mat-menu-item (click)="addInstance()">
          <mat-icon>add_circle</mat-icon>
          <span>Add an Instance</span>
        </button>
        <button mat-menu-item (click)="deleteCluster()">
          <mat-icon>delete</mat-icon>
          <span>DELETE this Cluster</span>
        </button>
      </mat-menu>
    </mat-toolbar-row>
  </mat-toolbar>
  <nav mat-tab-nav-bar>
    <a
      mat-tab-link
      *ngFor="let tabLink of tabLinks"
      [routerLink]="tabLink.link"
      routerLinkActive
      #rla="routerLinkActive"
      [active]="rla.isActive"
    >
      {{ tabLink.label }}
    </a>
  </nav>
  <section fxFlex>
    <router-outlet></router-outlet>
  </section>
</section>

./cluster-detail.component.scss

.mat-spinner {
  margin: 0 20px;
}

.mat-toolbar h6 {
  font-size: 14px;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""