UNPKG

ng2-date-picker

Version:

[![Build Status](https://travis-ci.org/vlio20/angular-datepicker.svg?branch=master)](https://travis-ci.org/vlio20/angular-datepicker) [![Backers on Open Collective](https://opencollective.com/angular-datepicker/backers/badge.svg)](#backers) [![Sponsor

1 lines 190 kB
{"version":3,"file":"ng2-date-picker.umd.js","sources":["../../node_modules/tslib/tslib.es6.js","ng://ng2-date-picker/common/types/calendar-mode-enum.ts","ng://ng2-date-picker/common/types/calendar-value-enum.ts","ng://ng2-date-picker/common/types/selection-evet.enum..ts","ng://ng2-date-picker/common/services/dom-appender/dom-appender.service.ts","ng://ng2-date-picker/common/services/utils/utils.service.ts","ng://ng2-date-picker/day-calendar/day-calendar.service.ts","ng://ng2-date-picker/day-calendar/day-calendar.component.ts","ng://ng2-date-picker/time-select/time-select.service.ts","ng://ng2-date-picker/day-time-calendar/day-time-calendar.service.ts","ng://ng2-date-picker/time-select/time-select.component.ts","ng://ng2-date-picker/date-picker/date-picker.service.ts","ng://ng2-date-picker/month-calendar/month-calendar.service.ts","ng://ng2-date-picker/month-calendar/month-calendar.component.ts","ng://ng2-date-picker/day-time-calendar/day-time-calendar.component.ts","ng://ng2-date-picker/date-picker/date-picker.component.ts","ng://ng2-date-picker/date-picker/date-picker-directive.service.ts","ng://ng2-date-picker/date-picker/date-picker.directive.ts","ng://ng2-date-picker/calendar-nav/calendar-nav.component.ts","ng://ng2-date-picker/date-picker.module.ts"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation. All rights reserved.\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthis file except in compliance with the License. You may obtain a copy of the\r\nLicense at http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\r\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\r\nMERCHANTABLITY OR NON-INFRINGEMENT.\r\n\r\nSee the Apache Version 2.0 License for specific language governing permissions\r\nand limitations under the License.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n","export enum ECalendarMode {\n Day,\n DayTime,\n Month,\n Time\n}\n","export enum ECalendarValue {\n Moment = 1,\n MomentArr,\n String,\n StringArr\n}\n","export enum SelectEvent {\n INPUT = 'input',\n SELECTION = 'selection'\n}\n","import {Injectable} from '@angular/core';\nimport {TDrops, TOpens} from '../../types/poistions.type';\n\n@Injectable()\nexport class DomHelper {\n\n private static setYAxisPosition(element: HTMLElement, container: HTMLElement, anchor: HTMLElement, drops: TDrops) {\n const anchorRect = anchor.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const bottom = anchorRect.bottom - containerRect.top;\n const top = anchorRect.top - containerRect.top;\n\n if (drops === 'down') {\n element.style.top = (bottom + 1 + 'px');\n } else {\n element.style.top = (top - 1 - element.scrollHeight) + 'px';\n }\n }\n\n private static setXAxisPosition(element: HTMLElement, container: HTMLElement, anchor: HTMLElement, dimElem: HTMLElement, opens: TOpens) {\n const anchorRect = anchor.getBoundingClientRect();\n const containerRect = container.getBoundingClientRect();\n const left = anchorRect.left - containerRect.left;\n\n if (opens === 'right') {\n element.style.left = left + 'px';\n } else {\n element.style.left = left - dimElem.offsetWidth + anchor.offsetWidth + 'px';\n }\n }\n\n private static isTopInView(el: HTMLElement): boolean {\n const {top} = el.getBoundingClientRect();\n return (top >= 0);\n }\n\n private static isBottomInView(el: HTMLElement): boolean {\n const {bottom} = el.getBoundingClientRect();\n return (bottom <= window.innerHeight);\n }\n\n private static isLeftInView(el: HTMLElement): boolean {\n const {left} = el.getBoundingClientRect();\n return (left >= 0);\n }\n\n private static isRightInView(el: HTMLElement): boolean {\n const {right} = el.getBoundingClientRect();\n return (right <= window.innerWidth);\n }\n\n appendElementToPosition(config: IAppendToArgs): void {\n const {container, element} = config;\n\n if (!container.style.position || container.style.position === 'static') {\n container.style.position = 'relative';\n }\n\n if (element.style.position !== 'absolute') {\n element.style.position = 'absolute';\n }\n\n element.style.visibility = 'hidden';\n\n setTimeout(() => {\n this.setElementPosition(config);\n\n element.style.visibility = 'visible';\n });\n }\n\n setElementPosition({element, container, anchor, dimElem, drops, opens}: IAppendToArgs) {\n DomHelper.setYAxisPosition(element, container, anchor, 'down');\n DomHelper.setXAxisPosition(element, container, anchor, dimElem, 'right');\n\n if (drops !== 'down' && drops !== 'up') {\n if (DomHelper.isBottomInView(dimElem)) {\n DomHelper.setYAxisPosition(element, container, anchor, 'down');\n } else if (DomHelper.isTopInView(dimElem)) {\n DomHelper.setYAxisPosition(element, container, anchor, 'up');\n }\n } else {\n DomHelper.setYAxisPosition(element, container, anchor, drops);\n }\n\n if (opens !== 'left' && opens !== 'right') {\n if (DomHelper.isRightInView(dimElem)) {\n DomHelper.setXAxisPosition(element, container, anchor, dimElem, 'right');\n } else if (DomHelper.isLeftInView(dimElem)) {\n DomHelper.setXAxisPosition(element, container, anchor, dimElem, 'left');\n }\n } else {\n DomHelper.setXAxisPosition(element, container, anchor, dimElem, opens);\n }\n }\n}\n\nexport interface IAppendToArgs {\n container: HTMLElement;\n element: HTMLElement;\n anchor: HTMLElement;\n dimElem: HTMLElement;\n drops: TDrops;\n opens: TOpens;\n}\n","import {ECalendarValue} from '../../types/calendar-value-enum';\nimport {SingleCalendarValue} from '../../types/single-calendar-value';\nimport {Injectable} from '@angular/core';\nimport * as momentNs from 'moment';\nimport {Moment, unitOfTime} from 'moment';\nimport {CalendarValue} from '../../types/calendar-value';\nimport {IDate} from '../../models/date.model';\nimport {CalendarMode} from '../../types/calendar-mode';\nimport {DateValidator} from '../../types/validator.type';\nimport {ICalendarInternal} from '../../models/calendar.model';\n\nconst moment = momentNs;\n\nexport interface DateLimits {\n minDate?: SingleCalendarValue;\n maxDate?: SingleCalendarValue;\n minTime?: SingleCalendarValue;\n maxTime?: SingleCalendarValue;\n}\n\n@Injectable()\nexport class UtilsService {\n static debounce(func: Function, wait: number) {\n let timeout;\n return function () {\n const context = this, args = arguments;\n timeout = clearTimeout(timeout);\n setTimeout(() => {\n func.apply(context, args);\n }, wait);\n };\n };\n\n createArray(size: number): number[] {\n return new Array(size).fill(1);\n }\n\n convertToMoment(date: SingleCalendarValue, format: string): Moment {\n if (!date) {\n return null;\n } else if (typeof date === 'string') {\n return moment(date, format);\n } else {\n return date.clone();\n }\n }\n\n isDateValid(date: string, format: string): boolean {\n if (date === '') {\n return true;\n }\n\n return moment(date, format, true).isValid();\n }\n\n // todo:: add unit test\n getDefaultDisplayDate(current: Moment,\n selected: Moment[],\n allowMultiSelect: boolean,\n minDate: Moment): Moment {\n if (current) {\n return current.clone();\n } else if (minDate && minDate.isAfter(moment())) {\n return minDate.clone();\n } else if (allowMultiSelect) {\n if (selected && selected[selected.length]) {\n return selected[selected.length].clone();\n }\n } else if (selected && selected[0]) {\n return selected[0].clone();\n }\n\n return moment();\n }\n\n // todo:: add unit test\n getInputType(value: CalendarValue, allowMultiSelect: boolean): ECalendarValue {\n if (Array.isArray(value)) {\n if (!value.length) {\n return ECalendarValue.MomentArr;\n } else if (typeof value[0] === 'string') {\n return ECalendarValue.StringArr;\n } else if (moment.isMoment(value[0])) {\n return ECalendarValue.MomentArr;\n }\n } else {\n if (typeof value === 'string') {\n return ECalendarValue.String;\n } else if (moment.isMoment(value)) {\n return ECalendarValue.Moment;\n }\n }\n\n return allowMultiSelect ? ECalendarValue.MomentArr : ECalendarValue.Moment;\n }\n\n // todo:: add unit test\n convertToMomentArray(value: CalendarValue, format: string, allowMultiSelect: boolean): Moment[] {\n switch (this.getInputType(value, allowMultiSelect)) {\n case (ECalendarValue.String):\n return value ? [moment(<string>value, format, true)] : [];\n case (ECalendarValue.StringArr):\n return (<string[]>value).map(v => v ? moment(v, format, true) : null).filter(Boolean);\n case (ECalendarValue.Moment):\n return value ? [(<Moment>value).clone()] : [];\n case (ECalendarValue.MomentArr):\n return (<Moment[]>value || []).map(v => v.clone());\n default:\n return [];\n }\n }\n\n // todo:: add unit test\n convertFromMomentArray(format: string,\n value: Moment[],\n convertTo: ECalendarValue): CalendarValue {\n switch (convertTo) {\n case (ECalendarValue.String):\n return value[0] && value[0].format(format);\n case (ECalendarValue.StringArr):\n return value.filter(Boolean).map(v => v.format(format));\n case (ECalendarValue.Moment):\n return value[0] ? value[0].clone() : value[0];\n case (ECalendarValue.MomentArr):\n return value ? value.map(v => v.clone()) : value;\n default:\n return value;\n }\n }\n\n convertToString(value: CalendarValue, format: string): string {\n let tmpVal: string[];\n\n if (typeof value === 'string') {\n tmpVal = [value];\n } else if (Array.isArray(value)) {\n if (value.length) {\n tmpVal = (<SingleCalendarValue[]>value).map((v) => {\n return this.convertToMoment(v, format).format(format);\n });\n } else {\n tmpVal = <string[]>value;\n }\n } else if (moment.isMoment(value)) {\n tmpVal = [value.format(format)];\n } else {\n return '';\n }\n\n return tmpVal.filter(Boolean).join(' | ');\n }\n\n // todo:: add unit test\n clearUndefined<T>(obj: T): T {\n if (!obj) {\n return obj;\n }\n\n Object.keys(obj).forEach((key) => (obj[key] === undefined) && delete obj[key]);\n return obj;\n }\n\n updateSelected(isMultiple: boolean,\n currentlySelected: Moment[],\n date: IDate,\n granularity: unitOfTime.Base = 'day'): Moment[] {\n if (isMultiple) {\n return !date.selected\n ? currentlySelected.concat([date.date])\n : currentlySelected.filter(d => !d.isSame(date.date, granularity));\n } else {\n return !date.selected ? [date.date] : [];\n }\n }\n\n closestParent(element: HTMLElement, selector: string): HTMLElement {\n if (!element) {\n return undefined;\n }\n const match = <HTMLElement>element.querySelector(selector);\n return match || this.closestParent(element.parentElement, selector);\n }\n\n onlyTime(m: Moment): Moment {\n return m && moment.isMoment(m) && moment(m.format('HH:mm:ss'), 'HH:mm:ss');\n }\n\n granularityFromType(calendarType: CalendarMode): unitOfTime.Base {\n switch (calendarType) {\n case 'time':\n return 'second';\n case 'daytime':\n return 'second';\n default:\n return calendarType;\n }\n }\n\n createValidator({minDate, maxDate, minTime, maxTime}: DateLimits,\n format: string,\n calendarType: CalendarMode): DateValidator {\n let isValid: boolean;\n let value: Moment[];\n const validators = [];\n const granularity = this.granularityFromType(calendarType);\n\n if (minDate) {\n const md = this.convertToMoment(minDate, format);\n validators.push({\n key: 'minDate',\n isValid: () => {\n const _isValid = value.every(val => val.isSameOrAfter(md, granularity));\n isValid = isValid ? _isValid : false;\n return _isValid;\n }\n });\n }\n\n if (maxDate) {\n const md = this.convertToMoment(maxDate, format);\n validators.push({\n key: 'maxDate',\n isValid: () => {\n const _isValid = value.every(val => val.isSameOrBefore(md, granularity));\n isValid = isValid ? _isValid : false;\n return _isValid;\n }\n });\n }\n\n if (minTime) {\n const md = this.onlyTime(this.convertToMoment(minTime, format));\n validators.push({\n key: 'minTime',\n isValid: () => {\n const _isValid = value.every(val => this.onlyTime(val).isSameOrAfter(md));\n isValid = isValid ? _isValid : false;\n return _isValid;\n }\n });\n }\n\n if (maxTime) {\n const md = this.onlyTime(this.convertToMoment(maxTime, format));\n validators.push({\n key: 'maxTime',\n isValid: () => {\n const _isValid = value.every(val => this.onlyTime(val).isSameOrBefore(md));\n isValid = isValid ? _isValid : false;\n return _isValid;\n }\n });\n }\n\n return (inputVal: CalendarValue) => {\n isValid = true;\n\n value = this.convertToMomentArray(inputVal, format, true).filter(Boolean);\n\n if (!value.every(val => val.isValid())) {\n return {\n format: {\n given: inputVal\n }\n };\n }\n\n const errors = validators.reduce((map, err) => {\n if (!err.isValid()) {\n map[err.key] = {\n given: value\n };\n }\n\n return map;\n }, {});\n\n return !isValid ? errors : null;\n };\n }\n\n datesStringToStringArray(value: string): string[] {\n return (value || '').split('|').map(m => m.trim()).filter(Boolean);\n }\n\n getValidMomentArray(value: string, format: string): Moment[] {\n return this.datesStringToStringArray(value)\n .filter(d => this.isDateValid(d, format))\n .map(d => moment(d, format));\n }\n\n shouldShowCurrent(showGoToCurrent: boolean,\n mode: CalendarMode,\n min: Moment,\n max: Moment): boolean {\n return showGoToCurrent &&\n mode !== 'time' &&\n this.isDateInRange(moment(), min, max);\n }\n\n isDateInRange(date: Moment, from: Moment, to: Moment): boolean {\n return date.isBetween(from, to, 'day', '[]');\n }\n\n convertPropsToMoment(obj: {[key: string]: any}, format: string, props: string[]) {\n props.forEach((prop) => {\n if (obj.hasOwnProperty(prop)) {\n obj[prop] = this.convertToMoment(obj[prop], format);\n }\n });\n }\n\n shouldResetCurrentView<T extends ICalendarInternal>(prevConf: T, currentConf: T): boolean {\n if (prevConf && currentConf) {\n if (!prevConf.min && currentConf.min) {\n return true;\n } else if (prevConf.min && currentConf.min && !prevConf.min.isSame(currentConf.min, 'd')) {\n return true;\n } else if (!prevConf.max && currentConf.max) {\n return true;\n } else if (prevConf.max && currentConf.max && !prevConf.max.isSame(currentConf.max, 'd')) {\n return true;\n }\n\n return false;\n }\n\n return false;\n }\n\n getNativeElement(elem: HTMLElement | string): HTMLElement {\n if (!elem) {\n return null;\n } else if (typeof elem === 'string') {\n return <HTMLElement>document.querySelector(elem);\n } else {\n return elem;\n }\n }\n}\n","import {Injectable} from '@angular/core';\nimport * as momentNs from 'moment';\nimport {Moment} from 'moment';\nimport {WeekDays} from '../common/types/week-days.type';\nimport {UtilsService} from '../common/services/utils/utils.service';\nimport {IDay} from './day.model';\nimport {IDayCalendarConfig, IDayCalendarConfigInternal} from './day-calendar-config.model';\nimport {IMonthCalendarConfig} from '../month-calendar/month-calendar-config';\n\nconst moment = momentNs;\n\n@Injectable()\nexport class DayCalendarService {\n private readonly DAYS = ['su', 'mo', 'tu', 'we', 'th', 'fr', 'sa'];\n readonly DEFAULT_CONFIG: IDayCalendarConfig = {\n showNearMonthDays: true,\n showWeekNumbers: false,\n firstDayOfWeek: 'su',\n weekDayFormat: 'ddd',\n format: 'DD-MM-YYYY',\n allowMultiSelect: false,\n monthFormat: 'MMM, YYYY',\n enableMonthSelector: true,\n locale: moment.locale(),\n dayBtnFormat: 'DD',\n unSelectOnClick: true\n };\n\n constructor(private utilsService: UtilsService) {\n }\n\n private removeNearMonthWeeks(currentMonth: Moment, monthArray: IDay[][]): IDay[][] {\n if (monthArray[monthArray.length - 1].find((day) => day.date.isSame(currentMonth, 'month'))) {\n return monthArray;\n } else {\n return monthArray.slice(0, -1);\n }\n }\n\n getConfig(config: IDayCalendarConfig): IDayCalendarConfigInternal {\n const _config = <IDayCalendarConfigInternal>{\n ...this.DEFAULT_CONFIG,\n ...this.utilsService.clearUndefined(config)\n };\n\n this.utilsService.convertPropsToMoment(_config, _config.format, ['min', 'max']);\n\n moment.locale(_config.locale);\n\n return _config;\n }\n\n generateDaysMap(firstDayOfWeek: WeekDays) {\n const firstDayIndex = this.DAYS.indexOf(firstDayOfWeek);\n const daysArr = this.DAYS.slice(firstDayIndex, 7).concat(this.DAYS.slice(0, firstDayIndex));\n return daysArr.reduce((map, day, index) => {\n map[day] = index;\n\n return map;\n }, <{[key: string]: number}>{});\n }\n\n generateMonthArray(config: IDayCalendarConfigInternal, month: Moment, selected: Moment[]): IDay[][] {\n let monthArray: IDay[][] = [];\n const firstDayOfWeekIndex = this.DAYS.indexOf(config.firstDayOfWeek);\n const firstDayOfBoard = month.clone().startOf('month');\n\n while (firstDayOfBoard.day() !== firstDayOfWeekIndex) {\n firstDayOfBoard.subtract(1, 'day');\n }\n\n const current = firstDayOfBoard.clone();\n const prevMonth = month.clone().subtract(1, 'month');\n const nextMonth = month.clone().add(1, 'month');\n const today = moment();\n\n const daysOfCalendar: IDay[] = this.utilsService.createArray(42)\n .reduce((array: IDay[]) => {\n array.push({\n date: current.clone(),\n selected: !!selected.find(selectedDay => current.isSame(selectedDay, 'day')),\n currentMonth: current.isSame(month, 'month'),\n prevMonth: current.isSame(prevMonth, 'month'),\n nextMonth: current.isSame(nextMonth, 'month'),\n currentDay: current.isSame(today, 'day'),\n disabled: this.isDateDisabled(current, config)\n });\n current.add(1, 'day');\n\n return array;\n }, []);\n\n daysOfCalendar.forEach((day, index) => {\n const weekIndex = Math.floor(index / 7);\n\n if (!monthArray[weekIndex]) {\n monthArray.push([]);\n }\n\n monthArray[weekIndex].push(day);\n });\n\n if (!config.showNearMonthDays) {\n monthArray = this.removeNearMonthWeeks(month, monthArray);\n }\n\n return monthArray;\n }\n\n generateWeekdays(firstDayOfWeek: WeekDays): Moment[] {\n const weekdayNames: {[key: string]: Moment} = {\n su: moment().day(0),\n mo: moment().day(1),\n tu: moment().day(2),\n we: moment().day(3),\n th: moment().day(4),\n fr: moment().day(5),\n sa: moment().day(6)\n };\n const weekdays: Moment[] = [];\n const daysMap = this.generateDaysMap(firstDayOfWeek);\n\n for (const dayKey in daysMap) {\n if (daysMap.hasOwnProperty(dayKey)) {\n weekdays[daysMap[dayKey]] = weekdayNames[dayKey];\n }\n }\n\n return weekdays;\n }\n\n isDateDisabled(date: Moment, config: IDayCalendarConfigInternal): boolean {\n if (config.isDayDisabledCallback) {\n return config.isDayDisabledCallback(date);\n }\n\n if (config.min && date.isBefore(config.min, 'day')) {\n return true;\n }\n\n return !!(config.max && date.isAfter(config.max, 'day'));\n }\n\n // todo:: add unit tests\n getHeaderLabel(config: IDayCalendarConfigInternal, month: Moment): string {\n if (config.monthFormatter) {\n return config.monthFormatter(month);\n }\n\n return month.format(config.monthFormat);\n }\n\n // todo:: add unit tests\n shouldShowLeft(min: Moment, currentMonthView: Moment): boolean {\n return min ? min.isBefore(currentMonthView, 'month') : true;\n }\n\n // todo:: add unit tests\n shouldShowRight(max: Moment, currentMonthView: Moment): boolean {\n return max ? max.isAfter(currentMonthView, 'month') : true;\n }\n\n generateDaysIndexMap(firstDayOfWeek: WeekDays) {\n const firstDayIndex = this.DAYS.indexOf(firstDayOfWeek);\n const daysArr = this.DAYS.slice(firstDayIndex, 7).concat(this.DAYS.slice(0, firstDayIndex));\n return daysArr.reduce((map, day, index) => {\n map[index] = day;\n\n return map;\n }, <{[key: number]: string}>{});\n }\n\n getMonthCalendarConfig(componentConfig: IDayCalendarConfigInternal): IMonthCalendarConfig {\n return this.utilsService.clearUndefined({\n min: componentConfig.min,\n max: componentConfig.max,\n format: componentConfig.format,\n isNavHeaderBtnClickable: true,\n allowMultiSelect: false,\n yearFormat: componentConfig.yearFormat,\n yearFormatter: componentConfig.yearFormatter,\n monthBtnFormat: componentConfig.monthBtnFormat,\n monthBtnFormatter: componentConfig.monthBtnFormatter,\n monthBtnCssClassCallback: componentConfig.monthBtnCssClassCallback,\n multipleYearsNavigateBy: componentConfig.multipleYearsNavigateBy,\n showMultipleYearsNavigation: componentConfig.showMultipleYearsNavigation,\n showGoToCurrent: componentConfig.showGoToCurrent\n });\n }\n\n getDayBtnText(config: IDayCalendarConfigInternal, day: Moment): string {\n if (config.dayBtnFormatter) {\n return config.dayBtnFormatter(day);\n }\n\n return day.format(config.dayBtnFormat);\n }\n\n getDayBtnCssClass(config: IDayCalendarConfigInternal, day: Moment): string {\n if (config.dayBtnCssClassCallback) {\n return config.dayBtnCssClassCallback(day);\n }\n\n return '';\n }\n}\n","import {ECalendarValue} from '../common/types/calendar-value-enum';\nimport {SingleCalendarValue} from '../common/types/single-calendar-value';\nimport {ECalendarMode} from '../common/types/calendar-mode-enum';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n forwardRef,\n HostBinding,\n Input,\n OnChanges,\n OnInit,\n Output,\n SimpleChange,\n SimpleChanges,\n ViewEncapsulation\n} from '@angular/core';\nimport {DayCalendarService} from './day-calendar.service';\nimport * as momentNs from 'moment';\nimport {Moment, unitOfTime} from 'moment';\nimport {IDayCalendarConfig, IDayCalendarConfigInternal} from './day-calendar-config.model';\nimport {IDay} from './day.model';\nimport {\n ControlValueAccessor,\n FormControl,\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n ValidationErrors,\n Validator\n} from '@angular/forms';\nimport {CalendarValue} from '../common/types/calendar-value';\nimport {UtilsService} from '../common/services/utils/utils.service';\nimport {IMonthCalendarConfig} from '../month-calendar/month-calendar-config';\nimport {IMonth} from '../month-calendar/month.model';\nimport {DateValidator} from '../common/types/validator.type';\nimport {INavEvent} from '../common/models/navigation-event.model';\nconst moment = momentNs;\n\n@Component({\n selector: 'dp-day-calendar',\n templateUrl: 'day-calendar.component.html',\n styleUrls: ['day-calendar.component.less'],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n DayCalendarService,\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => DayCalendarComponent),\n multi: true\n },\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => DayCalendarComponent),\n multi: true\n }\n ]\n})\nexport class DayCalendarComponent implements OnInit, OnChanges, ControlValueAccessor, Validator {\n\n @Input() config: IDayCalendarConfig;\n @Input() displayDate: SingleCalendarValue;\n @Input() minDate: Moment;\n @Input() maxDate: Moment;\n @HostBinding('class') @Input() theme: string;\n\n @Output() onSelect: EventEmitter<IDay> = new EventEmitter();\n @Output() onMonthSelect: EventEmitter<IMonth> = new EventEmitter();\n @Output() onNavHeaderBtnClick: EventEmitter<ECalendarMode> = new EventEmitter();\n @Output() onGoToCurrent: EventEmitter<void> = new EventEmitter();\n @Output() onLeftNav: EventEmitter<INavEvent> = new EventEmitter();\n @Output() onRightNav: EventEmitter<INavEvent> = new EventEmitter();\n\n CalendarMode = ECalendarMode;\n isInited: boolean = false;\n componentConfig: IDayCalendarConfigInternal;\n _selected: Moment[];\n weeks: IDay[][];\n weekdays: Moment[];\n _currentDateView: Moment;\n inputValue: CalendarValue;\n inputValueType: ECalendarValue;\n validateFn: DateValidator;\n currentCalendarMode: ECalendarMode = ECalendarMode.Day;\n monthCalendarConfig: IMonthCalendarConfig;\n _shouldShowCurrent: boolean = true;\n navLabel: string;\n showLeftNav: boolean;\n showRightNav: boolean;\n\n api = {\n moveCalendarsBy: this.moveCalendarsBy.bind(this),\n moveCalendarTo: this.moveCalendarTo.bind(this),\n toggleCalendarMode: this.toggleCalendarMode.bind(this)\n };\n\n set selected(selected: Moment[]) {\n this._selected = selected;\n this.onChangeCallback(this.processOnChangeCallback(selected));\n }\n\n get selected(): Moment[] {\n return this._selected;\n }\n\n set currentDateView(current: Moment) {\n this._currentDateView = current.clone();\n this.weeks = this.dayCalendarService\n .generateMonthArray(this.componentConfig, this._currentDateView, this.selected);\n this.navLabel = this.dayCalendarService.getHeaderLabel(this.componentConfig, this._currentDateView);\n this.showLeftNav = this.dayCalendarService.shouldShowLeft(this.componentConfig.min, this.currentDateView);\n this.showRightNav = this.dayCalendarService.shouldShowRight(this.componentConfig.max, this.currentDateView);\n }\n\n get currentDateView(): Moment {\n return this._currentDateView;\n }\n\n constructor(public readonly dayCalendarService: DayCalendarService,\n public readonly utilsService: UtilsService,\n public readonly cd: ChangeDetectorRef) {\n }\n\n ngOnInit() {\n this.isInited = true;\n this.init();\n this.initValidators();\n }\n\n init() {\n this.componentConfig = this.dayCalendarService.getConfig(this.config);\n this.selected = this.selected || [];\n this.currentDateView = this.displayDate\n ? this.utilsService.convertToMoment(this.displayDate, this.componentConfig.format).clone()\n : this.utilsService\n .getDefaultDisplayDate(\n this.currentDateView,\n this.selected,\n this.componentConfig.allowMultiSelect,\n this.componentConfig.min\n );\n this.weekdays = this.dayCalendarService\n .generateWeekdays(this.componentConfig.firstDayOfWeek);\n this.inputValueType = this.utilsService.getInputType(this.inputValue, this.componentConfig.allowMultiSelect);\n this.monthCalendarConfig = this.dayCalendarService.getMonthCalendarConfig(this.componentConfig);\n this._shouldShowCurrent = this.shouldShowCurrent();\n }\n\n ngOnChanges(changes: SimpleChanges) {\n if (this.isInited) {\n const {minDate, maxDate, config} = changes;\n\n this.handleConfigChange(config);\n this.init();\n\n if (minDate || maxDate) {\n this.initValidators();\n }\n }\n }\n\n writeValue(value: CalendarValue): void {\n this.inputValue = value;\n\n if (value) {\n this.selected = this.utilsService\n .convertToMomentArray(value, this.componentConfig.format, this.componentConfig.allowMultiSelect);\n this.inputValueType = this.utilsService\n .getInputType(this.inputValue, this.componentConfig.allowMultiSelect);\n } else {\n this.selected = [];\n }\n\n this.weeks = this.dayCalendarService\n .generateMonthArray(this.componentConfig, this.currentDateView, this.selected);\n\n this.cd.markForCheck();\n }\n\n registerOnChange(fn: any): void {\n this.onChangeCallback = fn;\n }\n\n onChangeCallback(_: any) {\n };\n\n registerOnTouched(fn: any): void {\n }\n\n validate(formControl: FormControl): ValidationErrors | any {\n if (this.minDate || this.maxDate) {\n return this.validateFn(formControl.value);\n } else {\n return () => null;\n }\n }\n\n processOnChangeCallback(value: Moment[]): CalendarValue {\n return this.utilsService.convertFromMomentArray(\n this.componentConfig.format,\n value,\n this.componentConfig.returnedValueType || this.inputValueType\n );\n }\n\n initValidators() {\n this.validateFn = this.utilsService.createValidator(\n {minDate: this.minDate, maxDate: this.maxDate},\n this.componentConfig.format,\n 'day'\n );\n\n this.onChangeCallback(this.processOnChangeCallback(this.selected));\n }\n\n dayClicked(day: IDay) {\n if (day.selected && !this.componentConfig.unSelectOnClick) {\n return;\n }\n\n this.selected = this.utilsService\n .updateSelected(this.componentConfig.allowMultiSelect, this.selected, day);\n this.weeks = this.dayCalendarService\n .generateMonthArray(this.componentConfig, this.currentDateView, this.selected);\n this.onSelect.emit(day);\n }\n\n getDayBtnText(day: IDay): string {\n return this.dayCalendarService.getDayBtnText(this.componentConfig, day.date);\n }\n\n getDayBtnCssClass(day: IDay): {[klass: string]: boolean} {\n const cssClasses: {[klass: string]: boolean} = {\n 'dp-selected': day.selected,\n 'dp-current-month': day.currentMonth,\n 'dp-prev-month': day.prevMonth,\n 'dp-next-month': day.nextMonth,\n 'dp-current-day': day.currentDay\n };\n const customCssClass: string = this.dayCalendarService.getDayBtnCssClass(this.componentConfig, day.date);\n if (customCssClass) {\n cssClasses[customCssClass] = true;\n }\n\n return cssClasses;\n }\n\n onLeftNavClick() {\n const from = this.currentDateView.clone();\n this.moveCalendarsBy(this.currentDateView, -1, 'month');\n const to = this.currentDateView.clone();\n this.onLeftNav.emit({from, to});\n }\n\n onRightNavClick() {\n const from = this.currentDateView.clone();\n this.moveCalendarsBy(this.currentDateView, 1, 'month');\n const to = this.currentDateView.clone();\n this.onRightNav.emit({from, to});\n }\n\n onMonthCalendarLeftClick(change: INavEvent) {\n this.onLeftNav.emit(change);\n }\n\n onMonthCalendarRightClick(change: INavEvent) {\n this.onRightNav.emit(change);\n }\n\n onMonthCalendarSecondaryLeftClick(change: INavEvent) {\n this.onRightNav.emit(change);\n }\n\n onMonthCalendarSecondaryRightClick(change: INavEvent) {\n this.onLeftNav.emit(change);\n }\n\n getWeekdayName(weekday: Moment): string {\n if (this.componentConfig.weekDayFormatter) {\n return this.componentConfig.weekDayFormatter(weekday.day());\n }\n\n return weekday.format(this.componentConfig.weekDayFormat);\n }\n\n toggleCalendarMode(mode: ECalendarMode) {\n if (this.currentCalendarMode !== mode) {\n this.currentCalendarMode = mode;\n this.onNavHeaderBtnClick.emit(mode);\n }\n\n this.cd.markForCheck();\n }\n\n monthSelected(month: IMonth) {\n this.currentDateView = month.date.clone();\n this.currentCalendarMode = ECalendarMode.Day;\n this.onMonthSelect.emit(month);\n }\n\n moveCalendarsBy(current: Moment, amount: number, granularity: unitOfTime.Base = 'month') {\n this.currentDateView = current.clone().add(amount, granularity);\n this.cd.markForCheck();\n }\n\n moveCalendarTo(to: SingleCalendarValue) {\n if (to) {\n this.currentDateView = this.utilsService.convertToMoment(to, this.componentConfig.format);\n }\n\n this.cd.markForCheck();\n }\n\n shouldShowCurrent(): boolean {\n return this.utilsService.shouldShowCurrent(\n this.componentConfig.showGoToCurrent,\n 'day',\n this.componentConfig.min,\n this.componentConfig.max\n );\n }\n\n goToCurrent() {\n this.currentDateView = moment();\n this.onGoToCurrent.emit();\n }\n\n handleConfigChange(config: SimpleChange) {\n if (config) {\n const prevConf: IDayCalendarConfigInternal = this.dayCalendarService.getConfig(config.previousValue);\n const currentConf: IDayCalendarConfigInternal = this.dayCalendarService.getConfig(config.currentValue);\n\n if (this.utilsService.shouldResetCurrentView(prevConf, currentConf)) {\n this._currentDateView = null;\n }\n }\n }\n}\n","import {Injectable} from '@angular/core';\nimport * as momentNs from 'moment';\nimport {Moment} from 'moment';\nimport {UtilsService} from '../common/services/utils/utils.service';\nimport {ITimeSelectConfig, ITimeSelectConfigInternal} from './time-select-config.model';\nconst moment = momentNs;\n\nexport type TimeUnit = 'hour' | 'minute' | 'second';\nexport const FIRST_PM_HOUR = 12;\n\n@Injectable()\nexport class TimeSelectService {\n readonly DEFAULT_CONFIG: ITimeSelectConfigInternal = {\n hours12Format: 'hh',\n hours24Format: 'HH',\n meridiemFormat: 'A',\n minutesFormat: 'mm',\n minutesInterval: 1,\n secondsFormat: 'ss',\n secondsInterval: 1,\n showSeconds: false,\n showTwentyFourHours: false,\n timeSeparator: ':',\n locale: moment.locale()\n };\n\n constructor(private utilsService: UtilsService) {\n }\n\n getConfig(config: ITimeSelectConfig): ITimeSelectConfigInternal {\n const timeConfigs = {\n maxTime: this.utilsService.onlyTime(config && config.maxTime),\n minTime: this.utilsService.onlyTime(config && config.minTime)\n };\n\n const _config = <ITimeSelectConfigInternal>{\n ...this.DEFAULT_CONFIG,\n ...this.utilsService.clearUndefined(config),\n ...timeConfigs\n };\n\n moment.locale(_config.locale);\n\n return _config;\n }\n\n getTimeFormat(config: ITimeSelectConfigInternal): string {\n return (config.showTwentyFourHours ? config.hours24Format : config.hours12Format)\n + config.timeSeparator + config.minutesFormat\n + (config.showSeconds ? (config.timeSeparator + config.secondsFormat) : '')\n + (config.showTwentyFourHours ? '' : ' ' + config.meridiemFormat);\n }\n\n getHours(config: ITimeSelectConfigInternal, t: Moment | null): string {\n const time = t || moment();\n return time && time.format(config.showTwentyFourHours ? config.hours24Format : config.hours12Format);\n }\n\n getMinutes(config: ITimeSelectConfigInternal, t: Moment | null): string {\n const time = t || moment();\n return time && time.format(config.minutesFormat);\n }\n\n getSeconds(config: ITimeSelectConfigInternal, t: Moment | null): string {\n const time = t || moment();\n return time && time.format(config.secondsFormat);\n }\n\n getMeridiem(config: ITimeSelectConfigInternal, time: Moment): string {\n return time && time.format(config.meridiemFormat);\n }\n\n decrease(config: ITimeSelectConfigInternal, time: Moment, unit: TimeUnit): Moment {\n let amount: number = 1;\n switch (unit) {\n case 'minute':\n amount = config.minutesInterval;\n break;\n case 'second':\n amount = config.secondsInterval;\n break;\n }\n return time.clone().subtract(amount, unit);\n }\n\n increase(config: ITimeSelectConfigInternal, time: Moment, unit: TimeUnit): Moment {\n let amount: number = 1;\n switch (unit) {\n case 'minute':\n amount = config.minutesInterval;\n break;\n case 'second':\n amount = config.secondsInterval;\n break;\n }\n return time.clone().add(amount, unit);\n }\n\n toggleMeridiem(time: Moment): Moment {\n if (time.hours() < FIRST_PM_HOUR) {\n return time.clone().add(12, 'hour');\n } else {\n return time.clone().subtract(12, 'hour');\n }\n }\n\n shouldShowDecrease(config: ITimeSelectConfigInternal, time: Moment, unit: TimeUnit): boolean {\n if (!config.min && !config.minTime) {\n return true;\n }\n ;\n const newTime = this.decrease(config, time, unit);\n\n return (!config.min || config.min.isSameOrBefore(newTime))\n && (!config.minTime || config.minTime.isSameOrBefore(this.utilsService.onlyTime(newTime)));\n }\n\n shouldShowIncrease(config: ITimeSelectConfigInternal, time: Moment, unit: TimeUnit): boolean {\n if (!config.max && !config.maxTime) {\n return true;\n }\n ;\n const newTime = this.increase(config, time, unit);\n\n return (!config.max || config.max.isSameOrAfter(newTime))\n && (!config.maxTime || config.maxTime.isSameOrAfter(this.utilsService.onlyTime(newTime)));\n }\n\n shouldShowToggleMeridiem(config: ITimeSelectConfigInternal, time: Moment): boolean {\n if (!config.min && !config.max && !config.minTime && !config.maxTime) {\n return true;\n }\n const newTime = this.toggleMeridiem(time);\n return (!config.max || config.max.isSameOrAfter(newTime))\n && (!config.min || config.min.isSameOrBefore(newTime))\n && (!config.maxTime || config.maxTime.isSameOrAfter(this.utilsService.onlyTime(newTime)))\n && (!config.minTime || config.minTime.isSameOrBefore(this.utilsService.onlyTime(newTime)));\n }\n}\n","import {Injectable} from '@angular/core';\nimport * as momentNs from 'moment';\nimport {Moment} from 'moment';\n\nimport {UtilsService} from '../common/services/utils/utils.service';\nimport {DayCalendarService} from '../day-calendar/day-calendar.service';\nimport {TimeSelectService} from '../time-select/time-select.service';\nimport {IDayTimeCalendarConfig} from './day-time-calendar-config.model';\nconst moment = momentNs;\n\nconst DAY_FORMAT = 'YYYYMMDD';\nconst TIME_FORMAT = 'HH:mm:ss';\nconst COMBINED_FORMAT = DAY_FORMAT + TIME_FORMAT;\n\n@Injectable()\nexport class DayTimeCalendarService {\n readonly DEFAULT_CONFIG: IDayTimeCalendarConfig = {\n locale: moment.locale()\n };\n\n constructor(private utilsService: UtilsService,\n private dayCalendarService: DayCalendarService,\n private timeSelectService: TimeSelectService) {\n }\n\n getConfig(config: IDayTimeCalendarConfig): IDayTimeCalendarConfig {\n const _config = {\n ...this.DEFAULT_CONFIG,\n ...this.timeSelectService.getConfig(config),\n ...this.dayCalendarService.getConfig(config)\n };\n\n moment.locale(config.locale);\n\n return _config;\n }\n\n updateDay(current: Moment, day: Moment, config: IDayTimeCalendarConfig): Moment {\n const time = current ? current : moment();\n let updated = moment(day.format(DAY_FORMAT) + time.format(TIME_FORMAT), COMBINED_FORMAT)\n\n if (config.min) {\n const min = <Moment>config.min;\n updated = min.isAfter(updated) ? min : updated;\n }\n\n if (config.max) {\n const max = <Moment>config.max;\n updated = max.isBefore(updated) ? max : updated;\n }\n\n return updated;\n }\n\n updateTime(current: Moment, time: Moment): Moment {\n const day = current ? current : moment();\n\n return moment(day.format(DAY_FORMAT) + time.format(TIME_FORMAT), COMBINED_FORMAT);\n }\n}\n","import {ECalendarValue} from '../common/types/calendar-value-enum';\nimport {SingleCalendarValue} from '../common/types/single-calendar-value';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n EventEmitter,\n forwardRef,\n HostBinding,\n Input,\n OnChanges,\n OnInit,\n Output,\n SimpleChanges,\n ViewEncapsulation\n} from '@angular/core';\nimport {TimeSelectService, TimeUnit} from './time-select.service';\nimport * as momentNs from 'moment';\nimport {Moment} from 'moment';\nimport {ITimeSelectConfig, ITimeSelectConfigInternal} from './time-select-config.model';\nimport {\n ControlValueAccessor,\n FormControl,\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n ValidationErrors,\n Validator\n} from '@angular/forms';\