@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
608 lines (602 loc) • 76.1 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, EventEmitter, Output, Input, Component, NgModule } from '@angular/core';
import * as i1 from '@c8y/ngx-components';
import { gettext, C8yTranslateDirective, C8yTranslatePipe, IconDirective, FormGroupComponent, RequiredInputPlaceholderDirective, EmailsValidatorDirective, Permissions, LoadingComponent, EmptyStateComponent, CoreModule, FormsModule as FormsModule$1 } from '@c8y/ngx-components';
import { orderBy, remove, some, isEqual, cloneDeep, isEmpty } from 'lodash-es';
import * as i2 from '@c8y/client';
import * as i3 from '@ngx-translate/core';
import { formatDate, NgIf, NgFor, DecimalPipe } from '@angular/common';
import * as i2$1 from 'ngx-bootstrap/modal';
import * as i4 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { BsDropdownDirective, BsDropdownToggleDirective, BsDropdownMenuDirective, BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { downgradeComponent, downgradeInjectable } from '@angular/upgrade/static';
import * as angular from 'angular';
import { registerNgModule } from '@c8y/ng1-modules';
class ReportsService {
constructor(alertService, inventoryService, client, translateService) {
this.alertService = alertService;
this.inventoryService = inventoryService;
this.client = client;
this.translateService = translateService;
this.microserviceUrl = '/service/reporting';
this.headers = { 'Content-Type': 'application/json' };
this.isReportAgentSubscribed = true;
this.REPORT_AGENT_NOT_SUBSCRIBED_EXPECTED_ERROR_LOWER_CASE = 'microservice/not found';
}
async getExport(exportId) {
let exp;
const exportDetail = await this.inventoryService.detail(exportId);
const { data, res } = exportDetail;
if (res.status !== 200) {
this.alertService.addServerFailure({ data, res });
}
else {
exp = data ? data : {};
}
return exp;
}
async getScheduleList(exportId) {
const exp = await this.getExport(exportId);
return this.extractScheduleListFromExport(exp);
}
extractScheduleListFromExport(exp) {
let scheduleList;
if (exp) {
scheduleList = exp.c8y_ScheduleConfiguration ? exp.c8y_ScheduleConfiguration : [];
}
return orderBy(scheduleList, ['timestamp'], ['desc']);
}
async addSchedule(schedule, exportId) {
return await this.updateSchedules(exportId, [], [schedule]);
}
async updateSchedule(oldSchedule, schedule, exportId) {
return await this.updateSchedules(exportId, [oldSchedule], [schedule]);
}
async updateSchedules(exportId, schedulesToRemove = [], schedulesToAdd = []) {
let success = false;
const exp = await this.getExport(exportId);
const schedules = this.extractScheduleListFromExport(exp);
remove(schedules, (schedule) => some(schedulesToRemove, (scheduleToRemove) => isEqual(schedule, scheduleToRemove)));
schedules.push(...schedulesToAdd);
exp.c8y_ScheduleConfiguration = schedules;
const { data, res } = await this.inventoryService.update(exp);
if (res.status === 200) {
success = await this.reschedule(exportId);
}
else {
this.alertService.addServerFailure({ data, res });
}
return success;
}
async reschedule(exportId) {
const options = {
method: 'PUT',
headers: this.headers
};
const rescheduling = await this.client.fetch(`${this.microserviceUrl}/schedule/${exportId}`, options);
return rescheduling.status === 200;
}
async deleteSchedule(schedule, exportId) {
return await this.updateSchedules(exportId, [schedule], []);
}
/**
* Removes report configuration.
*
* Note: fallback strategy is based on error code returned by backend
* in case of missing subscription for report-agent microservice.
* @param config entity of report configuration
* @returns Response wrapped in [[IFetchResponse]]
*/
async removeConfiguration(config) {
let res;
if (!this.isReportAgentSubscribed) {
res = await this.fallbackConfigurationRemoval(config);
}
else {
res = await this.normalConfigurationRemoval(config);
if (res.status === 404) {
const data = await res.json();
if (data &&
data.error &&
data.error.toLowerCase() === this.REPORT_AGENT_NOT_SUBSCRIBED_EXPECTED_ERROR_LOWER_CASE) {
res = await this.fallbackConfigurationRemoval(config);
this.isReportAgentSubscribed = false;
}
}
}
return res;
}
async normalConfigurationRemoval(config) {
const url = `${this.microserviceUrl}/config/${config.id}`;
return await this.client.fetch(url, { method: 'DELETE' });
}
async fallbackConfigurationRemoval(config) {
let res;
try {
res = (await this.inventoryService.delete(config)).res;
}
catch (e) {
// this could be an error related to not existing object or anything else which makes request return error status code
// in case of concurrent removal everything is fine, therefor warning message. But it might not recover from some errors
this.alertService.addServerFailure(e, 'warning');
}
return res;
}
async requestExport(config) {
const response = await this.client.fetch(`export/exports?configurationId=${config.id}`);
if (response.ok) {
return;
}
throw new Error(`Failed to request export: ${response.statusText}`);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ReportsService, deps: [{ token: i1.AlertService }, { token: i2.InventoryService }, { token: i2.FetchClient }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ReportsService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ReportsService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [{ type: i1.AlertService }, { type: i2.InventoryService }, { type: i2.FetchClient }, { type: i3.TranslateService }] });
var ActionType;
(function (ActionType) {
ActionType["CREATE"] = "create";
ActionType["EDIT"] = "edit";
ActionType["DUPLICATE"] = "duplicate";
})(ActionType || (ActionType = {}));
var Base;
(function (Base) {
Base[Base["Initial"] = 1] = "Initial";
Base[Base["Hour"] = 2] = "Hour";
Base[Base["Day"] = 3] = "Day";
Base[Base["Week"] = 4] = "Week";
Base[Base["Month"] = 5] = "Month";
Base[Base["Year"] = 6] = "Year";
})(Base || (Base = {}));
class CronService {
constructor(translateService) {
this.translateService = translateService;
this.daysOfWeekPosix = [];
this.daysOfMonth = [
{ value: '1', label: '1.' },
{ value: '2', label: '2.' },
{ value: '3', label: '3.' },
{ value: '4', label: '4.' },
{ value: '5', label: '5.' },
{ value: '6', label: '6.' },
{ value: '7', label: '7.' },
{ value: '8', label: '8.' },
{ value: '9', label: '9.' },
{ value: '10', label: '10.' },
{ value: '11', label: '11.' },
{ value: '12', label: '12.' },
{ value: '13', label: '13.' },
{ value: '14', label: '14.' },
{ value: '15', label: '15.' },
{ value: '16', label: '16.' },
{ value: '17', label: '17.' },
{ value: '18', label: '18.' },
{ value: '19', label: '19.' },
{ value: '20', label: '20.' },
{ value: '21', label: '21.' },
{ value: '22', label: '22.' },
{ value: '23', label: '23.' },
{ value: '24', label: '24.' },
{ value: '25', label: '25.' },
{ value: '26', label: '26.' },
{ value: '27', label: '27.' },
{ value: '28', label: '28.' },
{ value: '29', label: '29.' },
{ value: '30', label: '30.' },
{ value: '31', label: '31.' }
];
this.months = [];
this.hours = [];
this.minutes = [];
this.intervals = [
{ value: 2, label: gettext('Hour') },
{ value: 3, label: gettext('Day') },
{ value: 4, label: gettext('Week') },
{ value: 5, label: gettext('Month') },
{ value: 6, label: gettext('Year') }
];
for (let x = 0; x < 24; x++) {
this.hours.push({ value: x.toString(), label: `${x}` });
}
for (let x = 0; x < 60; x = x + 5) {
this.minutes.push({ value: x.toString(), label: `${x}` });
}
for (let x = 0; x < 7; x++) {
this.daysOfWeekPosix.push({
value: x.toString(),
label: this.getWeekDayName({ weekday: x })
});
}
for (let x = 1; x < 13; x++) {
this.months.push({
value: x.toString(),
label: this.getMonthName({ month: x })
});
}
}
generateCron(cronConfig) {
let cron = '';
cron = cronConfig.minute ? `${cronConfig.minute}` : '*';
cron += cronConfig.hour ? ` ${cronConfig.hour}` : ' *';
cron += cronConfig.day ? ` ${cronConfig.day}` : ' *';
cron += cronConfig.month ? ` ${cronConfig.month}` : ' *';
cron += cronConfig.weekday ? ` ${cronConfig.weekday}` : ' *';
return cron;
}
generateCronConfig(cron) {
const parts = cron.split(/\s+/);
const cronConfig = {
minute: parts[0],
hour: parts[1],
day: parts[2],
month: parts[3],
weekday: parts[4]
};
return cronConfig;
}
getBase(cronConfig) {
let base = Base.Initial;
if (cronConfig.minute !== '*' &&
cronConfig.hour === '*' &&
cronConfig.day === '*' &&
cronConfig.month === '*' &&
cronConfig.weekday === '*') {
base = Base.Hour;
}
else if (cronConfig.minute !== '*' &&
cronConfig.hour !== '*' &&
cronConfig.day === '*' &&
cronConfig.month === '*' &&
cronConfig.weekday === '*') {
base = Base.Day;
}
else if (cronConfig.minute !== '*' &&
cronConfig.hour !== '*' &&
cronConfig.day === '*' &&
cronConfig.month === '*' &&
cronConfig.weekday !== '*') {
base = Base.Week;
}
else if (cronConfig.minute !== '*' &&
cronConfig.hour !== '*' &&
cronConfig.day !== '*' &&
cronConfig.month === '*' &&
cronConfig.weekday === '*') {
base = Base.Month;
}
else if (cronConfig.minute !== '*' &&
cronConfig.hour !== '*' &&
cronConfig.day !== '*' &&
cronConfig.month !== '*' &&
cronConfig.weekday === '*') {
base = Base.Year;
}
else {
// cronConfig invalid
}
return base;
}
validateModels(base, cronConfig) {
let valid;
switch (base) {
case Base.Initial: // Please select
valid = false;
break;
case Base.Hour:
if (cronConfig.minute !== '*') {
valid = true;
}
else {
valid = false;
}
break;
case Base.Day:
if (cronConfig.minute !== '*' && cronConfig.hour !== '*') {
valid = true;
}
else {
valid = false;
}
break;
case Base.Week:
if (cronConfig.minute !== '*' && cronConfig.hour !== '*' && cronConfig.weekday !== '*') {
valid = true;
}
else {
valid = false;
}
break;
case Base.Month:
if (cronConfig.minute !== '*' && cronConfig.hour !== '*' && cronConfig.day !== '*') {
valid = true;
}
else {
valid = false;
}
break;
case Base.Year:
if (cronConfig.minute !== '*' &&
cronConfig.hour !== '*' &&
cronConfig.day !== '*' &&
cronConfig.month !== '*') {
valid = true;
}
else {
valid = false;
}
break;
default:
valid = false;
}
return valid;
}
clearNextModels(base, cronConfig) {
if (base === Base.Initial) {
// please select, delete all
// cron expression: every minute at second 0
cronConfig.minute = '*';
cronConfig.hour = '*';
cronConfig.day = '*';
cronConfig.month = '*';
cronConfig.weekday = '*';
}
else if (base === Base.Hour) {
// hour, don't delete minutes
// cron expression: every hour, at whatever minute, at second 0
cronConfig.minute = cronConfig.minute === '*' ? this.minutes[0].value : cronConfig.minute;
cronConfig.hour = '*';
cronConfig.day = '*';
cronConfig.month = '*';
cronConfig.weekday = '*';
}
else if (base === Base.Day) {
// day, don't delete minutes and hours
// cron expression: every day of every month, at whatever hour and minute, at second 0
cronConfig.minute = cronConfig.minute === '*' ? this.minutes[0].value : cronConfig.minute;
cronConfig.hour = cronConfig.hour === '*' ? this.hours[0].value : cronConfig.hour;
cronConfig.day = '*';
cronConfig.month = '*';
cronConfig.weekday = '*';
}
else if (base === Base.Week) {
// week, delete month and day
// cron expression: every month, at whatever weekday, hour and minute, at second 0
cronConfig.minute = cronConfig.minute === '*' ? this.minutes[0].value : cronConfig.minute;
cronConfig.hour = cronConfig.hour === '*' ? this.hours[0].value : cronConfig.hour;
cronConfig.day = '*';
cronConfig.month = '*';
cronConfig.weekday =
cronConfig.weekday === '*' || cronConfig.weekday === '?'
? this.daysOfWeekPosix[0].value
: cronConfig.weekday;
}
else if (base === Base.Month) {
// month, delete month and weekday
// cron expression: every month, at whatever day of month, hour and minute, at second 0
cronConfig.minute = cronConfig.minute === '*' ? this.minutes[0].value : cronConfig.minute;
cronConfig.hour = cronConfig.hour === '*' ? this.hours[0].value : cronConfig.hour;
cronConfig.day = cronConfig.day === '*' ? this.daysOfMonth[0].value : cronConfig.day;
cronConfig.month = '*';
cronConfig.weekday = '*';
}
else if (base === Base.Year) {
// year, delete weekday
// cron expression: every year, at whatever month, day of month, hour and minute, at second 0
cronConfig.minute = cronConfig.minute === '*' ? this.minutes[0].value : cronConfig.minute;
cronConfig.hour = cronConfig.hour === '*' ? this.hours[0].value : cronConfig.hour;
cronConfig.day = cronConfig.day === '*' ? this.daysOfMonth[0].value : cronConfig.day;
cronConfig.month = cronConfig.month === '*' ? this.months[0].value : cronConfig.month;
cronConfig.weekday = '*';
}
}
getWeekDayName(cronConfig) {
const date = new Date(0);
const firstSundayDate = date.getDate() + 3; // because we know date 0 was on Thursday...
date.setDate(firstSundayDate + parseInt(cronConfig.weekday, 10));
return formatDate(date, 'EEEE', this.translateService.currentLang);
}
getMonthDayName(cronConfig) {
let name = '';
this.daysOfMonth.forEach(item => {
if (item.value === cronConfig.day) {
name = item.label;
}
});
return name;
}
getMonthName(cronConfig) {
const date = new Date(0);
date.setMonth(parseInt(cronConfig.month, 10) - 1);
return formatDate(date, 'LLLL', this.translateService.currentLang);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CronService, deps: [{ token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CronService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CronService, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i3.TranslateService }] });
class CronComponent {
constructor(cronService) {
this.cronService = cronService;
this.emitter = new EventEmitter();
this.emittedCron = {
valid: false,
cron: ''
};
this.base = Base.Initial;
//
}
ngOnInit() {
this.daysOfWeekPosix = this.cronService.daysOfWeekPosix;
this.daysOfMonth = this.cronService.daysOfMonth;
this.months = this.cronService.months;
this.hours = this.cronService.hours;
this.minutes = this.cronService.minutes;
this.intervals = this.cronService.intervals;
this.cronConfig = this.cronService.generateCronConfig(this.cronIn);
this.base = this.cronService.getBase(this.cronConfig);
}
onChangeSelect() {
this.cronService.clearNextModels(this.base, this.cronConfig);
this.emittedCron.valid = this.cronService.validateModels(this.base, this.cronConfig);
this.emittedCron.cron = this.cronService.generateCron(this.cronConfig);
this.emitter.emit(this.emittedCron);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CronComponent, deps: [{ token: CronService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: CronComponent, isStandalone: true, selector: "cron", inputs: { cronIn: "cronIn" }, outputs: { emitter: "emitter" }, ngImport: i0, template: "<div class=\"cron-wrap\">\n <div class=\"form-group smart-cron-job-every\">\n <label for=\"smart-cron-job-every\" class=\"control-label\" translate>Interval</label>\n <div>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"cron-select form-control\"\n id=\"smart-cron-job-every\"\n [(ngModel)]=\"base\"\n required=\"true\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngIf=\"base === 1\" value=\"1\" translate>Select\u2026</option>\n <option *ngFor=\"let baseInterval of intervals\" [ngValue]=\"baseInterval.value\">\n {{ baseInterval.label | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"form-group smart-cron-job-on col-md-6\" *ngIf=\"base == 4\">\n <label class=\"control-label\" for=\"smart-cron-job-on\" translate>Day</label>\n\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"cron-select form-control day-value\"\n id=\"smart-cron-job-on\"\n [(ngModel)]=\"cronConfig.weekday\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngFor=\"let dayOfWeek of daysOfWeekPosix\" [ngValue]=\"dayOfWeek.value\">\n {{ dayOfWeek.label | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n\n <div class=\"form-group smart-cron-job-of col-md-6\" *ngIf=\"base == 6\">\n <label for=\"smart-cron-job-of\" class=\"control-label\" translate>Month</label>\n <div>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"smart-cron-job-of\"\n class=\"cron-select form-control month-value\"\n [(ngModel)]=\"cronConfig.month\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngFor=\"let month of months\" [ngValue]=\"month.value\">\n {{ month.label | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n\n <div class=\"form-group smart-cron-job-on-the col-md-6\" *ngIf=\"base >= 5\">\n <label for=\"smart-cron-job-on-the\" class=\"control-label\" translate>Day</label>\n <div>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"smart-cron-job-on-the\"\n class=\"cron-select form-control day-of-month-value\"\n [(ngModel)]=\"cronConfig.day\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngFor=\"let dayOfMonth of daysOfMonth\" [ngValue]=\"dayOfMonth.value\">\n {{ dayOfMonth.label | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"form-group smart-cron-job-at\" *ngIf=\"base >= 2\">\n <label for=\"smart-cron-job-at-hour\" class=\"control-label\">\n <span *ngIf=\"base >= 3\" translate>Time</span>\n <span *ngIf=\"base < 3\" translate>Minutes</span>\n </label>\n <div>\n <div class=\"form-inline\">\n <div class=\"c8y-select-wrapper\" *ngIf=\"base >= 3\">\n <select\n id=\"smart-cron-job-at-hour\"\n class=\"cron-select form-control hour-value\"\n [(ngModel)]=\"cronConfig.hour\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngFor=\"let hour of hours\" [ngValue]=\"hour.value\">\n {{ hour.value | number: '2.0-0' }}\n </option>\n </select>\n <span></span>\n </div>\n <span *ngIf=\"base >= 3\">:</span>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"cron-select form-control minute-value\"\n id=\"smart-cron-job-at-minute\"\n [(ngModel)]=\"cronConfig.minute\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngFor=\"let minute of minutes\" [ngValue]=\"minute.value\">\n {{ minute.value | number: '2.0-0' }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: DecimalPipe, name: "number" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: CronComponent, decorators: [{
type: Component,
args: [{ selector: 'cron', imports: [C8yTranslateDirective, FormsModule, NgIf, NgFor, C8yTranslatePipe, DecimalPipe], template: "<div class=\"cron-wrap\">\n <div class=\"form-group smart-cron-job-every\">\n <label for=\"smart-cron-job-every\" class=\"control-label\" translate>Interval</label>\n <div>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"cron-select form-control\"\n id=\"smart-cron-job-every\"\n [(ngModel)]=\"base\"\n required=\"true\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngIf=\"base === 1\" value=\"1\" translate>Select\u2026</option>\n <option *ngFor=\"let baseInterval of intervals\" [ngValue]=\"baseInterval.value\">\n {{ baseInterval.label | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n <div class=\"row\">\n <div class=\"form-group smart-cron-job-on col-md-6\" *ngIf=\"base == 4\">\n <label class=\"control-label\" for=\"smart-cron-job-on\" translate>Day</label>\n\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"cron-select form-control day-value\"\n id=\"smart-cron-job-on\"\n [(ngModel)]=\"cronConfig.weekday\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngFor=\"let dayOfWeek of daysOfWeekPosix\" [ngValue]=\"dayOfWeek.value\">\n {{ dayOfWeek.label | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n\n <div class=\"form-group smart-cron-job-of col-md-6\" *ngIf=\"base == 6\">\n <label for=\"smart-cron-job-of\" class=\"control-label\" translate>Month</label>\n <div>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"smart-cron-job-of\"\n class=\"cron-select form-control month-value\"\n [(ngModel)]=\"cronConfig.month\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngFor=\"let month of months\" [ngValue]=\"month.value\">\n {{ month.label | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n\n <div class=\"form-group smart-cron-job-on-the col-md-6\" *ngIf=\"base >= 5\">\n <label for=\"smart-cron-job-on-the\" class=\"control-label\" translate>Day</label>\n <div>\n <div class=\"c8y-select-wrapper\">\n <select\n id=\"smart-cron-job-on-the\"\n class=\"cron-select form-control day-of-month-value\"\n [(ngModel)]=\"cronConfig.day\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngFor=\"let dayOfMonth of daysOfMonth\" [ngValue]=\"dayOfMonth.value\">\n {{ dayOfMonth.label | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"form-group smart-cron-job-at\" *ngIf=\"base >= 2\">\n <label for=\"smart-cron-job-at-hour\" class=\"control-label\">\n <span *ngIf=\"base >= 3\" translate>Time</span>\n <span *ngIf=\"base < 3\" translate>Minutes</span>\n </label>\n <div>\n <div class=\"form-inline\">\n <div class=\"c8y-select-wrapper\" *ngIf=\"base >= 3\">\n <select\n id=\"smart-cron-job-at-hour\"\n class=\"cron-select form-control hour-value\"\n [(ngModel)]=\"cronConfig.hour\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngFor=\"let hour of hours\" [ngValue]=\"hour.value\">\n {{ hour.value | number: '2.0-0' }}\n </option>\n </select>\n <span></span>\n </div>\n <span *ngIf=\"base >= 3\">:</span>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"cron-select form-control minute-value\"\n id=\"smart-cron-job-at-minute\"\n [(ngModel)]=\"cronConfig.minute\"\n (change)=\"onChangeSelect()\"\n >\n <option *ngFor=\"let minute of minutes\" [ngValue]=\"minute.value\">\n {{ minute.value | number: '2.0-0' }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
}], ctorParameters: () => [{ type: CronService }], propDecorators: { cronIn: [{
type: Input
}], emitter: [{
type: Output
}] } });
class ScheduleModalComponent {
constructor(reportsService, modalRef, cronService) {
this.reportsService = reportsService;
this.modalRef = modalRef;
this.cronService = cronService;
this.emitter = new EventEmitter();
this.ActionType = ActionType;
this.cronExpression = '* * * * *';
this.validCron = false;
this.emitterPayload = {
success: false,
message: '',
schedule: { timestamp: undefined, emailConfig: undefined, cronConfig: undefined }
};
this.placeholdersInfo = gettext('Available placeholders: {tenant-domain}, {host}, {binaryId}. Whole link to downloadable file is: {tenant-domain}/inventory/binaries/{binaryId}.');
}
ngOnInit() {
this.oldSchedule = cloneDeep(this.schedule);
this.populateEmailFieldsFromSchedule(this.schedule);
this.cronExpression = this.cronService.generateCron(this.schedule.cronConfig);
this.validCron = this.cronService.validateModels(this.cronService.getBase(this.schedule.cronConfig), this.schedule.cronConfig);
}
populateEmailFieldsFromSchedule(schedule) {
if (schedule.emailConfig.to && schedule.emailConfig.to.length) {
this.emailTo = schedule.emailConfig.to.toString();
}
if (schedule.emailConfig.cc && schedule.emailConfig.cc.length) {
this.emailCc = schedule.emailConfig.cc.toString();
}
if (schedule.emailConfig.bcc && schedule.emailConfig.bcc.length) {
this.emailBcc = schedule.emailConfig.bcc.toString();
}
if (schedule.emailConfig.replyTo) {
this.emailReplyTo = schedule.emailConfig.replyTo;
}
if (schedule.emailConfig.subject) {
this.emailSubject = schedule.emailConfig.subject;
}
if (schedule.emailConfig.text) {
this.emailText = schedule.emailConfig.text;
}
}
save() {
this.populateScheduleFromCronExpression();
this.populateScheduleFromEmailFields();
if (this.actionType === ActionType.CREATE || this.actionType === ActionType.DUPLICATE) {
const date = new Date();
const timestamp = date.getTime();
this.schedule.timestamp = timestamp;
}
this.emitterPayload.success = true;
this.emitterPayload.schedule = this.schedule;
this.modalRef.hide();
// signal to the parent component to update list
this.emitter.emit(this.emitterPayload);
}
cancel() {
this.modalRef.hide();
}
getCron(cron) {
this.validCron = cron.valid;
if (cron.valid) {
this.cronExpression = cron.cron;
}
}
populateScheduleFromCronExpression() {
this.schedule.cronConfig = this.cronService.generateCronConfig(this.cronExpression);
}
convertStringOfEmailsToArray(stringOfEmails) {
const arr = [];
if (stringOfEmails) {
const parts = stringOfEmails.split(',');
parts.forEach(item => {
if (item) {
arr.push(item);
}
});
}
return arr;
}
populateScheduleFromEmailFields() {
this.schedule.emailConfig.to = this.emailTo
? this.convertStringOfEmailsToArray(this.emailTo)
: null;
this.schedule.emailConfig.cc = this.emailCc
? this.convertStringOfEmailsToArray(this.emailCc)
: null;
this.schedule.emailConfig.bcc = this.emailBcc
? this.convertStringOfEmailsToArray(this.emailBcc)
: null;
this.schedule.emailConfig.replyTo = this.emailReplyTo;
this.schedule.emailConfig.subject = this.emailSubject;
this.schedule.emailConfig.text = this.emailText;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ScheduleModalComponent, deps: [{ token: ReportsService }, { token: i2$1.BsModalRef }, { token: CronService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: ScheduleModalComponent, isStandalone: true, selector: "schedule-modal", outputs: { emitter: "emitter" }, ngImport: i0, template: "<div class=\"modal-header dialog-header\">\n <i c8yIcon=\"c8y-report\"></i>\n <h4 id=\"modal-title\">\n <span *ngIf=\"actionType === ActionType.CREATE\" translate>New export schedule</span>\n <span *ngIf=\"actionType === ActionType.EDIT\" translate>Edit export schedule</span>\n <span *ngIf=\"actionType === ActionType.DUPLICATE\" translate>Duplicate export schedule</span>\n </h4>\n</div>\n\n<div class=\"modal-body\" id=\"modal-body\">\n <p class=\"lead text-center p-t-24 m-b-0\" translate>On schedule send export via email</p>\n</div>\n<div class=\"modal-inner-scroll smart-rule-control\">\n <form #scheduleForm=\"ngForm\" class=\"edit-smart-rule-details\">\n <div class=\"list-group\">\n <div class=\"list-group-item bg-level-1\">\n <div class=\"smart-list-icon-label\">\n <span class=\"dot bg-primary-light m-r-8\">1</span>\n <strong translate>Frequency</strong>\n </div>\n <div class=\"p-t-16\">\n <div class=\"form-group\">\n <cron [cronIn]=\"cronExpression\" (emitter)=\"getCron($event)\" name=\"cron\"></cron>\n </div>\n </div>\n </div>\n <div class=\"list-group-item\">\n <div class=\"smart-list-icon-label\">\n <span class=\"dot bg-primary-light m-r-8\">2</span>\n <div class=\"d-inline-block\">\n <strong translate>Send email</strong>\n <p class=\"help-block text-muted small p-absolute\">\n <i class=\"text-info m-r-4 text-14\" c8yIcon=\"info-circle\"></i>\n <span translate\n >Enter one or more valid email addresses, separated with a comma.</span\n >\n </p>\n </div>\n </div>\n <div class=\"p-t-24\">\n <div class=\"form-group\">\n <label class=\"control-label\" translate>Send to</label>\n <c8y-form-group>\n <input\n emails\n type=\"text\"\n class=\"form-control\"\n name=\"to\"\n [(ngModel)]=\"emailTo\"\n placeholder=\"{{\n 'e.g. joe.doe@example.com,john.smith@example.com`LOCALIZE`' | translate\n }}\"\n required\n />\n </c8y-form-group>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\" translate>CC</label>\n <c8y-form-group>\n <input\n emails\n type=\"text\"\n class=\"form-control span\"\n name=\"cc\"\n placeholder=\"{{\n 'e.g. joe.doe@example.com,john.smith@example.com`LOCALIZE`' | translate\n }}\"\n [(ngModel)]=\"emailCc\"\n />\n </c8y-form-group>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\" translate>BCC</label>\n <c8y-form-group>\n <input\n emails\n type=\"text\"\n class=\"form-control span\"\n name=\"bcc\"\n placeholder=\"{{\n 'e.g. joe.doe@example.com,john.smith@example.com`LOCALIZE`' | translate\n }}\"\n [(ngModel)]=\"emailBcc\"\n />\n </c8y-form-group>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\" translate>Reply to (single email address)</label>\n <c8y-form-group>\n <input\n email\n type=\"text\"\n class=\"form-control span\"\n name=\"replyTo\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [(ngModel)]=\"emailReplyTo\"\n />\n </c8y-form-group>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\" translate>Subject</label>\n <c8y-form-group>\n <input\n type=\"text\"\n class=\"form-control span\"\n name=\"subject\"\n [(ngModel)]=\"emailSubject\"\n placeholder=\"{{ 'e.g. Daily report' | translate }}\"\n required\n />\n </c8y-form-group>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\" translate>Message</label>\n <c8y-form-group>\n <textarea\n class=\"form-control\"\n name=\"text\"\n [(ngModel)]=\"emailText\"\n placeholder=\"{{ 'Message' | translate }}\"\n rows=\"4\"\n required\n ></textarea>\n <p class=\"help-block text-muted\">\n {{ placeholdersInfo | translate }}\n </p>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n </form>\n</div>\n\n<div class=\"modal-footer\">\n <button class=\"btn btn-default\" (click)=\"cancel()\" title=\"{{ 'Cancel' | translate }}\">\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n (click)=\"save()\"\n [disabled]=\"!validCron || !scheduleForm.form.valid\"\n >\n <span>\n <span *ngIf=\"actionType === ActionType.CREATE\" title=\"{{ 'Create' | translate }}\">\n {{ 'Create' | translate }}\n </span>\n <span *ngIf=\"actionType === ActionType.EDIT\" title=\"{{ 'Save' | translate }}\">\n {{ 'Save' | translate }}\n </span>\n <span *ngIf=\"actionType === ActionType.DUPLICATE\" title=\"{{ 'Duplicate' | translate }}\">\n {{ 'Duplicate' | translate }}\n </span>\n </span>\n </button>\n</div>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4.EmailValidator, selector: "[email][formControlName],[email][formControl],[email][ngModel]", inputs: ["email"] }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: CronComponent, selector: "cron", inputs: ["cronIn"], outputs: ["emitter"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: EmailsValidatorDirective, selector: "[emails][formControlName],[emails][formControl],[emails][ngModel]", inputs: ["emails"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ScheduleModalComponent, decorators: [{
type: Component,
args: [{ selector: 'schedule-modal', imports: [
IconDirective,
NgIf,
C8yTranslateDirective,
FormsModule,
CronComponent,
FormGroupComponent,
RequiredInputPlaceholderDirective,
EmailsValidatorDirective,
C8yTranslatePipe
], template: "<div class=\"modal-header dialog-header\">\n <i c8yIcon=\"c8y-report\"></i>\n <h4 id=\"modal-title\">\n <span *ngIf=\"actionType === ActionType.CREATE\" translate>New export schedule</span>\n <span *ngIf=\"actionType === ActionType.EDIT\" translate>Edit export schedule</span>\n <span *ngIf=\"actionType === ActionType.DUPLICATE\" translate>Duplicate export schedule</span>\n </h4>\n</div>\n\n<div class=\"modal-body\" id=\"modal-body\">\n <p class=\"lead text-center p-t-24 m-b-0\" translate>On schedule send export via email</p>\n</div>\n<div class=\"modal-inner-scroll smart-rule-control\">\n <form #scheduleForm=\"ngForm\" class=\"edit-smart-rule-details\">\n <div class=\"list-group\">\n <div class=\"list-group-item bg-level-1\">\n <div class=\"smart-list-icon-label\">\n <span class=\"dot bg-primary-light m-r-8\">1</span>\n <strong translate>Frequency</strong>\n </div>\n <div class=\"p-t-16\">\n <div class=\"form-group\">\n <cron [cronIn]=\"cronExpression\" (emitter)=\"getCron($event)\" name=\"cron\"></cron>\n </div>\n </div>\n </div>\n <div class=\"list-group-item\">\n <div class=\"smart-list-icon-label\">\n <span class=\"dot bg-primary-light m-r-8\">2</span>\n <div class=\"d-inline-block\">\n <strong translate>Send email</strong>\n <p class=\"help-block text-muted small p-absolute\">\n <i class=\"text-info m-r-4 text-14\" c8yIcon=\"info-circle\"></i>\n <span translate\n >Enter one or more valid email addresses, separated with a comma.</span\n >\n </p>\n </div>\n </div>\n <div class=\"p-t-24\">\n <div class=\"form-group\">\n <label class=\"control-label\" translate>Send to</label>\n <c8y-form-group>\n <input\n emails\n type=\"text\"\n class=\"form-control\"\n name=\"to\"\n [(ngModel)]=\"emailTo\"\n placeholder=\"{{\n 'e.g. joe.doe@example.com,john.smith@example.com`LOCALIZE`' | translate\n }}\"\n required\n />\n </c8y-form-group>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\" translate>CC</label>\n <c8y-form-group>\n <input\n emails\n type=\"text\"\n class=\"form-control span\"\n name=\"cc\"\n placeholder=\"{{\n 'e.g. joe.doe@example.com,john.smith@example.com`LOCALIZE`' | translate\n }}\"\n [(ngModel)]=\"emailCc\"\n />\n </c8y-form-group>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\" translate>BCC</label>\n <c8y-form-group>\n <input\n emails\n type=\"text\"\n class=\"form-control span\"\n name=\"bcc\"\n placeholder=\"{{\n 'e.g. joe.doe@example.com,john.smith@example.com`LOCALIZE`' | translate\n }}\"\n [(ngModel)]=\"emailBcc\"\n />\n </c8y-form-group>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\" translate>Reply to (single email address)</label>\n <c8y-form-group>\n <input\n email\n type=\"text\"\n class=\"form-control span\"\n name=\"replyTo\"\n placeholder=\"{{ 'e.g. joe.doe@example.com`LOCALIZE`' | translate }}\"\n [(ngModel)]=\"emailReplyTo\"\n />\n </c8y-form-group>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\" translate>Subject</label>\n <c8y-form-group>\n <input\n type=\"text\"\n class=\"form-control span\"\n name=\"subject\"\n [(ngModel)]=\"emailSubject\"\n placeholder=\"{{ 'e.g. Daily report' | translate }}\"\n required\n />\n </c8y-form-group>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\" translate>Message</label>\n <c8y-form-group>\n <textarea\n class=\"form-control\"\n name=\"text\"\n [(ngModel)]=\"emailText\"\n placeholder=\"{{ 'Message' | translate }}\"\n rows=\"4\"\n required\n ></textarea>\n <p class=\"help-block text-muted\">\n {{ placeholdersInfo | translate }}\n </p>\n </c8y-form-group>\n </div>\n </div>\n </div>\n </div>\n </form>\n</div>\n\n<div class=\"modal-footer\">\n <button class=\"btn btn-default\" (click)=\"cancel()\" title=\"{{ 'Cancel' | translate }}\">\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n (click)=\"save()\"\n [disabled]=\"!validCron || !scheduleForm.form.valid\"\n >\n <span>\n <span *ngIf=\"actionType === ActionType.CREATE\" title=\"{{ 'Create' | translate }}\">\n {{ 'Create' | translate }}\n </span>\n <span *ngIf=\"actionType === ActionType.EDIT\" title=\"{{ 'Save' | translate }}\">\n {{ 'Save' | translate }}\n </span>\n <span *ngIf=\"actionType === ActionType.DUPLICATE\" title=\"{{ 'Duplicate' | translate }}\">\n {{ 'Duplicate' | translate }}\n </span>\n </span>\n </button>\n</div>\n" }]
}], ctorParameters: () => [{ type: ReportsService }, { type: i2$1.BsModalRef }, { type: CronService }], propDecorators: { emitter: [{
type: Output
}] } });
class ExportSchedulesComponent {
set exportId(exportId) {
this._exportId = exportId;
}
constructor(reportsService, bsModalService, cronService, translateService, userService, optionsService) {
this.reportsService = reportsService;
this.bsModalService = bsModalService;
this.cronService = cronService;
this.translateService = translateService;
this.userService = userService;
this.optionsService = optionsService;
this.onSchedulesUpdate = new EventEmitter();
this.scheduleList = [];
this.initialSchedule = {
timestamp: null,
emailConfig: {
to: [],
cc: [],
bcc: [],
replyTo: '',
text: '',
subject: ''
},
cronConfig: {
minute: '0',
hour: '0',
day: '1',
month: '1',
weekday: