diff --git a/apps/common/main/lib/component/Calendar.js b/apps/common/main/lib/component/Calendar.js
new file mode 100644
index 000000000..cc4f360e1
--- /dev/null
+++ b/apps/common/main/lib/component/Calendar.js
@@ -0,0 +1,374 @@
+/*
+ *
+ * (c) Copyright Ascensio System SIA 2010-2019
+ *
+ * This program is a free software product. You can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License (AGPL)
+ * version 3 as published by the Free Software Foundation. In accordance with
+ * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
+ * that Ascensio System SIA expressly excludes the warranty of non-infringement
+ * of any third-party rights.
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
+ * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+ *
+ * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
+ * street, Riga, Latvia, EU, LV-1050.
+ *
+ * The interactive user interfaces in modified source and object code versions
+ * of the Program must display Appropriate Legal Notices, as required under
+ * Section 5 of the GNU AGPL version 3.
+ *
+ * Pursuant to Section 7(b) of the License you must retain the original Product
+ * logo when distributing the program. Pursuant to Section 7(e) we decline to
+ * grant you any rights under trademark law for use of our trademarks.
+ *
+ * All the Product's GUI elements, including illustrations and icon sets, as
+ * well as technical writing content are licensed under the terms of the
+ * Creative Commons Attribution-ShareAlike 4.0 International. See the License
+ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+ *
+*/
+if (Common === undefined)
+ var Common = {};
+
+define([
+ 'common/main/lib/component/BaseView',
+ 'common/main/lib/util/utils'
+
+], function () {
+ 'use strict';
+
+ Common.UI.Calendar = Common.UI.BaseView.extend({
+
+ template :
+ _.template([
+ '
'
+ ].join('')),
+
+ options: {
+ date: undefined
+ },
+
+ initialize : function(options) {
+ Common.UI.BaseView.prototype.initialize.call(this, options);
+
+ var me = this;
+ me.cmpEl = me.$el || $(this.el);
+
+ this.monthNames = [this.textJanuary, this.textFebruary, this.textMarch, this.textApril, this.textMay, this.textJune, this.textJuly, this.textAugust, this.textSeptember, this.textOctober, this.textNovember, this.textDecember];
+ this.dayNamesShort = [this.textShortSunday, this.textShortMonday, this.textShortTuesday, this.textShortWednesday, this.textShortThursday, this.textShortFriday, this.textShortSaturday];
+ this.monthShortNames = [this.textShortJanuary, this.textShortFebruary, this.textShortMarch, this.textShortApril, this.textShortMay, this.textShortJune, this.textShortJuly, this.textShortAugust, this.textShortSeptember, this.textShortOctober, this.textShortNovember, this.textShortDecember];
+
+ me.options.date = options.date;
+
+ me._state = undefined;
+
+ me.render();
+ },
+
+ render: function () {
+ (this.$el || $(this.el)).html(this.template());
+
+ var me = this;
+
+ me.currentDate = me.options.date || new Date();
+
+ me.btnPrev = new Common.UI.Button({
+ cls: 'btn-toolbar',
+ iconCls: 'mmerge-prev',
+ });
+ me.btnPrev.render(me.cmpEl.find('#prev-arrow'));
+ me.btnPrev.on('click', _.bind(me.onClickPrev, me));
+
+ me.btnNext = new Common.UI.Button({
+ cls: 'btn-toolbar',
+ iconCls: 'mmerge-next',
+ });
+ me.btnNext.render(me.cmpEl.find('#next-arrow'));
+ me.btnNext.on('click', _.bind(me.onClickNext, me));
+
+ me.renderMonth(me.currentDate);
+
+ this.trigger('render:after', this);
+ return this;
+ },
+
+ onClickPrev: function () {
+ var me = this;
+ if (me._state === 'month') {
+ me.currentDate.setMonth(me.currentDate.getMonth() - 1);
+ me.renderMonth(me.currentDate);
+ } else if (me._state === 'months') {
+ me.currentDate.setFullYear(me.currentDate.getFullYear() - 1);
+ me.renderMonths(me.currentDate);
+ } else if (me._state === 'years') {
+ var year = me.currentDate.getFullYear(),
+ newYear;
+ if (year % 10 !== 0) {
+ newYear = String(year);
+ newYear = Number(newYear.slice(0, -1) + '0') - 1;
+ } else {
+ newYear = year - 1;
+ }
+ me.currentDate.setFullYear(newYear);
+ me.renderYears(newYear);
+ }
+ },
+
+ onClickNext: function () {
+ var me = this;
+ if (me._state === 'month') {
+ me.currentDate.setMonth(me.currentDate.getMonth() + 1);
+ me.renderMonth(me.currentDate);
+ } else if (me._state === 'months') {
+ me.currentDate.setFullYear(me.currentDate.getFullYear() + 1);
+ me.renderMonths(me.currentDate);
+ } else if (me._state === 'years') {
+ var year = me.currentDate.getFullYear(),
+ newYear;
+ if (year % 10 !== 9) {
+ newYear = String(year);
+ newYear = Number(newYear.slice(0, -1) + '9') + 1;
+ } else {
+ newYear = year + 1;
+ }
+ me.currentDate.setFullYear(newYear);
+ me.renderYears(newYear);
+ }
+ },
+
+ renderYears: function (year) {
+ var me = this,
+ year = _.isNumber(year) ? year : (me.currentDate ? me.currentDate.getFullYear() : (new Date()).getFullYear());
+
+ me._state = 'years';
+
+ var firstYear = year,
+ lastYear = year;
+ if ((firstYear % 10) !== 0) {
+ var strYear = String(year);
+ firstYear = Number(strYear.slice(0, -1) + '0');
+ }
+ if ((lastYear % 10) !== 9) {
+ var strYear = String(year);
+ lastYear = Number(strYear.slice(0, -1) + '9');
+ }
+
+ me.topTitle = _.template([
+ '' + firstYear + '-' + lastYear + ' '
+ ].join(''));
+ me.cmpEl.find('.calendar-header .title').html(me.topTitle);
+
+ me.bottomTitle = _.template([
+ '' + me.textYears + ' '
+ ].join(''));
+ me.cmpEl.find('.calendar-header .bottom-row').html(me.bottomTitle);
+
+ var arrYears = [];
+ var tmpYear = firstYear - 3;
+
+ for (var i = 0; i < 16; i++) {
+ arrYears.push({
+ year: tmpYear,
+ isCurrentDecade: ((tmpYear >= firstYear) && (tmpYear <= lastYear)) ? true : false
+ });
+ tmpYear++;
+ }
+
+ me.yearPicker = new Common.UI.DataView({
+ el: $('.calendar-content'),
+ store: new Common.UI.DataViewStore(arrYears),
+ itemTemplate: _.template('<%= year %>
')
+ });
+ me.yearPicker.on('item:click', function (picker, item) {
+ var selectYear = item.$el.children(),
+ year = selectYear.data('year');
+ var date = new Date();
+ date.setFullYear(year);
+ me.renderMonths(date);
+ });
+ },
+
+ renderMonths: function (date) {
+ var me = this,
+ curDate = (_.isDate(date)) ? date : (me.currentDate ? me.currentDate : new Date()),
+ year = curDate.getFullYear();
+
+ me._state = 'months';
+
+ // Number of year
+ me.topTitle = _.template([
+ '' + year + ' '
+ ].join(''));
+ me.cmpEl.find('.calendar-header .title').html(me.topTitle);
+ me.cmpEl.find('.calendar-header .title').on('click', _.bind(me.renderYears, me));
+
+ me.bottomTitle = _.template([
+ '' + me.textMonths + ' '
+ ].join(''));
+ me.cmpEl.find('.calendar-header .bottom-row').html(me.bottomTitle);
+
+ var arrMonths = [];
+
+ for (var ind = 0; ind < 12; ind++) {
+ arrMonths.push({
+ indexMonth: ind,
+ nameMonth: me.monthShortNames[ind],
+ year: year,
+ curYear: true,
+ isCurrentMonth: (ind === curDate.getMonth())
+ });
+ }
+ for (var ind = 0; ind < 4; ind++) {
+ arrMonths.push({
+ indexMonth: ind,
+ nameMonth: me.monthShortNames[ind],
+ year: year + 1,
+ curYear: false
+ });
+ }
+
+ me.monthPicker = new Common.UI.DataView({
+ el: $('.calendar-content'),
+ store: new Common.UI.DataViewStore(arrMonths),
+ itemTemplate: _.template('<%= nameMonth %>
')
+ });
+ me.monthPicker.on('item:click', function (picker, item) {
+ var selectMonth = item.$el.children(),
+ month = selectMonth.data('month'),
+ year = selectMonth.data('year');
+ var date = new Date(year, month);
+ me.renderMonth(date);
+ });
+ },
+
+ renderMonth: function (date) {
+ var me = this;
+ me._state = 'month';
+ // Current date
+ var curDate = date || new Date(),
+ curMonth = curDate.getMonth(),
+ curIndexDayInWeek = curDate.getDay(),
+ curNumberDayInMonth = curDate.getDate(),
+ curYear = curDate.getFullYear();
+
+ // Name month
+ me.topTitle = _.template([
+ '' + me.monthNames[curMonth] + ' ',
+ '' + curYear + ' '
+ ].join(''));
+ me.cmpEl.find('.calendar-header .title').html(me.topTitle);
+ me.cmpEl.find('.calendar-header .title').on('click', _.bind(me.renderMonths, me));
+
+ // Name days of week
+ var dayNamesTemplate = '';
+ me.dayNamesShort.forEach(function (item) {
+ dayNamesTemplate += '' + item + ' ';
+ });
+ me.cmpEl.find('.calendar-header .bottom-row').html(_.template(dayNamesTemplate));
+
+ // Month
+ var rows = 6,
+ cols = 7,
+ firstNumber = me.options.firstNumber;
+
+ var arrDays = [];
+
+ var d = new Date(curDate);
+ d.setDate(1);
+ var firstDayOfMonthIndex = d.getDay();
+
+ var daysInPrevMonth = me.daysInMonth(d.getTime() - (10 * 24 * 60 * 60 * 1000)),
+ numberDay = (firstDayOfMonthIndex > 0) ? (daysInPrevMonth - (firstDayOfMonthIndex - 1)) : 1,
+ month,
+ year;
+ if (firstDayOfMonthIndex > 0) {
+ if (curMonth - 1 >= 0) {
+ month = curMonth - 1
+ year = curYear;
+ } else {
+ month = 11;
+ year = curYear - 1;
+ }
+ } else {
+ month = curMonth;
+ year = curYear;
+ }
+
+ var tmp = new Date(year, month, numberDay);
+
+ for(var r = 0; r < rows; r++) {
+ for(var c = 0; c < cols; c++) {
+ arrDays.push({
+ indexInWeek: tmp.getDay(),
+ dayNumber: tmp.getDate(),
+ month: tmp.getMonth(),
+ year: tmp.getFullYear(),
+ isToday: (tmp.getDate() === curNumberDayInMonth) ? true : false,
+ isCurrentMonth: (tmp.getMonth() === curMonth) ? true : false
+ });
+ tmp.setDate(tmp.getDate() + 1);
+ }
+ }
+
+ me.monthPicker = new Common.UI.DataView({
+ el: $('.calendar-content'),
+ store: new Common.UI.DataViewStore(arrDays),
+ itemTemplate: _.template('<%= dayNumber %>
')
+ });
+ },
+
+ daysInMonth: function (date) {
+ var d;
+ d = date ? new Date(date) : new Date();
+ return (new Date(d.getFullYear(), d.getMonth() + 1, 0)).getDate();
+ },
+
+ textJanuary: 'January',
+ textFebruary: 'February',
+ textMarch: 'March',
+ textApril: 'April',
+ textMay: 'May',
+ textJune: 'June',
+ textJuly: 'July',
+ textAugust: 'August',
+ textSeptember: 'September',
+ textOctober: 'October',
+ textNovember: 'November',
+ textDecember: 'December',
+ textShortJanuary: 'Jan',
+ textShortFebruary: 'Feb',
+ textShortMarch: 'Mar',
+ textShortApril: 'Apr',
+ textShortMay: 'May',
+ textShortJune: 'Jun',
+ textShortJuly: 'Jul',
+ textShortAugust: 'Aug',
+ textShortSeptember: 'Sep',
+ textShortOctober: 'Oct',
+ textShortNovember: 'Nov',
+ textShortDecember: 'Dec',
+ textShortSunday: 'Su',
+ textShortMonday: 'Mo',
+ textShortTuesday: 'Tu',
+ textShortWednesday: 'We',
+ textShortThursday: 'Th',
+ textShortFriday: 'Fr',
+ textShortSaturday: 'Sa',
+ textMonths: 'Months',
+ textYears: 'Years'
+ });
+});
\ No newline at end of file
diff --git a/apps/common/main/lib/view/Calendar.js b/apps/common/main/lib/view/Calendar.js
index 7e433f35b..5cd483371 100644
--- a/apps/common/main/lib/view/Calendar.js
+++ b/apps/common/main/lib/view/Calendar.js
@@ -44,8 +44,8 @@ if (Common === undefined)
define([
'common/main/lib/component/Window',
- 'underscore'
-], function (base, _) {
+ 'common/main/lib/component/Calendar',
+], function () {
'use strict';
Common.Views.Calendar = Common.UI.Window.extend(_.extend({
@@ -57,8 +57,8 @@ define([
_.extend(_options, {
closable: false,
- width: 192,
- height: 214,
+ width: 200,
+ height: 220,
header: false,
modal: false,
alias: 'Common.Views.Calendar',
@@ -69,27 +69,11 @@ define([
this.template = options.template || [
''
].join('');
- this.monthNames = [this.textJanuary, this.textFebruary, this.textMarch, this.textApril, this.textMay, this.textJune, this.textJuly, this.textAugust, this.textSeptember, this.textOctober, this.textNovember, this.textDecember];
- this.dayNamesShort = [this.textShortSunday, this.textShortMonday, this.textShortTuesday, this.textShortWednesday, this.textShortThursday, this.textShortFriday, this.textShortSaturday];
-
-
_options.tpl = _.template(this.template)(_options);
@@ -105,7 +89,7 @@ define([
window.css({
height: '',
- minHeight: '',
+ minHeight: 222,
overflow: 'hidden',
position: 'absolute',
zIndex: '990'
@@ -116,29 +100,9 @@ define([
body.css('position', 'relative');
}
- me.btnPrev = new Common.UI.Button({
- cls: 'btn-toolbar',
- iconCls: 'mmerge-prev',
+ me.calendar = new Common.UI.Calendar({
+ el: $('#id-popover')
});
- me.btnPrev.render(me.$window.find('#prev-arrow'));
-
- me.btnNext = new Common.UI.Button({
- cls: 'btn-toolbar',
- iconCls: 'mmerge-next',
- });
- me.btnNext.render(me.$window.find('#next-arrow'));
-
- me.topTitle = _.template([
- '' + me.monthNames[0] + ' ',
- '' + 2019 + ' '
- ].join(''));
- me.$window.find('.calendar-header .title').html(me.topTitle);
-
- var dayNamesTemplate = '';
- me.dayNamesShort.forEach(function (item) {
- dayNamesTemplate += '' + item + ' ';
- });
- me.$window.find('.calendar-header .bottom-row').html(_.template(dayNamesTemplate));
},
@@ -268,25 +232,5 @@ define([
}
},
- textJanuary: 'January',
- textFebruary: 'February',
- textMarch: 'March',
- textApril: 'April',
- textMay: 'May',
- textJune: 'June',
- textJuly: 'July',
- textAugust: 'August',
- textSeptember: 'September',
- textOctober: 'October',
- textNovember: 'November',
- textDecember: 'December',
- textShortSunday: 'Su',
- textShortMonday: 'Mo',
- textShortTuesday: 'Tu',
- textShortWednesday: 'We',
- textShortThursday: 'Th',
- textShortFriday: 'Fr',
- textShortSaturday: 'Sa'
-
}, Common.Views.Calendar || {}))
});
\ No newline at end of file
diff --git a/apps/common/main/resources/less/calendar.less b/apps/common/main/resources/less/calendar.less
index 9ba98c372..5bcd74011 100644
--- a/apps/common/main/resources/less/calendar.less
+++ b/apps/common/main/resources/less/calendar.less
@@ -3,11 +3,11 @@
.calendar-window {
border-radius: 0;
box-shadow: none;
- border: 1px solid @calendar-bg-color;
}
-.calendar-popover {
- width: 190px;
- height: 214px;
+.calendar-box {
+ width: 198px;
+ height: 220px;
+ border: 1px solid @calendar-bg-color;
.btn {
background-color: transparent;
border: none;
@@ -31,8 +31,8 @@
}
.bottom-row {
display: flex;
- justify-content: space-between;
- padding: 0 10px;
+ justify-content: space-around;
+ padding: 0;
}
.title {
padding-top: 6px;
@@ -44,6 +44,54 @@
}
}
+ }
+ }
+ .calendar-content {
+ .item {
+ margin: 0;
+ padding: 0;
+ height: auto;
+ width: auto;
+ box-shadow: none;
+ border: 1px solid #fff;
+ .name-month, .name-year {
+ height: 40px;
+ width: 47px;
+ background-color: #F1F1F1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 13px;
+ }
+ .number-day {
+ height: 26px;
+ width: 26px;
+ background-color: #F1F1F1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+ &.selected {
+ .number-day, .name-month, .name-year {
+ color: #fff;
+ background-color: #7D858C;
+ }
+ }
+ .weekend {
+ color: #D25252;
+ }
+ .no-current-month, .no-cur-year, .no-current-decade {
+ color: #A5A5A5;
+ }
+ &:not(.disabled):not(.selected) {
+ .number-day, .name-month, .name-year {
+ &:hover {
+ background-color: #D9D9D9;
+ }
+ }
+ }
+
+
}
}
}
\ No newline at end of file