add-robot.component.ts 7.88 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
import {
  Component,
  OnInit,
  Input,
  ViewChild,
  OnDestroy,
  Output,
  EventEmitter,
  ChangeDetectorRef
} from "@angular/core";
import { Robot } from "../robot";
import { NgForm } from "@angular/forms";
import { Subject } from "rxjs";
import { debounceTime, finalize } from "rxjs/operators";
import { RobotService } from "../robot-account.service";
import { TranslateService } from "@ngx-translate/core";
import { MessageHandlerService } from "../../../shared/message-handler/message-handler.service";
import { InlineAlertComponent } from "../../../shared/inline-alert/inline-alert.component";
19
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
AllForNothing's avatar
AllForNothing committed
20
import { AppConfigService } from "../../../services/app-config.service";
21
import { ErrorHandler } from "../../../../lib/utils/error-handler";
AllForNothing's avatar
AllForNothing committed
22 23
const ONE_THOUSAND: number = 1000;
const NEVER_EXPIRED: number = -1;
24 25 26 27 28 29 30 31 32 33
@Component({
  selector: "add-robot",
  templateUrl: "./add-robot.component.html",
  styleUrls: ["./add-robot.component.scss"]
})
export class AddRobotComponent implements OnInit, OnDestroy {
  addRobotOpened: boolean;
  copyToken: boolean;
  robotToken: string;
  robotAccount: string;
34 35
  downLoadFileName: string = '';
  downLoadHref: SafeUrl = '';
36 37 38 39 40 41 42 43 44 45
  isSubmitOnGoing = false;
  closable: boolean = false;
  staticBackdrop: boolean = true;
  createSuccess: string;
  isRobotNameValid: boolean = true;
  checkOnGoing: boolean = false;
  robot: Robot = new Robot();
  robotNameChecker: Subject<string> = new Subject<string>();
  nameTooltipText = "ROBOT_ACCOUNT.ROBOT_NAME";
  robotForm: NgForm;
46 47
  imagePermissionPush: boolean = true;
  imagePermissionPull: boolean = true;
Yogi_Wang's avatar
Yogi_Wang committed
48
  withHelmChart: boolean;
49 50 51
  @Input() projectId: number;
  @Input() projectName: string;
  @Output() create = new EventEmitter<boolean>();
52
  @ViewChild("robotForm", {static: true}) currentForm: NgForm;
53
  @ViewChild("copyAlert") copyAlert: InlineAlertComponent;
AllForNothing's avatar
AllForNothing committed
54 55 56
  private _expiresDate: Date;
  isNeverExpired: boolean = false;
  expiresDatePlaceholder: string = ' ';
57
  constructor(
58 59 60 61
      private robotService: RobotService,
      private translate: TranslateService,
      private errorHandler: ErrorHandler,
      private cdr: ChangeDetectorRef,
62
      private messageHandlerService: MessageHandlerService,
Yogi_Wang's avatar
Yogi_Wang committed
63 64
      private sanitizer: DomSanitizer,
      private appConfigService: AppConfigService
65

Yogi_Wang's avatar
Yogi_Wang committed
66
  ) {}
67
  ngOnInit(): void {
Yogi_Wang's avatar
Yogi_Wang committed
68 69
    this.withHelmChart = this.appConfigService.getConfig().with_chartmuseum;

70 71 72 73 74 75 76
    this.robotNameChecker.pipe(debounceTime(800)).subscribe((name: string) => {
      let cont = this.currentForm.controls["robot_name"];
      if (cont) {
        this.isRobotNameValid = cont.valid;
        if (this.isRobotNameValid) {
          this.checkOnGoing = true;
          this.robotService
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
              .listRobotAccount(this.projectId)
              .pipe(
                  finalize(() => {
                    this.checkOnGoing = false;
                    let hnd = setInterval(() => this.cdr.markForCheck(), 100);
                    setTimeout(() => clearInterval(hnd), 2000);
                  })
              )
              .subscribe(
                  response => {
                    if (response && response.length) {
                      if (
                          response.find(target => {
                            return target.name === "robot$" + cont.value;
                          })
                      ) {
                        this.isRobotNameValid = false;
                        this.nameTooltipText = "ROBOT_ACCOUNT.ACCOUNT_EXISTING";
                      }
                    }
                  },
                  error => {
                    this.errorHandler.error(error);
100
                  }
101
              );
102 103 104 105 106 107 108 109 110 111 112 113 114 115
        } else {
          this.nameTooltipText = "ROBOT_ACCOUNT.ROBOT_NAME";
        }
      }
    });
  }

