UNPKG

cron-editor

Version:

A cron expression generator to be used in Angular applications

791 lines (785 loc) 137 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/forms'), require('@angular/common')) : typeof define === 'function' && define.amd ? define('cron-editor', ['exports', '@angular/core', '@angular/forms', '@angular/common'], factory) : (factory((global['cron-editor'] = {}),global.ng.core,global.ng.forms,global.ng.common)); }(this, (function (exports,core,forms,common) { 'use strict'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed 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 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ var Days = { 'SUN': 'Sunday', 'MON': 'Monday', 'TUE': 'Tuesday', 'WED': 'Wednesday', 'THU': 'Thursday', 'FRI': 'Friday', 'SAT': 'Saturday' }; /** @type {?} */ var MonthWeeks = { '#1': 'First', '#2': 'Second', '#3': 'Third', '#4': 'Fourth', '#5': 'Fifth', 'L': 'Last' }; /** @enum {number} */ var Months = { January: 1, February: 2, March: 3, April: 4, May: 5, June: 6, July: 7, August: 8, September: 9, October: 10, November: 11, December: 12, }; Months[Months.January] = 'January'; Months[Months.February] = 'February'; Months[Months.March] = 'March'; Months[Months.April] = 'April'; Months[Months.May] = 'May'; Months[Months.June] = 'June'; Months[Months.July] = 'July'; Months[Months.August] = 'August'; Months[Months.September] = 'September'; Months[Months.October] = 'October'; Months[Months.November] = 'November'; Months[Months.December] = 'December'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ // @dynamic var // @dynamic Utils = /** @class */ (function () { function Utils() { } /** This returns a range of numbers. Starts from 0 if 'startFrom' is not set */ /** * This returns a range of numbers. Starts from 0 if 'startFrom' is not set * @param {?} startFrom * @param {?} until * @return {?} */ Utils.getRange = /** * This returns a range of numbers. Starts from 0 if 'startFrom' is not set * @param {?} startFrom * @param {?} until * @return {?} */ function (startFrom, until) { return Array.from({ length: (until + 1 - startFrom) }, function (_, k) { return k + startFrom; }); }; return Utils; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ var CronEditorComponent = /** @class */ (function () { function CronEditorComponent() { // the name is an Angular convention, @Input variable name + "Change" suffix this.cronChange = new core.EventEmitter(); this.selectOptions = this.getSelectOptions(); } Object.defineProperty(CronEditorComponent.prototype, "cron", { get: /** * @return {?} */ function () { return this.localCron; }, set: /** * @param {?} value * @return {?} */ function (value) { this.localCron = value; this.cronChange.emit(this.localCron); }, enumerable: true, configurable: true }); /** * @return {?} */ CronEditorComponent.prototype.ngOnInit = /** * @return {?} */ function () { if (this.options.removeSeconds) { this.options.hideSeconds = true; } this.state = this.getDefaultState(); this.handleModelChange(this.cron); }; /** * @param {?} changes * @return {?} */ CronEditorComponent.prototype.ngOnChanges = /** * @param {?} changes * @return {?} */ function (changes) { /** @type {?} */ var newCron = changes['cron']; if (newCron && !newCron.firstChange) { this.handleModelChange(this.cron); } }; /** * @param {?} tab * @return {?} */ CronEditorComponent.prototype.setActiveTab = /** * @param {?} tab * @return {?} */ function (tab) { if (!this.disabled) { this.activeTab = tab; this.regenerateCron(); } }; /** * @param {?} day * @return {?} */ CronEditorComponent.prototype.dayDisplay = /** * @param {?} day * @return {?} */ function (day) { return Days[day]; }; /** * @param {?} monthWeekNumber * @return {?} */ CronEditorComponent.prototype.monthWeekDisplay = /** * @param {?} monthWeekNumber * @return {?} */ function (monthWeekNumber) { return MonthWeeks[monthWeekNumber]; }; /** * @param {?} month * @return {?} */ CronEditorComponent.prototype.monthDisplay = /** * @param {?} month * @return {?} */ function (month) { return Months[month]; }; /** * @param {?} month * @return {?} */ CronEditorComponent.prototype.monthDayDisplay = /** * @param {?} month * @return {?} */ function (month) { if (month === 'L') { return 'Last Day'; } else if (month === 'LW') { return 'Last Weekday'; } else if (month === '1W') { return 'First Weekday'; } else { return "" + month + this.getOrdinalSuffix(month) + " day"; } }; /** * @return {?} */ CronEditorComponent.prototype.regenerateCron = /** * @return {?} */ function () { var _this = this; this.isDirty = true; switch (this.activeTab) { case 'minutes': this.cron = "0/" + this.state.minutes.minutes + " * 1/1 * ?"; if (!this.options.removeSeconds) { this.cron = this.state.minutes.seconds + " " + this.cron; } if (!this.options.removeYears) { this.cron = this.cron + " *"; } break; case 'hourly': this.cron = this.state.hourly.minutes + " 0/" + this.state.hourly.hours + " 1/1 * ?"; if (!this.options.removeSeconds) { this.cron = this.state.hourly.seconds + " " + this.cron; } if (!this.options.removeYears) { this.cron = this.cron + " *"; } break; case 'daily': switch (this.state.daily.subTab) { case 'everyDays': // tslint:disable-next-line:max-line-length this.cron = this.state.daily.everyDays.minutes + " " + this.hourToCron(this.state.daily.everyDays.hours, this.state.daily.everyDays.hourType) + " 1/" + this.state.daily.everyDays.days + " * ?"; if (!this.options.removeSeconds) { this.cron = this.state.daily.everyDays.seconds + " " + this.cron; } if (!this.options.removeYears) { this.cron = this.cron + " *"; } break; case 'everyWeekDay': // tslint:disable-next-line:max-line-length this.cron = this.state.daily.everyWeekDay.minutes + " " + this.hourToCron(this.state.daily.everyWeekDay.hours, this.state.daily.everyWeekDay.hourType) + " ? * MON-FRI"; if (!this.options.removeSeconds) { this.cron = this.state.daily.everyWeekDay.seconds + " " + this.cron; } if (!this.options.removeYears) { this.cron = this.cron + " *"; } break; default: throw new Error('Invalid cron daily subtab selection'); } break; case 'weekly': /** @type {?} */ var days = this.selectOptions.days .reduce(function (acc, day) { return _this.state.weekly[day] ? acc.concat([day]) : acc; }, []) .join(','); this.cron = this.state.weekly.minutes + " " + this.hourToCron(this.state.weekly.hours, this.state.weekly.hourType) + " ? * " + days; if (!this.options.removeSeconds) { this.cron = this.state.weekly.seconds + " " + this.cron; } if (!this.options.removeYears) { this.cron = this.cron + " *"; } break; case 'monthly': switch (this.state.monthly.subTab) { case 'specificDay': /** @type {?} */ var day = this.state.monthly.runOnWeekday ? this.state.monthly.specificDay.day + "W" : this.state.monthly.specificDay.day; // tslint:disable-next-line:max-line-length this.cron = this.state.monthly.specificDay.minutes + " " + this.hourToCron(this.state.monthly.specificDay.hours, this.state.monthly.specificDay.hourType) + " " + day + " 1/" + this.state.monthly.specificDay.months + " ?"; if (!this.options.removeSeconds) { this.cron = this.state.monthly.specificDay.seconds + " " + this.cron; } if (!this.options.removeYears) { this.cron = this.cron + " *"; } break; case 'specificWeekDay': // tslint:disable-next-line:max-line-length this.cron = this.state.monthly.specificWeekDay.minutes + " " + this.hourToCron(this.state.monthly.specificWeekDay.hours, this.state.monthly.specificWeekDay.hourType) + " ? " + this.state.monthly.specificWeekDay.startMonth + "/" + this.state.monthly.specificWeekDay.months + " " + this.state.monthly.specificWeekDay.day + this.state.monthly.specificWeekDay.monthWeek; if (!this.options.removeSeconds) { this.cron = this.state.monthly.specificWeekDay.seconds + " " + this.cron; } if (!this.options.removeYears) { this.cron = this.cron + " *"; } break; default: throw new Error('Invalid cron monthly subtab selection'); } break; case 'yearly': switch (this.state.yearly.subTab) { case 'specificMonthDay': // tslint:disable-next-line:max-line-length /** @type {?} */ var day = this.state.yearly.runOnWeekday ? this.state.yearly.specificMonthDay.day + "W" : this.state.yearly.specificMonthDay.day; // tslint:disable-next-line:max-line-length this.cron = this.state.yearly.specificMonthDay.minutes + " " + this.hourToCron(this.state.yearly.specificMonthDay.hours, this.state.yearly.specificMonthDay.hourType) + " " + day + " " + this.state.yearly.specificMonthDay.month + " ?"; if (!this.options.removeSeconds) { this.cron = this.state.yearly.specificMonthDay.seconds + " " + this.cron; } if (!this.options.removeYears) { this.cron = this.cron + " *"; } break; case 'specificMonthWeek': // tslint:disable-next-line:max-line-length this.cron = this.state.yearly.specificMonthWeek.minutes + " " + this.hourToCron(this.state.yearly.specificMonthWeek.hours, this.state.yearly.specificMonthWeek.hourType) + " ? " + this.state.yearly.specificMonthWeek.month + " " + this.state.yearly.specificMonthWeek.day + this.state.yearly.specificMonthWeek.monthWeek; if (!this.options.removeSeconds) { this.cron = this.state.yearly.specificMonthWeek.seconds + " " + this.cron; } if (!this.options.removeYears) { this.cron = this.cron + " *"; } break; default: throw new Error('Invalid cron yearly subtab selection'); } break; case 'advanced': this.cron = this.state.advanced.expression; break; default: throw new Error('Invalid cron active tab selection'); } }; /** * @private * @param {?} hour * @return {?} */ CronEditorComponent.prototype.getAmPmHour = /** * @private * @param {?} hour * @return {?} */ function (hour) { return this.options.use24HourTime ? hour : (hour + 11) % 12 + 1; }; /** * @private * @param {?} hour * @return {?} */ CronEditorComponent.prototype.getHourType = /** * @private * @param {?} hour * @return {?} */ function (hour) { return this.options.use24HourTime ? undefined : (hour >= 12 ? 'PM' : 'AM'); }; /** * @private * @param {?} hour * @param {?} hourType * @return {?} */ CronEditorComponent.prototype.hourToCron = /** * @private * @param {?} hour * @param {?} hourType * @return {?} */ function (hour, hourType) { if (this.options.use24HourTime) { return hour; } else { return hourType === 'AM' ? (hour === 12 ? 0 : hour) : (hour === 12 ? 12 : hour + 12); } }; /** * @private * @param {?} cron * @return {?} */ CronEditorComponent.prototype.handleModelChange = /** * @private * @param {?} cron * @return {?} */ function (cron) { var _this = this; if (this.isDirty) { this.isDirty = false; return; } else { this.isDirty = false; } this.validate(cron); /** @type {?} */ var cronSeven = cron; if (this.options.removeSeconds) { cronSeven = "0 " + cron; } if (this.options.removeYears) { cronSeven = cronSeven + " *"; } var _a = __read(cronSeven.split(' '), 6), seconds = _a[0], minutes = _a[1], hours = _a[2], dayOfMonth = _a[3], month = _a[4], dayOfWeek = _a[5]; if (cronSeven.match(/\d+ 0\/\d+ \* 1\/1 \* \? \*/)) { this.activeTab = 'minutes'; this.state.minutes.minutes = Number(minutes.substring(2)); this.state.minutes.seconds = Number(seconds); } else if (cronSeven.match(/\d+ \d+ 0\/\d+ 1\/1 \* \? \*/)) { this.activeTab = 'hourly'; this.state.hourly.hours = Number(hours.substring(2)); this.state.hourly.minutes = Number(minutes); this.state.hourly.seconds = Number(seconds); } else if (cronSeven.match(/\d+ \d+ \d+ 1\/\d+ \* \? \*/)) { this.activeTab = 'daily'; this.state.daily.subTab = 'everyDays'; this.state.daily.everyDays.days = Number(dayOfMonth.substring(2)); /** @type {?} */ var parsedHours = Number(hours); this.state.daily.everyDays.hours = this.getAmPmHour(parsedHours); this.state.daily.everyDays.hourType = this.getHourType(parsedHours); this.state.daily.everyDays.minutes = Number(minutes); this.state.daily.everyDays.seconds = Number(seconds); } else if (cronSeven.match(/\d+ \d+ \d+ \? \* MON-FRI \*/)) { this.activeTab = 'daily'; this.state.daily.subTab = 'everyWeekDay'; /** @type {?} */ var parsedHours = Number(hours); this.state.daily.everyWeekDay.hours = this.getAmPmHour(parsedHours); this.state.daily.everyWeekDay.hourType = this.getHourType(parsedHours); this.state.daily.everyWeekDay.minutes = Number(minutes); this.state.daily.everyWeekDay.seconds = Number(seconds); } else if (cronSeven.match(/\d+ \d+ \d+ \? \* (MON|TUE|WED|THU|FRI|SAT|SUN)(,(MON|TUE|WED|THU|FRI|SAT|SUN))* \*/)) { this.activeTab = 'weekly'; this.selectOptions.days.forEach(function (weekDay) { return _this.state.weekly[weekDay] = false; }); dayOfWeek.split(',').forEach(function (weekDay) { return _this.state.weekly[weekDay] = true; }); /** @type {?} */ var parsedHours = Number(hours); this.state.weekly.hours = this.getAmPmHour(parsedHours); this.state.weekly.hourType = this.getHourType(parsedHours); this.state.weekly.minutes = Number(minutes); this.state.weekly.seconds = Number(seconds); } else if (cronSeven.match(/\d+ \d+ \d+ (\d+|L|LW|1W) 1\/\d+ \? \*/)) { this.activeTab = 'monthly'; this.state.monthly.subTab = 'specificDay'; if (dayOfMonth.indexOf('W') !== -1) { this.state.monthly.specificDay.day = dayOfMonth.charAt(0); this.state.monthly.runOnWeekday = true; } else { this.state.monthly.specificDay.day = dayOfMonth; } this.state.monthly.specificDay.months = Number(month.substring(2)); /** @type {?} */ var parsedHours = Number(hours); this.state.monthly.specificDay.hours = this.getAmPmHour(parsedHours); this.state.monthly.specificDay.hourType = this.getHourType(parsedHours); this.state.monthly.specificDay.minutes = Number(minutes); this.state.monthly.specificDay.seconds = Number(seconds); } else if (cronSeven.match(/\d+ \d+ \d+ \? \d+\/\d+ (MON|TUE|WED|THU|FRI|SAT|SUN)((#[1-5])|L) \*/)) { /** @type {?} */ var day = dayOfWeek.substr(0, 3); /** @type {?} */ var monthWeek = dayOfWeek.substr(3); this.activeTab = 'monthly'; this.state.monthly.subTab = 'specificWeekDay'; this.state.monthly.specificWeekDay.monthWeek = monthWeek; this.state.monthly.specificWeekDay.day = day; if (month.indexOf('/') !== -1) { var _b = __read(month.split('/').map(Number), 2), startMonth = _b[0], months = _b[1]; this.state.monthly.specificWeekDay.months = months; this.state.monthly.specificWeekDay.startMonth = startMonth; } /** @type {?} */ var parsedHours = Number(hours); this.state.monthly.specificWeekDay.hours = this.getAmPmHour(parsedHours); this.state.monthly.specificWeekDay.hourType = this.getHourType(parsedHours); this.state.monthly.specificWeekDay.minutes = Number(minutes); this.state.monthly.specificWeekDay.seconds = Number(seconds); } else if (cronSeven.match(/\d+ \d+ \d+ (\d+|L|LW|1W) \d+ \? \*/)) { this.activeTab = 'yearly'; this.state.yearly.subTab = 'specificMonthDay'; this.state.yearly.specificMonthDay.month = Number(month); if (dayOfMonth.indexOf('W') !== -1) { this.state.yearly.specificMonthDay.day = dayOfMonth.charAt(0); this.state.yearly.runOnWeekday = true; } else { this.state.yearly.specificMonthDay.day = dayOfMonth; } /** @type {?} */ var parsedHours = Number(hours); this.state.yearly.specificMonthDay.hours = this.getAmPmHour(parsedHours); this.state.yearly.specificMonthDay.hourType = this.getHourType(parsedHours); this.state.yearly.specificMonthDay.minutes = Number(minutes); this.state.yearly.specificMonthDay.seconds = Number(seconds); } else if (cronSeven.match(/\d+ \d+ \d+ \? \d+ (MON|TUE|WED|THU|FRI|SAT|SUN)((#[1-5])|L) \*/)) { /** @type {?} */ var day = dayOfWeek.substr(0, 3); /** @type {?} */ var monthWeek = dayOfWeek.substr(3); this.activeTab = 'yearly'; this.state.yearly.subTab = 'specificMonthWeek'; this.state.yearly.specificMonthWeek.monthWeek = monthWeek; this.state.yearly.specificMonthWeek.day = day; this.state.yearly.specificMonthWeek.month = Number(month); /** @type {?} */ var parsedHours = Number(hours); this.state.yearly.specificMonthWeek.hours = this.getAmPmHour(parsedHours); this.state.yearly.specificMonthWeek.hourType = this.getHourType(parsedHours); this.state.yearly.specificMonthWeek.minutes = Number(minutes); this.state.yearly.specificMonthWeek.seconds = Number(seconds); } else { this.activeTab = 'advanced'; this.state.advanced.expression = cron; } }; /** * @private * @param {?} cron * @return {?} */ CronEditorComponent.prototype.validate = /** * @private * @param {?} cron * @return {?} */ function (cron) { this.state.validation.isValid = false; this.state.validation.errorMessage = ''; if (!cron) { this.state.validation.errorMessage = 'Cron expression cannot be null'; return; } /** @type {?} */ var cronParts = cron.split(' '); /** @type {?} */ var expected = 5; if (!this.options.removeSeconds) { expected++; } if (!this.options.removeYears) { expected++; } if (cronParts.length !== expected) { this.state.validation.errorMessage = "Invalid cron expression, there must be " + expected + " segments"; return; } this.state.validation.isValid = true; return; }; /** * @private * @return {?} */ CronEditorComponent.prototype.getDefaultAdvancedCronExpression = /** * @private * @return {?} */ function () { if (this.options.removeSeconds && !this.options.removeYears) { return '15 10 L-2 * ? 2019'; } if (!this.options.removeSeconds && this.options.removeYears) { return '0 15 10 L-2 * ?'; } if (this.options.removeSeconds && this.options.removeYears) { return '15 10 L-2 * ?'; } return '0 15 10 L-2 * ? 2019'; }; /** * @private * @return {?} */ CronEditorComponent.prototype.getDefaultState = /** * @private * @return {?} */ function () { var _a = __read(this.options.defaultTime.split(':').map(Number), 3), defaultHours = _a[0], defaultMinutes = _a[1], defaultSeconds = _a[2]; return { minutes: { minutes: 1, seconds: 0 }, hourly: { hours: 1, minutes: 0, seconds: 0 }, daily: { subTab: 'everyDays', everyDays: { days: 1, hours: this.getAmPmHour(defaultHours), minutes: defaultMinutes, seconds: defaultSeconds, hourType: this.getHourType(defaultHours) }, everyWeekDay: { hours: this.getAmPmHour(defaultHours), minutes: defaultMinutes, seconds: defaultSeconds, hourType: this.getHourType(defaultHours) } }, weekly: { MON: true, TUE: false, WED: false, THU: false, FRI: false, SAT: false, SUN: false, hours: this.getAmPmHour(defaultHours), minutes: defaultMinutes, seconds: defaultSeconds, hourType: this.getHourType(defaultHours) }, monthly: { subTab: 'specificDay', runOnWeekday: false, specificDay: { day: '1', months: 1, hours: this.getAmPmHour(defaultHours), minutes: defaultMinutes, seconds: defaultSeconds, hourType: this.getHourType(defaultHours) }, specificWeekDay: { monthWeek: '#1', day: 'MON', startMonth: 1, months: 1, hours: this.getAmPmHour(defaultHours), minutes: defaultMinutes, seconds: defaultSeconds, hourType: this.getHourType(defaultHours) } }, yearly: { subTab: 'specificMonthDay', runOnWeekday: false, specificMonthDay: { month: 1, day: '1', hours: this.getAmPmHour(defaultHours), minutes: defaultMinutes, seconds: defaultSeconds, hourType: this.getHourType(defaultHours) }, specificMonthWeek: { monthWeek: '#1', day: 'MON', month: 1, hours: this.getAmPmHour(defaultHours), minutes: defaultMinutes, seconds: defaultSeconds, hourType: this.getHourType(defaultHours) } }, advanced: { expression: this.getDefaultAdvancedCronExpression() }, validation: { isValid: true, errorMessage: '' } }; }; /** * @private * @param {?} value * @return {?} */ CronEditorComponent.prototype.getOrdinalSuffix = /** * @private * @param {?} value * @return {?} */ function (value) { if (value.length > 1) { /** @type {?} */ var secondToLastDigit = value.charAt(value.length - 2); if (secondToLastDigit === '1') { return 'th'; } } /** @type {?} */ var lastDigit = value.charAt(value.length - 1); switch (lastDigit) { case '1': return 'st'; case '2': return 'nd'; case '3': return 'rd'; default: return 'th'; } }; /** * @private * @return {?} */ CronEditorComponent.prototype.getSelectOptions = /** * @private * @return {?} */ function () { return { months: Utils.getRange(1, 12), monthWeeks: ['#1', '#2', '#3', '#4', '#5', 'L'], days: ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'], minutes: Utils.getRange(0, 59), fullMinutes: Utils.getRange(0, 59), seconds: Utils.getRange(0, 59), hours: Utils.getRange(1, 23), monthDays: Utils.getRange(1, 31), monthDaysWithLasts: __spread(Utils.getRange(1, 31).map(String), ['L']), hourTypes: ['AM', 'PM'] }; }; CronEditorComponent.decorators = [ { type: core.Component, args: [{ selector: 'cron-editor', template: "<!-- Tabs -->\r\n<ul class=\"nav nav-tabs tab-nav\" role=\"tablist\">\r\n <li [ngClass]=\"{'active': activeTab === 'minutes'}\" *ngIf=\"!options.hideMinutesTab\">\r\n <a aria-controls=\"minutes\" role=\"tab\" data-toggle=\"tab\" (click)=\"setActiveTab('minutes')\">\r\n Minutes\r\n </a>\r\n </li>\r\n\r\n <li role=\"presentation\" *ngIf=\"!options.hideHourlyTab\" [ngClass]=\"{'active': activeTab === 'hourly'}\">\r\n <a aria-controls=\"hourly\" role=\"tab\" data-toggle=\"tab\" (click)=\"setActiveTab('hourly')\">\r\n Hourly\r\n </a>\r\n </li>\r\n\r\n <li role=\"presentation\" *ngIf=\"!options.hideDailyTab\" [ngClass]=\"{'active': activeTab === 'daily'}\">\r\n <a aria-controls=\"daily\" role=\"tab\" data-toggle=\"tab\" (click)=\"setActiveTab('daily')\">\r\n Daily\r\n </a>\r\n </li>\r\n\r\n <li role=\"presentation\" *ngIf=\"!options.hideWeeklyTab\" [ngClass]=\"{'active': activeTab === 'weekly'}\">\r\n <a aria-controls=\"weekly\" role=\"tab\" data-toggle=\"tab\" (click)=\"setActiveTab('weekly')\">\r\n Weekly\r\n </a>\r\n </li>\r\n\r\n <li role=\"presentation\" *ngIf=\"!options.hideMonthlyTab\" [ngClass]=\"{'active': activeTab === 'monthly'}\">\r\n <a aria-controls=\"monthly\" role=\"tab\" data-toggle=\"tab\" (click)=\"setActiveTab('monthly')\">\r\n Monthly\r\n </a>\r\n </li>\r\n\r\n <li role=\"presentation\" *ngIf=\"!options.hideYearlyTab\" [ngClass]=\"{'active': activeTab === 'yearly'}\">\r\n <a aria-controls=\"yearly\" role=\"tab\" data-toggle=\"tab\" (click)=\"setActiveTab('yearly')\">\r\n Yearly\r\n </a>\r\n </li>\r\n\r\n <li role=\"presentation\" *ngIf=\"!options.hideAdvancedTab\" [ngClass]=\"{'active': activeTab === 'advanced'}\">\r\n <a aria-controls=\"advanced\" role=\"tab\" data-toggle=\"tab\" (click)=\"setActiveTab('advanced')\">\r\n Advanced\r\n </a>\r\n </li>\r\n</ul>\r\n\r\n<!-- Tab content -->\r\n<div class=\"cron-editor-container\">\r\n <div class=\"row\">\r\n <div class=\"col-xs-12\">\r\n <div class=\"tab-content\">\r\n <!-- Minutes-->\r\n <div class=\"tab-pane\" *ngIf=\"!options.hideMinutesTab\" [ngClass]=\"{'active': activeTab === 'minutes'}\">\r\n <div class=\"well well-small\">\r\n Every\r\n <select class=\"minutes\" [disabled]=\"disabled || activeTab !== 'minutes'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.minutes.minutes\" [ngClass]=\"options.formSelectClass\">\r\n <option *ngFor=\"let minute of selectOptions.minutes\" [ngValue]=\"minute\">\r\n {{minute}}\r\n </option>\r\n </select> minute(s)\r\n <span *ngIf=\"!options.hideSeconds\">on second</span>\r\n <select class=\"seconds\" *ngIf=\"!options.hideSeconds\" [disabled]=\"disabled || activeTab !== 'minutes'\"\r\n (change)=\"regenerateCron()\" [(ngModel)]=\"state.minutes.seconds\" [ngClass]=\"options.formSelectClass\">\r\n <option *ngFor=\"let second of selectOptions.seconds\" [ngValue]=\"second\">\r\n {{second}}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <!-- Hourly-->\r\n <div class=\"tab-pane\" *ngIf=\"!options.hideHourlyTab\" [ngClass]=\"{'active': activeTab === 'hourly'}\">\r\n <div class=\"well well-small\">\r\n Every\r\n <select class=\"hours\" [disabled]=\"disabled || activeTab !== 'hourly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.hourly.hours\" [ngClass]=\"options.formSelectClass\">\r\n <option *ngFor=\"let hour of selectOptions.hours\" [ngValue]=\"hour\">\r\n {{hour}}\r\n </option>\r\n </select> hour(s) on minute\r\n <select class=\"minutes\" [disabled]=\"disabled || activeTab !== 'hourly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.hourly.minutes\" [ngClass]=\"options.formSelectClass\">\r\n <option *ngFor=\"let minute of selectOptions.fullMinutes\" [ngValue]=\"minute\">\r\n {{minute}}\r\n </option>\r\n </select>\r\n <span *ngIf=\"!options.hideSeconds\">and second</span>\r\n <select class=\"seconds\" *ngIf=\"!options.hideSeconds\" [disabled]=\"disabled || activeTab !== 'hourly'\"\r\n (change)=\"regenerateCron()\" [(ngModel)]=\"state.hourly.seconds\" [ngClass]=\"options.formSelectClass\">\r\n <option *ngFor=\"let second of selectOptions.seconds\" [ngValue]=\"second\">\r\n {{second}}\r\n </option>\r\n </select>\r\n </div>\r\n </div>\r\n\r\n <!-- Daily-->\r\n <div class=\"tab-pane\" *ngIf=\"!options.hideDailyTab\" [ngClass]=\"{'active': activeTab === 'daily'}\">\r\n <div class=\"well well-small\">\r\n <input type=\"radio\" name=\"daily-radio\" value=\"everyDays\" [disabled]=\"disabled\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.daily.subTab\" value=\"everyDays\" [disabled]=\"disabled\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.daily.subTab\" [ngClass]=\"state.formRadioClass\" checked=\"checked\">\r\n Every\r\n <select class=\"days\" [disabled]=\"disabled || activeTab !== 'daily' || state.daily.subTab !== 'everyDays'\"\r\n (change)=\"regenerateCron()\" [(ngModel)]=\"state.daily.everyDays.days\" [ngClass]=\"options.formSelectClass\">\r\n <option *ngFor=\"let monthDay of selectOptions.monthDays\" [ngValue]=\"monthDay\">\r\n {{monthDay}}\r\n </option>\r\n </select> day(s) at\r\n\r\n <cron-time-picker [disabled]=\"disabled || activeTab !== 'daily' || state.daily.subTab !== 'everyDays'\"\r\n (change)=\"regenerateCron()\" [(time)]=\"state.daily.everyDays\" [selectClass]=\"options.formSelectClass\"\r\n [use24HourTime]=\"options.use24HourTime\" [hideSeconds]=\"options.hideSeconds\">\r\n </cron-time-picker>\r\n </div>\r\n\r\n <div class=\"well well-small\">\r\n <input type=\"radio\" name=\"daily-radio\" value=\"everyWeekDay\" [disabled]=\"disabled\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.daily.subTab\" [ngClass]=\"state.formRadioClass\"> Every working day at\r\n <cron-time-picker [disabled]=\"disabled || activeTab !== 'daily' || state.daily.subTab !== 'everyWeekDay'\"\r\n (change)=\"regenerateCron()\" [(time)]=\"state.daily.everyWeekDay\" [selectClass]=\"options.formSelectClass\"\r\n [use24HourTime]=\"options.use24HourTime\" [hideSeconds]=\"options.hideSeconds\">\r\n </cron-time-picker>\r\n </div>\r\n </div>\r\n\r\n <!-- Weekly-->\r\n <div class=\"tab-pane\" *ngIf=\"!options.hideWeeklyTab\" [ngClass]=\"{'active': activeTab === 'weekly'}\">\r\n <div class=\"well well-small\">\r\n <div class=\"row\">\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\" [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.MON\" [ngClass]=\"options.formCheckboxClass\"> Monday</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\" [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.TUE\" [ngClass]=\"options.formCheckboxClass\"> Tuesday</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\" [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.WED\" [ngClass]=\"options.formCheckboxClass\"> Wednesday</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\" [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.THU\" [ngClass]=\"options.formCheckboxClass\"> Thursday</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\" [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.FRI\" [ngClass]=\"options.formCheckboxClass\"> Friday</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\" [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.SAT\" [ngClass]=\"options.formCheckboxClass\"> Saturday</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\" [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.SUN\" [ngClass]=\"options.formCheckboxClass\"> Sunday</label>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-sm-6\">\r\n at\r\n <cron-time-picker [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(time)]=\"state.weekly\" [selectClass]=\"options.formSelectClass\" [use24HourTime]=\"options.use24HourTime\"\r\n [hideSeconds]=\"options.hideSeconds\">\r\n </cron-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n <!-- Monthly-->\r\n <div class=\"tab-pane\" *ngIf=\"!options.hideMonthlyTab\" [ngClass]=\"{'active': activeTab === 'monthly'}\">\r\n <div class=\"well well-small\">\r\n <input type=\"radio\" name=\"monthly-radio\" value=\"specificDay\" [disabled]=\"disabled\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.monthly.subTab\" [ngClass]=\"state.formRadioClass\"> On the\r\n <select class=\"month-days\" [disabled]=\"disabled || activeTab !== 'monthly' || state.monthly.subTab !== 'specificDay'\"\r\n (change)=\"regenerateCron()\" [(ngModel)]=\"state.monthly.specificDay.day\" [ngClass]=\"options.formSelectClass\">\r\n <option *ngFor=\"let monthDaysWithLast of selectOptions.monthDaysWithLasts\" [ngValue]=\"monthDaysWithLast\">\r\n {{monthDayDisplay(monthDaysWithLast)}}\r\n </option>\r\n </select> of every\r\n <select class=\"months-small\" [disabled]=\"disabled || activeTab !== 'monthly' || state.monthly.subTab !== 'specificDay'\"\r\n (change)=\"regenerateCron()\" [(ngModel)]=\"state.monthly.specificDay.months\" [ngClass]=\"options.formSelectClass\">\r\n <option *ngFor=\"let month of selectOptions.months\" [ngValue]=\"month\">\r\n {{month}}\r\n </option>\r\n </select> month(s) at\r\n <cron-time-picker [disabled]=\"disabled || activeTab !== 'monthly' || state.monthly.subTab !== 'specificDay'\"\r\n (change)=\"regenerateCron()\" [(time)]=\"state.monthly.specificDay\" [selectClass]=\"options.formSelectClass\"\r\n [use24HourTime]=\"options.use24HourTime\" [hideSeconds]=\"options.hideSeconds\">\r\n </cron-time-picker>&nbsp;\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\" [disabled]=\"disabled || activeTab !== 'monthly' || state.monthly.subTab !== 'specificDay'\" \r\n (change)=\"regenerateCron()\" [(ngModel)]=\"state.monthly.runOnWeekday\" [ngClass]=\"options.formCheckboxClass\"> during the nearest weekday</label>\r\n </div>\r\n <div class=\"well well-small\">\r\n <input type=\"radio\" name=\"monthly-radio\" value=\"specificWeekDay\" [disabled]=\"disabled\" (change)=\"regenerateCron()\"\r\n