import { Component } from '@angular/core';
import { Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
-import { I18n } from '@ngx-translate/i18n-polyfill';
-import * as _ from 'lodash';
-import { BsModalService } from 'ngx-bootstrap/modal';
+import _ from 'lodash';
+import moment from 'moment';
-import { PrometheusService } from '../../../../shared/api/prometheus.service';
-import {
- ActionLabelsI18n,
- SucceededActionLabelsI18n
-} from '../../../../shared/constants/app.constants';
-import { Icons } from '../../../../shared/enum/icons.enum';
-import { NotificationType } from '../../../../shared/enum/notification-type.enum';
-import { CdFormBuilder } from '../../../../shared/forms/cd-form-builder';
-import { CdFormGroup } from '../../../../shared/forms/cd-form-group';
-import { CdValidators } from '../../../../shared/forms/cd-validators';
+import { DashboardNotFoundError } from '~/app/core/error/error';
+import { PrometheusService } from '~/app/shared/api/prometheus.service';
+import { ActionLabelsI18n, SucceededActionLabelsI18n } from '~/app/shared/constants/app.constants';
+import { Icons } from '~/app/shared/enum/icons.enum';
+import { NotificationType } from '~/app/shared/enum/notification-type.enum';
+import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
+import { CdValidators } from '~/app/shared/forms/cd-validators';
import {
AlertmanagerSilence,
AlertmanagerSilenceMatcher,
AlertmanagerSilenceMatcherMatch
-} from '../../../../shared/models/alertmanager-silence';
-import { Permission } from '../../../../shared/models/permissions';
-import { AlertmanagerAlert, PrometheusRule } from '../../../../shared/models/prometheus-alerts';
-import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
-import { NotificationService } from '../../../../shared/services/notification.service';
-import { PrometheusSilenceMatcherService } from '../../../../shared/services/prometheus-silence-matcher.service';
-import { TimeDiffService } from '../../../../shared/services/time-diff.service';
+} from '~/app/shared/models/alertmanager-silence';
+import { Permission } from '~/app/shared/models/permissions';
+import { AlertmanagerAlert, PrometheusRule } from '~/app/shared/models/prometheus-alerts';
+import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
+import { ModalService } from '~/app/shared/services/modal.service';
+import { NotificationService } from '~/app/shared/services/notification.service';
+import { PrometheusSilenceMatcherService } from '~/app/shared/services/prometheus-silence-matcher.service';
+import { TimeDiffService } from '~/app/shared/services/time-diff.service';
import { SilenceMatcherModalComponent } from '../silence-matcher-modal/silence-matcher-modal.component';
@Component({
form: CdFormGroup;
rules: PrometheusRule[];
- // Date formatting rules can be found here: https://momentjs.com/docs/#/displaying/format/
- bsConfig = { dateInputFormat: 'YYYY-MM-DDT HH:mm' };
-
recreate = false;
edit = false;
id: string;
action: string;
- resource = this.i18n('silence');
+ resource = $localize`silence`;
matchers: AlertmanagerSilenceMatcher[] = [];
matcherMatch: AlertmanagerSilenceMatcherMatch = undefined;
matcherConfig = [
{
- tooltip: this.i18n('Attribute name'),
+ tooltip: $localize`Attribute name`,
icon: this.icons.paragraph,
attribute: 'name'
},
{
- tooltip: this.i18n('Value'),
+ tooltip: $localize`Value`,
icon: this.icons.terminal,
attribute: 'value'
},
{
- tooltip: this.i18n('Regular expression'),
+ tooltip: $localize`Regular expression`,
icon: this.icons.magic,
attribute: 'isRegex'
}
];
+ datetimeFormat = 'YYYY-MM-DD HH:mm';
+
constructor(
- private i18n: I18n,
private router: Router,
private authStorageService: AuthStorageService,
private formBuilder: CdFormBuilder,
private notificationService: NotificationService,
private route: ActivatedRoute,
private timeDiff: TimeDiffService,
- private bsModalService: BsModalService,
+ private modalService: ModalService,
private silenceMatcher: PrometheusSilenceMatcherService,
private actionLabels: ActionLabelsI18n,
private succeededLabels: SucceededActionLabelsI18n
}
private chooseMode() {
- this.edit = this.router.url.startsWith('/monitoring/silence/edit');
- this.recreate = this.router.url.startsWith('/monitoring/silence/recreate');
+ this.edit = this.router.url.startsWith('/monitoring/silences/edit');
+ this.recreate = this.router.url.startsWith('/monitoring/silences/recreate');
if (this.edit) {
this.action = this.actionLabels.EDIT;
} else if (this.recreate) {
const allowed =
this.permission.read && (this.edit ? this.permission.update : this.permission.create);
if (!allowed) {
- this.router.navigate(['/404']);
+ throw new DashboardNotFoundError();
}
}
private createForm() {
+ const formatValidator = CdValidators.custom('format', (expiresAt: string) => {
+ const result = expiresAt === '' || moment(expiresAt, this.datetimeFormat).isValid();
+ return !result;
+ });
this.form = this.formBuilder.group(
{
- startsAt: [null, [Validators.required]],
+ startsAt: ['', [Validators.required, formatValidator]],
duration: ['2h', [Validators.min(1)]],
- endsAt: [null, [Validators.required]],
+ endsAt: ['', [Validators.required, formatValidator]],
createdBy: [this.authStorageService.getUsername(), [Validators.required]],
comment: [null, [Validators.required]]
},
}
private setupDates() {
- const now = new Date();
- now.setSeconds(0, 0); // Normalizes start date
+ const now = moment().format(this.datetimeFormat);
this.form.silentSet('startsAt', now);
this.updateDate();
this.subscribeDateChanges();
}
private updateDate(updateStartDate?: boolean) {
- const next = this.timeDiff.calculateDate(
+ const date = moment(
this.form.getValue(updateStartDate ? 'endsAt' : 'startsAt'),
- this.form.getValue('duration'),
- updateStartDate
- );
+ this.datetimeFormat
+ ).toDate();
+ const next = this.timeDiff.calculateDate(date, this.form.getValue('duration'), updateStartDate);
if (next) {
- this.form.silentSet(updateStartDate ? 'startsAt' : 'endsAt', next);
+ const nextDate = moment(next).format(this.datetimeFormat);
+ this.form.silentSet(updateStartDate ? 'startsAt' : 'endsAt', nextDate);
}
}
}
private onDateChange(updateStartDate?: boolean) {
- if (this.form.getValue('startsAt') < this.form.getValue('endsAt')) {
+ const startsAt = moment(this.form.getValue('startsAt'), this.datetimeFormat);
+ const endsAt = moment(this.form.getValue('endsAt'), this.datetimeFormat);
+ if (startsAt.isBefore(endsAt)) {
this.updateDuration();
} else {
this.updateDate(updateStartDate);
}
private updateDuration() {
- this.form.silentSet(
- 'duration',
- this.timeDiff.calculateDuration(this.form.getValue('startsAt'), this.form.getValue('endsAt'))
- );
+ const startsAt = moment(this.form.getValue('startsAt'), this.datetimeFormat).toDate();
+ const endsAt = moment(this.form.getValue('endsAt'), this.datetimeFormat).toDate();
+ this.form.silentSet('duration', this.timeDiff.calculateDuration(startsAt, endsAt));
}
private getData() {
this.rules = [];
this.notificationService.show(
NotificationType.info,
- this.i18n(
- 'Please add your Prometheus host to the dashboard configuration and refresh the page'
- ),
+ $localize`Please add your Prometheus host to the dashboard configuration and refresh the page`,
undefined,
undefined,
'Prometheus'
private fillFormWithSilence(silence: AlertmanagerSilence) {
this.id = silence.id;
if (this.edit) {
- ['startsAt', 'endsAt'].forEach((attr) => this.form.silentSet(attr, new Date(silence[attr])));
+ ['startsAt', 'endsAt'].forEach((attr) =>
+ this.form.silentSet(attr, moment(silence[attr]).format(this.datetimeFormat))
+ );
this.updateDuration();
}
['createdBy', 'comment'].forEach((attr) => this.form.silentSet(attr, silence[attr]));
}
showMatcherModal(index?: number) {
- const modalRef = this.bsModalService.show(SilenceMatcherModalComponent);
- const modal = modalRef.content as SilenceMatcherModalComponent;
- modal.rules = this.rules;
+ const modalRef = this.modalService.show(SilenceMatcherModalComponent);
+ const modalComponent = modalRef.componentInstance as SilenceMatcherModalComponent;
+ modalComponent.rules = this.rules;
if (_.isNumber(index)) {
- modal.editMode = true;
- modal.preFillControls(this.matchers[index]);
+ modalComponent.editMode = true;
+ modalComponent.preFillControls(this.matchers[index]);
}
- modalRef.content.submitAction.subscribe((matcher: AlertmanagerSilenceMatcher) => {
+ modalComponent.submitAction.subscribe((matcher: AlertmanagerSilenceMatcher) => {
this.setMatcher(matcher, index);
});
}
}
this.prometheusService.setSilence(this.getSubmitData()).subscribe(
(resp) => {
- this.router.navigate(['/monitoring'], { fragment: 'silences' });
+ this.router.navigate(['/monitoring/silences']);
this.notificationService.show(
NotificationType.success,
this.getNotificationTile(resp.body['silenceId']),
private getSubmitData(): AlertmanagerSilence {
const payload = this.form.value;
delete payload.duration;
- payload.startsAt = payload.startsAt.toISOString();
- payload.endsAt = payload.endsAt.toISOString();
+ payload.startsAt = moment(payload.startsAt, this.datetimeFormat).toISOString();
+ payload.endsAt = moment(payload.endsAt, this.datetimeFormat).toISOString();
payload.matchers = this.matchers;
if (this.edit) {
payload.id = this.id;