  openAddRobotModal(): void {
    if (this.isSubmitOnGoing) {
      return;
    }
    this.robot.name = "";
    this.robot.description = "";
    this.addRobotOpened = true;
116 117
    this.imagePermissionPush = true;
    this.imagePermissionPull = true;
118 119 120
    this.isRobotNameValid = true;
    this.robot = new Robot();
    this.nameTooltipText = "ROBOT_ACCOUNT.ROBOT_NAME";
AllForNothing's avatar
AllForNothing committed
121 122 123
    this.isNeverExpired = false;
    this.expiresDate = null;
    this.expiresDatePlaceholder = ' ';
124
    this.copyAlert.close();
125 126 127 128 129 130 131 132 133 134 135 136 137 138
  }

  onCancel(): void {
    this.addRobotOpened = false;
  }

  ngOnDestroy(): void {
    this.robotNameChecker.unsubscribe();
  }

  onSubmit(): void {
    if (this.isSubmitOnGoing) {
      return;
    }
139
    // set value to robot.access.isPullImage and robot.access.isPushOrPullImage when submit
140
    if ( this.imagePermissionPush && this.imagePermissionPull) {
141 142
      this.robot.access.isPullImage = false;
      this.robot.access.isPushOrPullImage = true;
143 144 145
    } else {
      this.robot.access.isPullImage = true;
      this.robot.access.isPushOrPullImage = false;
146
    }
AllForNothing's avatar
AllForNothing committed
147 148 149 150 151 152 153 154 155 156 157 158
    if (this.isNeverExpired) {
      this.robot.expires_at = NEVER_EXPIRED;
    } else {
      if (this.expiresDate) {
        if (this.expiresDate <= new Date()) {
          this.copyAlert.showInlineError("ROBOT_ACCOUNT.INVALID_VALUE");
          return;
        } else {
          this.robot.expires_at = Math.floor(this.expiresDate.getTime() / ONE_THOUSAND);
        }
      }
    }
159 160
    this.isSubmitOnGoing = true;
    this.robotService
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
        .addRobotAccount(
            this.projectId,
            this.robot,
            this.projectName
        )
        .subscribe(
            response => {
              this.isSubmitOnGoing = false;
              this.robotToken = response.token;
              this.robotAccount = response.name;
              this.copyToken = true;
              this.create.emit(true);
              this.translate
                  .get("ROBOT_ACCOUNT.CREATED_SUCCESS", { param: this.robotAccount })
                  .subscribe((res: string) => {
                    this.createSuccess = res;
                  });
              this.addRobotOpened = false;
179 180 181 182
              // export to token file
              const downLoadUrl = `data:text/json;charset=utf-8, ${encodeURIComponent(JSON.stringify(response))}`;
              this.downLoadHref = this.sanitizer.bypassSecurityTrustUrl(downLoadUrl);
              this.downLoadFileName = `${response.name}.json`;
183 184 185 186 187 188
            },
            error => {
              this.isSubmitOnGoing = false;
              this.copyAlert.showInlineError(error);
            }
        );
189 190 191 192
  }

  isValid(): boolean {
    return (
193 194 195 196 197
        this.currentForm &&
        this.currentForm.valid &&
        !this.isSubmitOnGoing &&
        this.isRobotNameValid &&
        !this.checkOnGoing
198 199 200 201 202
    );
  }
  get shouldDisable(): boolean {
    if (this.robot && this.robot.access) {
      return (
203 204 205
          !this.isValid() ||
          (!this.robot.access.isPushOrPullImage && !this.robot.access.isPullImage
              && !this.robot.access.isPullChart && !this.robot.access.isPushChart)
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
      );
    }
  }

  // Handle the form validation
  handleValidation(): void {
    let cont = this.currentForm.controls["robot_name"];
    if (cont) {
      this.robotNameChecker.next(cont.value);
    }
  }

  onCpError($event: any): void {
    if (this.copyAlert) {
      this.copyAlert.showInlineError("PUSH_IMAGE.COPY_ERROR");
    }
  }

  onCpSuccess($event: any): void {
    this.copyToken = false;
    this.translate
227 228 229 230
        .get("ROBOT_ACCOUNT.COPY_SUCCESS", { param: this.robotAccount })
        .subscribe((res: string) => {
          this.messageHandlerService.showSuccess(res);
        });
231
  }
232 233 234 235

  closeModal() {
    this.copyToken = false;
  }
AllForNothing's avatar
AllForNothing committed
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
  switch() {
    if (this.isNeverExpired) {
      this.expiresDate = null;
      this.translate.get('ROBOT_ACCOUNT.NEVER_EXPIRED').subscribe(value => {
        this.expiresDatePlaceholder = value;
      });
    } else {
      this.expiresDatePlaceholder = ' ';
    }
  }
  get expiresDate(): Date {
    return this._expiresDate;
  }
  set expiresDate(date: Date) {
    if (date) {
      this.isNeverExpired = false;
    }
    this._expiresDate = date;
  }
255
}