ngx-ntk-cron-editor
Version:
Angular cron editor
1 lines • 101 kB
Source Map (JSON)
{"version":3,"file":"ngx-ntk-cron-editor.mjs","sources":["../../../projects/ngx-ntk-cron-editor/src/lib/poco/Utils.ts","../../../projects/ngx-ntk-cron-editor/src/lib/time-picker/time-picker.component.ts","../../../projects/ngx-ntk-cron-editor/src/lib/time-picker/time-picker.component.html","../../../projects/ngx-ntk-cron-editor/src/lib/models/cron-options-model.ts","../../../projects/ngx-ntk-cron-editor/src/lib/models/enums.ts","../../../projects/ngx-ntk-cron-editor/src/lib/translations/ru.ts","../../../projects/ngx-ntk-cron-editor/src/lib/translations/en.ts","../../../projects/ngx-ntk-cron-editor/src/lib/translations/fa.ts","../../../projects/ngx-ntk-cron-editor/src/lib/services/translateUi.service.ts","../../../projects/ngx-ntk-cron-editor/src/lib/cron-editor.component.ts","../../../projects/ngx-ntk-cron-editor/src/lib/cron-editor.component.html","../../../projects/ngx-ntk-cron-editor/src/lib/cron-editor.module.ts","../../../projects/ngx-ntk-cron-editor/src/ngx-ntk-cron-editor.ts"],"sourcesContent":["// @dynamic\r\nexport default class Utils {\r\n /** This returns a range of numbers. Starts from 0 if 'startFrom' is not set */\r\n public static getRange(startFrom: number, until: number) {\r\n return Array.from({ length: (until + 1 - startFrom) }, (_, k) => k + startFrom);\r\n }\r\n\r\n public static isObject(value: any): value is object {\r\n return typeof value === 'object' && value !== null;\r\n }\r\n\r\n public static merge(target: object, ...sources: object[]): object {\r\n for (const source of sources) {\r\n for (const [key, value] of Object.entries(source)) {\r\n if (Utils.isObject(target[key]) && Utils.isObject(value)) {\r\n Utils.merge(target[key], value);\r\n } else {\r\n target[key] = value;\r\n }\r\n }\r\n }\r\n return target;\r\n }\r\n}\r\n","import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';\r\nimport Utils from '../poco/Utils';\r\n\r\n\r\n\r\n@Component({\r\n selector: 'cron-time-picker',\r\n templateUrl: './time-picker.component.html',\r\n styleUrls: ['./time-picker.component.css']\r\n})\r\nexport class TimePickerComponent implements OnInit {\r\n @Output() public change = new EventEmitter();\r\n @Input() public disabled: boolean;\r\n @Input() public time: any;\r\n @Input() public selectClass: string;\r\n @Input() public use24HourTime: boolean;\r\n @Input() public hideSeconds: boolean;\r\n\r\n public hours: number[];\r\n public minutes: number[];\r\n public seconds: number[];\r\n public hourTypes: string[];\r\n\r\n public ngOnInit() {\r\n this.hours = this.use24HourTime ? Utils.getRange(0, 23) : Utils.getRange(0, 12);\r\n this.minutes = Utils.getRange(0, 59);\r\n this.seconds = Utils.getRange(0, 59);\r\n this.hourTypes = ['AM', 'PM'];\r\n }\r\n}\r\n","<!-- hour -->\r\n<select class=\"timeFormControl\" (change)=\"change.emit()\" [(ngModel)]=\"time.hours\" [disabled]=\"disabled\" [ngClass]=\"selectClass\">\r\n <option *ngFor=\"let hour of hours\" [ngValue]=\"hour\">{{hour}}</option>\r\n</select>\r\n\r\n<!-- minute -->\r\n<select class=\"timeFormControl\" (change)=\"change.emit()\" [(ngModel)]=\"time.minutes\" [disabled]=\"disabled\" [ngClass]=\"selectClass\">\r\n <option *ngFor=\"let minute of minutes\" [ngValue]=\"minute\">{{minute}}</option>\r\n</select>\r\n\r\n<!-- second -->\r\n<select class=\"timeFormControl\" (change)=\"change.emit()\" [(ngModel)]=\"time.seconds\" [disabled]=\"disabled\" *ngIf=\"!hideSeconds\"\r\n [ngClass]=\"selectClass\">\r\n <option *ngFor=\"let second of seconds\" [ngValue]=\"second\">{{second}}</option>\r\n</select>\r\n\r\n<!-- am/pm -->\r\n<select class=\"timeFormControl\" (change)=\"change.emit()\" [(ngModel)]=\"time.hourTypes\" [disabled]=\"disabled\" *ngIf=\"!use24HourTime\"\r\n [ngClass]=\"selectClass\">\r\n <option *ngFor=\"let hourType of hourTypes\" [ngValue]=\"hourType\">{{ hourType}}</option>\r\n</select>\r\n","export interface CronOptionModel {\r\n formInputClass: string;\r\n formSelectClass: string;\r\n formRadioClass: string;\r\n formCheckboxClass: string;\r\n\r\n defaultTime: string;\r\n use24HourTime: boolean;\r\n\r\n hideMinutesTab: boolean;\r\n hideHourlyTab: boolean;\r\n hideDailyTab: boolean;\r\n hideWeeklyTab: boolean;\r\n hideMonthlyTab: boolean;\r\n hideYearlyTab: boolean;\r\n hideAdvancedTab: boolean;\r\n\r\n /** hides the Seconds UI form element */\r\n hideSeconds: boolean;\r\n\r\n /** removes Seconds from the Cron expression */\r\n removeSeconds: boolean;\r\n\r\n /** removes Years from the Cron expression */\r\n removeYears: boolean;\r\n}\r\n\r\nexport const defaultCronOptions: CronOptionModel = {\r\n formInputClass: \"form-control cron-editor-input\",\r\n formSelectClass: \"form-select cron-editor-select\",\r\n formRadioClass: \"cron-editor-radio\",\r\n formCheckboxClass: \"form-check-input cron-editor-checkbox\",\r\n\r\n defaultTime: \"10:00:00\",\r\n use24HourTime: true,\r\n\r\n hideMinutesTab: false,\r\n hideHourlyTab: false,\r\n hideDailyTab: false,\r\n hideWeeklyTab: false,\r\n hideMonthlyTab: false,\r\n hideYearlyTab: false,\r\n hideAdvancedTab: false,\r\n\r\n hideSeconds: true,\r\n removeSeconds: true,\r\n removeYears: true,\r\n};\r\n","export const Days = {\r\n 'SUN': 'Sunday',\r\n 'MON': 'Monday',\r\n 'TUE': 'Tuesday',\r\n 'WED': 'Wednesday',\r\n 'THU': 'Thursday',\r\n 'FRI': 'Friday',\r\n 'SAT': 'Saturday'\r\n};\r\n\r\nexport const MonthWeeks = {\r\n '#1': 'First',\r\n '#2': 'Second',\r\n '#3': 'Third',\r\n '#4': 'Fourth',\r\n '#5': 'Fifth',\r\n 'L': 'Last'\r\n};\r\n\r\nexport enum Months {\r\n January = 1,\r\n February,\r\n March,\r\n April,\r\n May,\r\n June,\r\n July,\r\n August,\r\n September,\r\n October,\r\n November,\r\n December\r\n}\r\n","export const ru = {\r\n CRON: {\r\n TABS: {\r\n MINUTES: 'Минута',\r\n HOURLY: 'Час',\r\n DAILY: 'День',\r\n WEEKLY: 'Неделя',\r\n MONTHLY: 'Месяц',\r\n YEARLY: 'Год',\r\n ADVANCED: 'Продвинутый'\r\n },\r\n MINUTES: {\r\n EVERY: 'Каждые(-ую)',\r\n MINUTES: 'минут(-у)',\r\n ON_SECOND: 'в секунду:'\r\n },\r\n HOURLY: {\r\n EVERY: 'Каждый(-ые)',\r\n HOURS: 'час(-ов)',\r\n ON_MINUTE: 'в минуту:',\r\n ON_SECOND: 'и секунду:'\r\n },\r\n DAILY: {\r\n EVERY: 'Каждый',\r\n DAYS: 'день в',\r\n WORKING_DAY: 'Каждый рабочий день в'\r\n },\r\n WEEKLY: {\r\n AT: 'в'\r\n },\r\n MONTHLY: {\r\n ON: 'В',\r\n OF_EVERY: 'каждый(-ые)',\r\n MONTHS: 'месяц(-ев)',\r\n NEAREST_WEEKDAY: 'в ближайший будний день',\r\n AT: 'в',\r\n STARTING_IN: 'начиная с'\r\n },\r\n YEARLY: {\r\n EVERY: 'Каждый',\r\n ON: 'в',\r\n AT: 'в',\r\n OF: '',\r\n NEAREST_WEEKDAY: 'в ближайший будний день'\r\n },\r\n ADVANCED: {\r\n CRON: 'Cron-выражение'\r\n },\r\n MONTH_DAY: {\r\n LAST_DAY: 'Последний день',\r\n LAST_WEEKDAY: 'Последний рабочий день',\r\n FIRST_WEEKDAY: 'Первый рабочий день',\r\n DAY_N: '{{n}}-й день'\r\n },\r\n MONTH_WEEK: {\r\n FIRST: 'Первый',\r\n SECOND: 'Второй',\r\n THIRD: 'Третий',\r\n FOURTH: 'Четвертый',\r\n FIFTH: 'Пятый',\r\n LAST: 'Последний'\r\n },\r\n MONTH: {\r\n JANUARY: 'Январь',\r\n FEBRUARY: 'Февраль',\r\n MARCH: 'Март',\r\n APRIL: 'Апрель',\r\n MAY: 'Май',\r\n JUNE: 'Июнь',\r\n JULY: 'Июль',\r\n AUGUST: 'Август',\r\n SEPTEMBER: 'Сентябрь',\r\n OCTOBER: 'Октябрь',\r\n NOVEMBER: 'Ноябрь',\r\n DECEMBER: 'Декабрь'\r\n },\r\n WEEK: {\r\n MON: 'Понедельник',\r\n TUE: 'Вторник',\r\n WED: 'Среда',\r\n THU: 'Четверг',\r\n FRI: 'Пятница',\r\n SAT: 'Суббота',\r\n SUN: 'Воскресенье',\r\n },\r\n HOUR_TYPES: {\r\n AM: 'ДП',\r\n PM: 'ПП'\r\n },\r\n VALIDATION_MESSAGE: {\r\n NULL: 'Cron-выражение не может быть null',\r\n SEGMENTS: 'Неверное cron-выражение, должно быть {{n}} сегментов'\r\n }\r\n }\r\n};\r\n","\r\n\r\nexport const en = {\r\n CRON: {\r\n TABS: {\r\n MINUTES: 'Minutes',\r\n HOURLY: 'Hourly',\r\n DAILY: 'Daily',\r\n WEEKLY: 'Weekly',\r\n MONTHLY: 'Monthly',\r\n YEARLY: 'Yearly',\r\n ADVANCED: 'Advanced'\r\n },\r\n MINUTES: {\r\n EVERY: 'Every',\r\n MINUTES: 'minute(s)',\r\n ON_SECOND: 'on second'\r\n },\r\n HOURLY: {\r\n EVERY: 'Every',\r\n HOURS: 'hour(s)',\r\n ON_MINUTE: 'on minute',\r\n ON_SECOND: 'and second'\r\n },\r\n DAILY: {\r\n EVERY: 'Every',\r\n DAYS: 'day(s) at',\r\n WORKING_DAY: 'Every working day at'\r\n },\r\n WEEKLY: {\r\n AT: 'at'\r\n },\r\n MONTHLY: {\r\n ON: 'On the',\r\n OF_EVERY: 'of every',\r\n MONTHS: 'month(s)',\r\n NEAREST_WEEKDAY: 'during the nearest weekday',\r\n AT: 'at',\r\n STARTING_IN: 'starting in'\r\n },\r\n YEARLY: {\r\n EVERY: 'Every',\r\n ON: 'on the',\r\n AT: 'at',\r\n OF: 'of',\r\n NEAREST_WEEKDAY: 'during the nearest weekday'\r\n },\r\n ADVANCED: {\r\n CRON: 'Cron Expression'\r\n },\r\n MONTH_DAY: {\r\n LAST_DAY: 'Last Day',\r\n LAST_WEEKDAY: 'Last Weekday',\r\n FIRST_WEEKDAY: 'First Weekday',\r\n DAY_N: 'Day {{n}}'\r\n },\r\n MONTH_WEEK: {\r\n FIRST: 'First',\r\n SECOND: 'Second',\r\n THIRD: 'Third',\r\n FOURTH: 'Fourth',\r\n FIFTH: 'Fifth',\r\n LAST: 'Last'\r\n },\r\n MONTH: {\r\n JANUARY: 'January',\r\n FEBRUARY: 'February',\r\n MARCH: 'March',\r\n APRIL: 'April',\r\n MAY: 'May',\r\n JUNE: 'June',\r\n JULY: 'July',\r\n AUGUST: 'August',\r\n SEPTEMBER: 'September',\r\n OCTOBER: 'October',\r\n NOVEMBER: 'November',\r\n DECEMBER: 'December'\r\n },\r\n WEEK: {\r\n MON: 'Monday',\r\n TUE: 'Tuesday',\r\n WED: 'Wednesday',\r\n THU: 'Thursday',\r\n FRI: 'Friday',\r\n SAT: 'Saturday',\r\n SUN: 'Sunday',\r\n },\r\n HOUR_TYPES: {\r\n AM: 'AM',\r\n PM: 'PM'\r\n },\r\n VALIDATION_MESSAGE: {\r\n NULL: 'Cron expression cannot be null',\r\n SEGMENTS: 'Invalid cron expression, there must be {{n}} segments'\r\n }\r\n }\r\n};\r\n","\r\nexport const fa = {\r\n CRON: {\r\n TABS: {\r\n MINUTES: 'دقیقه',\r\n HOURLY: 'ساعت',\r\n DAILY: 'روز',\r\n WEEKLY: 'هفتگی',\r\n MONTHLY: 'ماهیانه',\r\n YEARLY: 'سالیانه',\r\n ADVANCED: 'Advanced'\r\n },\r\n MINUTES: {\r\n EVERY: 'هر',\r\n MINUTES: 'minute(s)',\r\n ON_SECOND: 'on second'\r\n },\r\n HOURLY: {\r\n EVERY: 'هر',\r\n HOURS: 'hour(s)',\r\n ON_MINUTE: 'on minute',\r\n ON_SECOND: 'and second'\r\n },\r\n DAILY: {\r\n EVERY: 'هر',\r\n DAYS: 'day(s) at',\r\n WORKING_DAY: 'Every working day at'\r\n },\r\n WEEKLY: {\r\n AT: 'at'\r\n },\r\n MONTHLY: {\r\n ON: 'On the',\r\n OF_EVERY: 'of every',\r\n MONTHS: 'month(s)',\r\n NEAREST_WEEKDAY: 'during the nearest weekday',\r\n AT: 'at',\r\n STARTING_IN: 'starting in'\r\n },\r\n YEARLY: {\r\n EVERY: 'هر',\r\n ON: 'on the',\r\n AT: 'at',\r\n OF: 'of',\r\n NEAREST_WEEKDAY: 'during the nearest weekday'\r\n },\r\n ADVANCED: {\r\n CRON: 'Cron Expression'\r\n },\r\n MONTH_DAY: {\r\n LAST_DAY: 'روز آخر',\r\n LAST_WEEKDAY: 'روز هفته گذشته',\r\n FIRST_WEEKDAY: 'روز اول هفته',\r\n DAY_N: 'Day {{n}}'\r\n },\r\n MONTH_WEEK: {\r\n FIRST: 'اولین',\r\n SECOND: 'دومین',\r\n THIRD: 'سوم',\r\n FOURTH: 'چهارم',\r\n FIFTH: 'پنجم',\r\n LAST: 'آخر'\r\n },\r\n MONTH: {\r\n JANUARY: 'January',\r\n FEBRUARY: 'February',\r\n MARCH: 'March',\r\n APRIL: 'April',\r\n MAY: 'May',\r\n JUNE: 'June',\r\n JULY: 'July',\r\n AUGUST: 'August',\r\n SEPTEMBER: 'September',\r\n OCTOBER: 'October',\r\n NOVEMBER: 'November',\r\n DECEMBER: 'December'\r\n },\r\n WEEK: {\r\n MON: 'دوشنبه',\r\n TUE: 'سه شنبه',\r\n WED: 'چهارشنبه',\r\n THU: 'پنج شنبه',\r\n FRI: 'جمعه',\r\n SAT: 'شنبه',\r\n SUN: 'یکشنبه',\r\n },\r\n HOUR_TYPES: {\r\n AM: 'صبح',\r\n PM: 'عصر'\r\n },\r\n VALIDATION_MESSAGE: {\r\n NULL: 'Cron expression cannot be null',\r\n SEGMENTS: 'Invalid cron expression, there must be {{n}} segments'\r\n }\r\n }\r\n};\r\n","import {ru} from '../translations/ru';\r\nimport {en} from '../translations/en';\r\nimport {fa} from '../translations/fa';\r\nimport { Injectable } from '@angular/core';\r\nimport { TranslateService } from '@ngx-translate/core';\r\n\r\n@Injectable()\r\nexport class TranslateUiService {\r\n private availableLanguages = { en, ru,fa };\r\n\r\n constructor(private translateService: TranslateService) {\r\n }\r\n\r\n public init(language: string = null): any {\r\n if (language) {\r\n //initialize one specific language\r\n this.translateService.setTranslation(language, this.availableLanguages[language], true);\r\n } else {\r\n //initialize all\r\n Object.keys(this.availableLanguages).forEach((language) => {\r\n this.translateService.setTranslation(language, this.availableLanguages[language], true);\r\n });\r\n }\r\n }\r\n}","import {\r\n Component,\r\n EventEmitter,\r\n Input,\r\n OnChanges,\r\n OnInit,\r\n Output,\r\n SimpleChanges,\r\n} from \"@angular/core\";\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from \"@angular/forms\";\r\nimport { distinctUntilChanged } from \"rxjs\";\r\nimport { CronOptionModel, defaultCronOptions } from \"./models/cron-options-model\";\r\nimport { Days, Months, MonthWeeks } from \"./models/enums\";\r\nimport Utils from \"./poco/Utils\";\r\nimport { TranslateService } from \"@ngx-translate/core\";\r\nimport { TranslateUiService } from \"./services/translateUi.service\";\r\n\r\n@Component({\r\n selector: \"cron-editor\",\r\n templateUrl: \"./cron-editor.component.html\",\r\n styleUrls: [\"./cron-editor.component.css\"],\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: CronEditorComponent,\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class CronEditorComponent implements OnInit, OnChanges, ControlValueAccessor {\r\n\r\n static nextId = 0;\r\n id = ++CronEditorComponent.nextId;\r\n \r\n private _language = 'en';\r\n @Input() set language(value: string) {\r\n this._language = value;\r\n this.translateUiService.init(value);\r\n this.translate.use(this.language);\r\n\r\n }\r\n\r\n get language(): string {\r\n return this._language;\r\n }\r\n @Input() public disabled: boolean;\r\n\r\n // @Input({\r\n // transform: (value: CronOptionModel | null) => {\r\n // if (value) return value;\r\n\r\n // return defaultCronOptions;\r\n // },\r\n // })\r\n @Input()\r\n public options: CronOptionModel = defaultCronOptions;\r\n\r\n @Input() get cron(): string {\r\n return this.localCron;\r\n }\r\n set cron(value: string) {\r\n this.localCron = value;\r\n }\r\n\r\n // the name is an Angular convention, @Input variable name + \"Change\" suffix\r\n @Output() cronChange = new EventEmitter();\r\n\r\n public activeTab: string;\r\n public selectOptions = this.getSelectOptions();\r\n public state: any;\r\n\r\n private localCron: string;\r\n private isDirty: boolean;\r\n constructor(\r\n private translate: TranslateService,\r\n private translateUiService: TranslateUiService,\r\n ) {\r\n \r\n \r\n }\r\n public ngOnInit() {\r\n \r\n if (this.options.removeSeconds) {\r\n this.options.hideSeconds = true;\r\n }\r\n\r\n this.state = this.getDefaultState();\r\n\r\n this.handleModelChange(this.cron);\r\n }\r\n\r\n public ngOnChanges(changes: SimpleChanges) {\r\n const newCron = changes[\"cron\"];\r\n if (newCron && !newCron.firstChange) {\r\n this.handleModelChange(this.cron);\r\n }\r\n }\r\n\r\n writeValue(cronExpression: string): void {\r\n this.handleModelChange(cronExpression);\r\n }\r\n\r\n registerOnChange(onChange: (cronExpression: string) => void): void {\r\n this.cronChange.subscribe({\r\n next: (cronExpression: string) => {\r\n onChange(cronExpression);\r\n this.validate(cronExpression);\r\n },\r\n });\r\n }\r\n\r\n registerOnTouched(onTouched: () => void): void {\r\n this.cronChange.pipe(distinctUntilChanged()).subscribe(onTouched);\r\n }\r\n\r\n setDisabledState?(isDisabled: boolean): void {\r\n this.disabled = isDisabled;\r\n }\r\n\r\n public setActiveTab(tab: string) {\r\n if (!this.disabled) {\r\n this.activeTab = tab;\r\n this.regenerateCron();\r\n }\r\n }\r\n\r\n public dayDisplay(day: string): string {\r\n return Days[day];\r\n }\r\n\r\n public monthWeekDisplay(monthWeekNumber: number): string {\r\n return MonthWeeks[monthWeekNumber];\r\n }\r\n\r\n public monthDisplay(month: number): string {\r\n return Months[month];\r\n }\r\n\r\n public monthDayDisplay(month: string): string {\r\n if (month === \"L\") {\r\n return \"Last Day\";\r\n } else if (month === \"LW\") {\r\n return \"Last Weekday\";\r\n } else if (month === \"1W\") {\r\n return \"First Weekday\";\r\n } else {\r\n return `${month}${this.getOrdinalSuffix(month)} day`;\r\n }\r\n }\r\n\r\n public regenerateCron() {\r\n this.isDirty = true;\r\n\r\n const oldCron = this.localCron;\r\n\r\n switch (this.activeTab) {\r\n case \"minutes\":\r\n this.cron = `0/${this.state.minutes.minutes} * 1/1 * ?`;\r\n\r\n if (!this.options.removeSeconds) {\r\n this.cron = `${this.state.minutes.seconds} ${this.cron}`;\r\n }\r\n\r\n if (!this.options.removeYears) {\r\n this.cron = `${this.cron} *`;\r\n }\r\n break;\r\n case \"hourly\":\r\n this.cron = `${this.state.hourly.minutes} 0/${this.state.hourly.hours} 1/1 * ?`;\r\n\r\n if (!this.options.removeSeconds) {\r\n this.cron = `${this.state.hourly.seconds} ${this.cron}`;\r\n }\r\n\r\n if (!this.options.removeYears) {\r\n this.cron = `${this.cron} *`;\r\n }\r\n break;\r\n case \"daily\":\r\n switch (this.state.daily.subTab) {\r\n case \"everyDays\":\r\n // tslint:disable-next-line:max-line-length\r\n this.cron = `${this.state.daily.everyDays.minutes\r\n } ${this.hourToCron(\r\n this.state.daily.everyDays.hours,\r\n this.state.daily.everyDays.hourType\r\n )} 1/${this.state.daily.everyDays.days} * ?`;\r\n\r\n if (!this.options.removeSeconds) {\r\n this.cron = `${this.state.daily.everyDays.seconds} ${this.cron}`;\r\n }\r\n\r\n if (!this.options.removeYears) {\r\n this.cron = `${this.cron} *`;\r\n }\r\n break;\r\n case \"everyWeekDay\":\r\n // tslint:disable-next-line:max-line-length\r\n this.cron = `${this.state.daily.everyWeekDay.minutes\r\n } ${this.hourToCron(\r\n this.state.daily.everyWeekDay.hours,\r\n this.state.daily.everyWeekDay.hourType\r\n )} ? * MON-FRI`;\r\n\r\n if (!this.options.removeSeconds) {\r\n this.cron = `${this.state.daily.everyWeekDay.seconds} ${this.cron}`;\r\n }\r\n\r\n if (!this.options.removeYears) {\r\n this.cron = `${this.cron} *`;\r\n }\r\n break;\r\n default:\r\n throw new Error(\"Invalid cron daily subtab selection\");\r\n }\r\n break;\r\n case \"weekly\":\r\n const days = this.selectOptions.days\r\n .reduce(\r\n (acc, day) => (this.state.weekly[day] ? acc.concat([day]) : acc),\r\n []\r\n )\r\n .join(\",\");\r\n this.cron = `${this.state.weekly.minutes} ${this.hourToCron(\r\n this.state.weekly.hours,\r\n this.state.weekly.hourType\r\n )} ? * ${days}`;\r\n\r\n if (!this.options.removeSeconds) {\r\n this.cron = `${this.state.weekly.seconds} ${this.cron}`;\r\n }\r\n\r\n if (!this.options.removeYears) {\r\n this.cron = `${this.cron} *`;\r\n }\r\n break;\r\n case \"monthly\":\r\n switch (this.state.monthly.subTab) {\r\n case \"specificDay\":\r\n const day = this.state.monthly.runOnWeekday\r\n ? `${this.state.monthly.specificDay.day}W`\r\n : this.state.monthly.specificDay.day;\r\n // tslint:disable-next-line:max-line-length\r\n this.cron = `${this.state.monthly.specificDay.minutes\r\n } ${this.hourToCron(\r\n this.state.monthly.specificDay.hours,\r\n this.state.monthly.specificDay.hourType\r\n )} ${day} 1/${this.state.monthly.specificDay.months} ?`;\r\n\r\n if (!this.options.removeSeconds) {\r\n this.cron = `${this.state.monthly.specificDay.seconds} ${this.cron}`;\r\n }\r\n\r\n if (!this.options.removeYears) {\r\n this.cron = `${this.cron} *`;\r\n }\r\n break;\r\n case \"specificWeekDay\":\r\n // tslint:disable-next-line:max-line-length\r\n this.cron = `${this.state.monthly.specificWeekDay.minutes\r\n } ${this.hourToCron(\r\n this.state.monthly.specificWeekDay.hours,\r\n this.state.monthly.specificWeekDay.hourType\r\n )} ? ${this.state.monthly.specificWeekDay.startMonth}/${this.state.monthly.specificWeekDay.months\r\n } ${this.state.monthly.specificWeekDay.day}${this.state.monthly.specificWeekDay.monthWeek\r\n }`;\r\n\r\n if (!this.options.removeSeconds) {\r\n this.cron = `${this.state.monthly.specificWeekDay.seconds} ${this.cron}`;\r\n }\r\n\r\n if (!this.options.removeYears) {\r\n this.cron = `${this.cron} *`;\r\n }\r\n break;\r\n default:\r\n throw new Error(\"Invalid cron monthly subtab selection\");\r\n }\r\n break;\r\n case \"yearly\":\r\n switch (this.state.yearly.subTab) {\r\n case \"specificMonthDay\":\r\n // tslint:disable-next-line:max-line-length\r\n const day = this.state.yearly.runOnWeekday\r\n ? `${this.state.yearly.specificMonthDay.day}W`\r\n : this.state.yearly.specificMonthDay.day;\r\n // tslint:disable-next-line:max-line-length\r\n this.cron = `${this.state.yearly.specificMonthDay.minutes\r\n } ${this.hourToCron(\r\n this.state.yearly.specificMonthDay.hours,\r\n this.state.yearly.specificMonthDay.hourType\r\n )} ${day} ${this.state.yearly.specificMonthDay.month} ?`;\r\n\r\n if (!this.options.removeSeconds) {\r\n this.cron = `${this.state.yearly.specificMonthDay.seconds} ${this.cron}`;\r\n }\r\n\r\n if (!this.options.removeYears) {\r\n this.cron = `${this.cron} *`;\r\n }\r\n break;\r\n case \"specificMonthWeek\":\r\n // tslint:disable-next-line:max-line-length\r\n this.cron = `${this.state.yearly.specificMonthWeek.minutes\r\n } ${this.hourToCron(\r\n this.state.yearly.specificMonthWeek.hours,\r\n this.state.yearly.specificMonthWeek.hourType\r\n )} ? ${this.state.yearly.specificMonthWeek.month} ${this.state.yearly.specificMonthWeek.day\r\n }${this.state.yearly.specificMonthWeek.monthWeek}`;\r\n\r\n if (!this.options.removeSeconds) {\r\n this.cron = `${this.state.yearly.specificMonthWeek.seconds} ${this.cron}`;\r\n }\r\n\r\n if (!this.options.removeYears) {\r\n this.cron = `${this.cron} *`;\r\n }\r\n break;\r\n default:\r\n throw new Error(\"Invalid cron yearly subtab selection\");\r\n }\r\n break;\r\n case \"advanced\":\r\n this.cron = this.state.advanced.expression;\r\n break;\r\n default:\r\n throw new Error(\"Invalid cron active tab selection\");\r\n }\r\n\r\n if (oldCron !== this.cron) {\r\n this.cronChange.emit(this.cron);\r\n }\r\n }\r\n\r\n private getAmPmHour(hour: number) {\r\n return this.options.use24HourTime ? hour : ((hour + 11) % 12) + 1;\r\n }\r\n\r\n private getHourType(hour: number) {\r\n return this.options.use24HourTime ? undefined : hour >= 12 ? \"PM\" : \"AM\";\r\n }\r\n\r\n private hourToCron(hour: number, hourType: string) {\r\n if (this.options.use24HourTime) {\r\n return hour;\r\n } else {\r\n return hourType === \"AM\"\r\n ? hour === 12\r\n ? 0\r\n : hour\r\n : hour === 12\r\n ? 12\r\n : hour + 12;\r\n }\r\n }\r\n\r\n private handleModelChange(cron: string) {\r\n if (this.isDirty) {\r\n this.isDirty = false;\r\n return;\r\n } else {\r\n this.isDirty = false;\r\n }\r\n\r\n this.validate(cron);\r\n\r\n const oldValue = this.localCron;\r\n\r\n let cronSeven = cron;\r\n if (this.options.removeSeconds) {\r\n cronSeven = `0 ${cron}`;\r\n }\r\n\r\n if (this.options.removeYears) {\r\n cronSeven = `${cronSeven} *`;\r\n }\r\n\r\n const [seconds, minutes, hours, dayOfMonth, month, dayOfWeek] =\r\n cronSeven.split(\" \");\r\n\r\n if (cronSeven.match(/\\d+ 0\\/\\d+ \\* 1\\/1 \\* \\? \\*/)) {\r\n this.activeTab = \"minutes\";\r\n\r\n this.state.minutes.minutes = Number(minutes.substring(2));\r\n this.state.minutes.seconds = Number(seconds);\r\n } else if (cronSeven.match(/\\d+ \\d+ 0\\/\\d+ 1\\/1 \\* \\? \\*/)) {\r\n this.activeTab = \"hourly\";\r\n\r\n this.state.hourly.hours = Number(hours.substring(2));\r\n this.state.hourly.minutes = Number(minutes);\r\n this.state.hourly.seconds = Number(seconds);\r\n } else if (cronSeven.match(/\\d+ \\d+ \\d+ 1\\/\\d+ \\* \\? \\*/)) {\r\n this.activeTab = \"daily\";\r\n\r\n this.state.daily.subTab = \"everyDays\";\r\n this.state.daily.everyDays.days = Number(dayOfMonth.substring(2));\r\n const parsedHours = Number(hours);\r\n this.state.daily.everyDays.hours = this.getAmPmHour(parsedHours);\r\n this.state.daily.everyDays.hourType = this.getHourType(parsedHours);\r\n this.state.daily.everyDays.minutes = Number(minutes);\r\n this.state.daily.everyDays.seconds = Number(seconds);\r\n } else if (cronSeven.match(/\\d+ \\d+ \\d+ \\? \\* MON-FRI \\*/)) {\r\n this.activeTab = \"daily\";\r\n\r\n this.state.daily.subTab = \"everyWeekDay\";\r\n const parsedHours = Number(hours);\r\n this.state.daily.everyWeekDay.hours = this.getAmPmHour(parsedHours);\r\n this.state.daily.everyWeekDay.hourType = this.getHourType(parsedHours);\r\n this.state.daily.everyWeekDay.minutes = Number(minutes);\r\n this.state.daily.everyWeekDay.seconds = Number(seconds);\r\n } else if (\r\n cronSeven.match(\r\n /\\d+ \\d+ \\d+ \\? \\* (MON|TUE|WED|THU|FRI|SAT|SUN)(,(MON|TUE|WED|THU|FRI|SAT|SUN))* \\*/\r\n )\r\n ) {\r\n this.activeTab = \"weekly\";\r\n this.selectOptions.days.forEach(\r\n (weekDay) => (this.state.weekly[weekDay] = false)\r\n );\r\n dayOfWeek\r\n .split(\",\")\r\n .forEach((weekDay) => (this.state.weekly[weekDay] = true));\r\n const parsedHours = Number(hours);\r\n this.state.weekly.hours = this.getAmPmHour(parsedHours);\r\n this.state.weekly.hourType = this.getHourType(parsedHours);\r\n this.state.weekly.minutes = Number(minutes);\r\n this.state.weekly.seconds = Number(seconds);\r\n } else if (cronSeven.match(/\\d+ \\d+ \\d+(L|LW|W)? 1\\/\\d+ \\?/)) {\r\n this.activeTab = \"monthly\";\r\n this.state.monthly.subTab = \"specificDay\";\r\n\r\n const wIndex = dayOfMonth.indexOf(\"W\");\r\n if (wIndex !== -1) {\r\n this.state.monthly.specificDay.day = dayOfMonth.split(\"W\")[0];\r\n this.state.monthly.runOnWeekday = true;\r\n } else {\r\n this.state.monthly.specificDay.day = dayOfMonth;\r\n this.state.monthly.runOnWeekday = false;\r\n }\r\n\r\n this.state.monthly.specificDay.months = Number(month.substring(2));\r\n const parsedHours = Number(hours);\r\n this.state.monthly.specificDay.hours = this.getAmPmHour(parsedHours);\r\n this.state.monthly.specificDay.hourType = this.getHourType(parsedHours);\r\n this.state.monthly.specificDay.minutes = Number(minutes);\r\n this.state.monthly.specificDay.seconds = Number(seconds);\r\n } else if (\r\n cronSeven.match(\r\n /\\d+ \\d+ \\d+ \\? \\d+\\/\\d+ (MON|TUE|WED|THU|FRI|SAT|SUN)((#[1-5])|L) \\*/\r\n )\r\n ) {\r\n const day = dayOfWeek.substr(0, 3);\r\n const monthWeek = dayOfWeek.substr(3);\r\n this.activeTab = \"monthly\";\r\n this.state.monthly.subTab = \"specificWeekDay\";\r\n this.state.monthly.specificWeekDay.monthWeek = monthWeek;\r\n this.state.monthly.specificWeekDay.day = day;\r\n\r\n if (month.indexOf(\"/\") !== -1) {\r\n const [startMonth, months] = month.split(\"/\").map(Number);\r\n this.state.monthly.specificWeekDay.months = months;\r\n this.state.monthly.specificWeekDay.startMonth = startMonth;\r\n }\r\n\r\n const parsedHours = Number(hours);\r\n this.state.monthly.specificWeekDay.hours = this.getAmPmHour(parsedHours);\r\n this.state.monthly.specificWeekDay.hourType =\r\n this.getHourType(parsedHours);\r\n this.state.monthly.specificWeekDay.minutes = Number(minutes);\r\n this.state.monthly.specificWeekDay.seconds = Number(seconds);\r\n } else if (cronSeven.match(/\\d+ \\d+ \\d+ (\\d+|L|LW|1W) \\d+ \\? \\*/)) {\r\n this.activeTab = \"yearly\";\r\n this.state.yearly.subTab = \"specificMonthDay\";\r\n this.state.yearly.specificMonthDay.month = Number(month);\r\n\r\n if (dayOfMonth.indexOf(\"W\") !== -1) {\r\n this.state.yearly.specificMonthDay.day = dayOfMonth.charAt(0);\r\n this.state.yearly.runOnWeekday = true;\r\n } else {\r\n this.state.yearly.specificMonthDay.day = dayOfMonth;\r\n }\r\n\r\n const parsedHours = Number(hours);\r\n this.state.yearly.specificMonthDay.hours = this.getAmPmHour(parsedHours);\r\n this.state.yearly.specificMonthDay.hourType =\r\n this.getHourType(parsedHours);\r\n this.state.yearly.specificMonthDay.minutes = Number(minutes);\r\n this.state.yearly.specificMonthDay.seconds = Number(seconds);\r\n } else if (\r\n cronSeven.match(\r\n /\\d+ \\d+ \\d+ \\? \\d+ (MON|TUE|WED|THU|FRI|SAT|SUN)((#[1-5])|L) \\*/\r\n )\r\n ) {\r\n const day = dayOfWeek.substr(0, 3);\r\n const monthWeek = dayOfWeek.substr(3);\r\n this.activeTab = \"yearly\";\r\n this.state.yearly.subTab = \"specificMonthWeek\";\r\n this.state.yearly.specificMonthWeek.monthWeek = monthWeek;\r\n this.state.yearly.specificMonthWeek.day = day;\r\n this.state.yearly.specificMonthWeek.month = Number(month);\r\n const parsedHours = Number(hours);\r\n this.state.yearly.specificMonthWeek.hours = this.getAmPmHour(parsedHours);\r\n this.state.yearly.specificMonthWeek.hourType =\r\n this.getHourType(parsedHours);\r\n this.state.yearly.specificMonthWeek.minutes = Number(minutes);\r\n this.state.yearly.specificMonthWeek.seconds = Number(seconds);\r\n } else {\r\n this.activeTab = \"advanced\";\r\n this.state.advanced.expression = cron;\r\n }\r\n\r\n if (oldValue !== this.cron) {\r\n this.cronChange.emit(this.cron);\r\n }\r\n }\r\n\r\n private validate(cron: string): void {\r\n this.state.validation.isValid = false;\r\n this.state.validation.errorMessage = \"\";\r\n\r\n if (!cron) {\r\n this.state.validation.errorMessage = \"Cron expression cannot be null\";\r\n return;\r\n }\r\n\r\n const cronParts = cron.split(\" \");\r\n\r\n let expected = 5;\r\n\r\n if (!this.options.removeSeconds) {\r\n expected++;\r\n }\r\n\r\n if (!this.options.removeYears) {\r\n expected++;\r\n }\r\n\r\n if (cronParts.length !== expected) {\r\n this.state.validation.errorMessage = `Invalid cron expression, there must be ${expected} segments`;\r\n return;\r\n }\r\n\r\n this.state.validation.isValid = true;\r\n return;\r\n }\r\n\r\n private getDefaultAdvancedCronExpression(): string {\r\n if (this.options.removeSeconds && !this.options.removeYears) {\r\n return \"15 10 L-2 * ? 2019\";\r\n }\r\n\r\n if (!this.options.removeSeconds && this.options.removeYears) {\r\n return \"0 15 10 L-2 * ?\";\r\n }\r\n\r\n if (this.options.removeSeconds && this.options.removeYears) {\r\n return \"15 10 L-2 * ?\";\r\n }\r\n\r\n return \"0 15 10 L-2 * ? 2019\";\r\n }\r\n\r\n private getDefaultState() {\r\n const [defaultHours, defaultMinutes, defaultSeconds] =\r\n this.options.defaultTime.split(\":\").map(Number);\r\n\r\n return {\r\n minutes: {\r\n minutes: 1,\r\n seconds: 0,\r\n },\r\n hourly: {\r\n hours: 1,\r\n minutes: 0,\r\n seconds: 0,\r\n },\r\n daily: {\r\n subTab: \"everyDays\",\r\n everyDays: {\r\n days: 1,\r\n hours: this.getAmPmHour(defaultHours),\r\n minutes: defaultMinutes,\r\n seconds: defaultSeconds,\r\n hourType: this.getHourType(defaultHours),\r\n },\r\n everyWeekDay: {\r\n hours: this.getAmPmHour(defaultHours),\r\n minutes: defaultMinutes,\r\n seconds: defaultSeconds,\r\n hourType: this.getHourType(defaultHours),\r\n },\r\n },\r\n weekly: {\r\n MON: true,\r\n TUE: false,\r\n WED: false,\r\n THU: false,\r\n FRI: false,\r\n SAT: false,\r\n SUN: false,\r\n hours: this.getAmPmHour(defaultHours),\r\n minutes: defaultMinutes,\r\n seconds: defaultSeconds,\r\n hourType: this.getHourType(defaultHours),\r\n },\r\n monthly: {\r\n subTab: \"specificDay\",\r\n runOnWeekday: false,\r\n specificDay: {\r\n day: \"1\",\r\n months: 1,\r\n hours: this.getAmPmHour(defaultHours),\r\n minutes: defaultMinutes,\r\n seconds: defaultSeconds,\r\n hourType: this.getHourType(defaultHours),\r\n },\r\n specificWeekDay: {\r\n monthWeek: \"#1\",\r\n day: \"MON\",\r\n startMonth: 1,\r\n months: 1,\r\n hours: this.getAmPmHour(defaultHours),\r\n minutes: defaultMinutes,\r\n seconds: defaultSeconds,\r\n hourType: this.getHourType(defaultHours),\r\n },\r\n },\r\n yearly: {\r\n subTab: \"specificMonthDay\",\r\n runOnWeekday: false,\r\n specificMonthDay: {\r\n month: 1,\r\n day: \"1\",\r\n hours: this.getAmPmHour(defaultHours),\r\n minutes: defaultMinutes,\r\n seconds: defaultSeconds,\r\n hourType: this.getHourType(defaultHours),\r\n },\r\n specificMonthWeek: {\r\n monthWeek: \"#1\",\r\n day: \"MON\",\r\n month: 1,\r\n hours: this.getAmPmHour(defaultHours),\r\n minutes: defaultMinutes,\r\n seconds: defaultSeconds,\r\n hourType: this.getHourType(defaultHours),\r\n },\r\n },\r\n advanced: {\r\n expression: this.getDefaultAdvancedCronExpression(),\r\n },\r\n validation: {\r\n isValid: true,\r\n errorMessage: \"\",\r\n },\r\n };\r\n }\r\n\r\n private getOrdinalSuffix(value: string) {\r\n if (value.length > 1) {\r\n const secondToLastDigit = value.charAt(value.length - 2);\r\n if (secondToLastDigit === \"1\") {\r\n return \"th\";\r\n }\r\n }\r\n\r\n const lastDigit = value.charAt(value.length - 1);\r\n switch (lastDigit) {\r\n case \"1\":\r\n return \"st\";\r\n case \"2\":\r\n return \"nd\";\r\n case \"3\":\r\n return \"rd\";\r\n default:\r\n return \"th\";\r\n }\r\n }\r\n\r\n private getSelectOptions() {\r\n return {\r\n months: Utils.getRange(1, 12),\r\n monthWeeks: [\"#1\", \"#2\", \"#3\", \"#4\", \"#5\", \"L\"],\r\n days: [\"MON\", \"TUE\", \"WED\", \"THU\", \"FRI\", \"SAT\", \"SUN\"],\r\n minutes: Utils.getRange(0, 59),\r\n fullMinutes: Utils.getRange(0, 59),\r\n seconds: Utils.getRange(0, 59),\r\n hours: Utils.getRange(1, 23),\r\n monthDays: Utils.getRange(1, 31),\r\n monthDaysWithLasts: [...Utils.getRange(1, 31).map(String), \"L\"],\r\n hourTypes: [\"AM\", \"PM\"],\r\n };\r\n }\r\n}\r\n","<!-- Tabs -->\r\n<ul class=\"nav nav-tabs\" role=\"tablist\">\r\n <li class=\"nav-item\" *ngIf=\"!options.hideMinutesTab\">\r\n <a class=\"nav-link\" [ngClass]=\"{ active: activeTab === 'minutes' }\" aria-controls=\"minutes\" role=\"tab\"\r\n data-bs-toggle=\"tab\" (click)=\"setActiveTab('minutes')\">\r\n {{'CRON.TABS.MINUTES'|translate}}\r\n </a>\r\n </li>\r\n\r\n <li class=\"nav-item\" *ngIf=\"!options.hideHourlyTab\">\r\n <a class=\"nav-link\" [ngClass]=\"{ active: activeTab === 'hourly' }\" aria-controls=\"hourly\" role=\"tab\"\r\n data-bs-toggle=\"tab\" (click)=\"setActiveTab('hourly')\">\r\n {{'CRON.TABS.HOURLY'|translate}}\r\n </a>\r\n </li>\r\n\r\n <li class=\"nav-item\" *ngIf=\"!options.hideDailyTab\">\r\n <a class=\"nav-link\" [ngClass]=\"{ active: activeTab === 'daily' }\" aria-controls=\"daily\" role=\"tab\"\r\n data-bs-toggle=\"tab\" (click)=\"setActiveTab('daily')\">\r\n {{'CRON.TABS.DAILY'|translate}}\r\n </a>\r\n </li>\r\n\r\n <li class=\"nav-item\" *ngIf=\"!options.hideWeeklyTab\">\r\n <a class=\"nav-link\" [ngClass]=\"{ active: activeTab === 'weekly' }\" aria-controls=\"weekly\" role=\"tab\"\r\n data-bs-toggle=\"tab\" (click)=\"setActiveTab('weekly')\">\r\n {{'CRON.TABS.WEEKLY'|translate}}\r\n </a>\r\n </li>\r\n\r\n <li class=\"nav-item\" *ngIf=\"!options.hideMonthlyTab\">\r\n <a class=\"nav-link\" [ngClass]=\"{ active: activeTab === 'monthly' }\" aria-controls=\"monthly\" role=\"tab\"\r\n data-bs-toggle=\"tab\" (click)=\"setActiveTab('monthly')\">\r\n {{'CRON.TABS.MONTHLY'|translate}}\r\n </a>\r\n </li>\r\n\r\n <li class=\"nav-item\" *ngIf=\"!options.hideYearlyTab\">\r\n <a class=\"nav-link\" [ngClass]=\"{ active: activeTab === 'yearly' }\" aria-controls=\"yearly\" role=\"tab\"\r\n data-bs-toggle=\"tab\" (click)=\"setActiveTab('yearly')\">\r\n {{'CRON.TABS.YEARLY'|translate}}\r\n </a>\r\n </li>\r\n\r\n <li class=\"nav-item\" *ngIf=\"!options.hideAdvancedTab\">\r\n <a class=\"nav-link\" [ngClass]=\"{ active: activeTab === 'advanced' }\" aria-controls=\"advanced\" role=\"tab\"\r\n data-bs-toggle=\"tab\" (click)=\"setActiveTab('advanced')\">\r\n {{'CRON.TABS.ADVANCED'|translate}}\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-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=\"card card-body bg-light\">\r\n {{'CRON.MINUTES.EVERY'|translate}}\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 | number:'2.0' }}\r\n </option>\r\n </select>\r\n {{'CRON.MINUTES.MINUTES'|translate}}\r\n <span *ngIf=\"!options.hideSeconds\">{{'CRON.MINUTES.ON_SECOND'|translate}}</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 | number:'2.0' }}\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=\"card card-body bg-light\">\r\n {{'CRON.HOURLY.EVERY'|translate}}\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>\r\n {{'CRON.HOURLY.HOURS'|translate}}\r\n {{'CRON.HOURLY.ON_MINUTE'|translate}}\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 | number:'2.0' }}\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=\"card card-body bg-light\">\r\n <input type=\"radio\" name=\"daily-radio\" value=\"everyDays\" [disabled]=\"disabled\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.daily.subTab\" [ngClass]=\"state.formRadioClass\" checked=\"checked\" />\r\n {{'CRON.DAILY.EVERY'|translate}}\r\n <select class=\"days\" [disabled]=\"\r\n disabled ||\r\n activeTab !== 'daily' ||\r\n state.daily.subTab !== 'everyDays'\r\n \" (change)=\"regenerateCron()\" [(ngModel)]=\"state.daily.everyDays.days\"\r\n [ngClass]=\"options.formSelectClass\">\r\n <option *ngFor=\"let monthDay of selectOptions.monthDays\" [ngValue]=\"monthDay\">\r\n {{ monthDay }}\r\n </option>\r\n </select>\r\n {{'CRON.DAILY.DAYS'|translate}}\r\n <cron-time-picker [disabled]=\"\r\n disabled ||\r\n activeTab !== 'daily' ||\r\n 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=\"card card-body bg-light\">\r\n <input type=\"radio\" name=\"daily-radio\" value=\"everyWeekDay\" [disabled]=\"disabled\"\r\n (change)=\"regenerateCron()\" [(ngModel)]=\"state.daily.subTab\" [ngClass]=\"state.formRadioClass\" />\r\n {{'CRON.DAILY.WORKING_DAY'|translate}}\r\n <cron-time-picker [disabled]=\"\r\n disabled ||\r\n activeTab !== 'daily' ||\r\n 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=\"card card-body bg-light\">\r\n <div class=\"row\">\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\"\r\n [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.MON\" [ngClass]=\"options.formCheckboxClass\" />\r\n {{'CRON.WEEK.MON'|translate}}</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\"\r\n [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.TUE\" [ngClass]=\"options.formCheckboxClass\" />\r\n {{'CRON.WEEK.TUE'|translate}}</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\"\r\n [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.WED\" [ngClass]=\"options.formCheckboxClass\" />\r\n {{'CRON.WEEK.WED'|translate}}</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\"\r\n [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.THU\" [ngClass]=\"options.formCheckboxClass\" />\r\n {{'CRON.WEEK.THU'|translate}}</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\"\r\n [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.FRI\" [ngClass]=\"options.formCheckboxClass\" />\r\n {{'CRON.WEEK.FRI'|translate}}</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\"\r\n [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.SAT\" [ngClass]=\"options.formCheckboxClass\" />\r\n {{'CRON.WEEK.SAT'|translate}}</label>\r\n </div>\r\n <div class=\"col-sm-6\">\r\n <label class=\"advanced-cron-editor-label\"><input type=\"checkbox\"\r\n [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(ngModel)]=\"state.weekly.SUN\" [ngClass]=\"options.formCheckboxClass\" />\r\n {{'CRON.WEEK.SUN'|translate}}</label>\r\n </div>\r\n </div>\r\n <div class=\"row\">\r\n <div class=\"col-sm-6\">\r\n {{'CRON.WEEKLY.AT'|translate}}\r\n <cron-time-picker [disabled]=\"disabled || activeTab !== 'weekly'\" (change)=\"regenerateCron()\"\r\n [(time)]=\"state.weekly\" [selectClass]=\"options.formSelectClass\"\r\n [use24HourTime]=\"options.use24HourTime\" [hideSeconds]=\"options.hideSeconds\">\r\n </cron-time-picker>\r\n </div>\r\n </div>\r\n </div>\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=\"card card-body bg-light\">\r\n <input type=\"radio\" name=\"monthly-radio\" value=\"specificDay\" [disabled]=\"disabled\"\r\n (change)=\"regenerateCron()\" [(ngModel)]=\"state.monthly.subTab\" [ngClass]=\"state.formRadioClass\" />\r\n On the\r\n <select class=\"month-days\" [disabled]=\"\r\n disabled ||\r\n activeTab !== 'monthly' ||\r\n state.monthly.subTab !== 'specificDay'\r\n \" (change)=\"regenerateCron()\" [(ngModel)]=\"state.monthly.specificDay.day\"\r\n