@smart-solutions-tech/smart-angular-calendar 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/components/calendar/calendar.component.mjs +9 -7
- package/esm2020/lib/components/day/day.component.mjs +92 -0
- package/esm2020/lib/components/duration-event/duration-event.component.mjs +56 -0
- package/esm2020/lib/components/month-selector/month-selector.component.mjs +82 -0
- package/esm2020/lib/components/more-events-modal/more-events-modal.component.mjs +2 -2
- package/esm2020/lib/components/smart-calendar/smart-calendar.component.mjs +180 -6
- package/esm2020/lib/pipes/translate-month.pipe.mjs +22 -0
- package/esm2020/lib/smart-angular-calendar.module.mjs +15 -3
- package/esm2020/lib/translations.mjs +43 -1
- package/esm2020/lib/types.mjs +1 -1
- package/fesm2015/smart-solutions-tech-smart-angular-calendar.mjs +468 -13
- package/fesm2015/smart-solutions-tech-smart-angular-calendar.mjs.map +1 -1
- package/fesm2020/smart-solutions-tech-smart-angular-calendar.mjs +467 -13
- package/fesm2020/smart-solutions-tech-smart-angular-calendar.mjs.map +1 -1
- package/lib/components/calendar/calendar.component.d.ts +4 -13
- package/lib/components/day/day.component.d.ts +28 -0
- package/lib/components/duration-event/duration-event.component.d.ts +20 -0
- package/lib/components/month-selector/month-selector.component.d.ts +30 -0
- package/lib/components/smart-calendar/smart-calendar.component.d.ts +36 -2
- package/lib/pipes/translate-month.pipe.d.ts +10 -0
- package/lib/smart-angular-calendar.module.d.ts +6 -2
- package/lib/translations.d.ts +14 -0
- package/lib/types.d.ts +14 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, Component, Input, Pipe, EventEmitter, Output, ViewChild, NgModule } from '@angular/core';
|
|
2
|
+
import { Injectable, Component, Input, Pipe, EventEmitter, Output, ViewChild, HostListener, NgModule } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
|
|
@@ -54,6 +54,20 @@ const TRANSLATIONS = {
|
|
|
54
54
|
thu: 'Thursday',
|
|
55
55
|
fri: 'Friday',
|
|
56
56
|
sat: 'Saturday',
|
|
57
|
+
today: 'Today',
|
|
58
|
+
allDayEvents: 'All-day events',
|
|
59
|
+
january: 'January',
|
|
60
|
+
february: 'February',
|
|
61
|
+
march: 'March',
|
|
62
|
+
april: 'April',
|
|
63
|
+
may: 'May',
|
|
64
|
+
june: 'June',
|
|
65
|
+
july: 'July',
|
|
66
|
+
august: 'August',
|
|
67
|
+
september: 'September',
|
|
68
|
+
october: 'October',
|
|
69
|
+
november: 'November',
|
|
70
|
+
december: 'December',
|
|
57
71
|
moreEvents: 'More events',
|
|
58
72
|
nMoreEvents: '{{n}} More events'
|
|
59
73
|
},
|
|
@@ -65,9 +79,37 @@ const TRANSLATIONS = {
|
|
|
65
79
|
thu: 'Jueves',
|
|
66
80
|
fri: 'Viernes',
|
|
67
81
|
sat: 'Sábado',
|
|
82
|
+
today: 'Hoy',
|
|
83
|
+
allDayEvents: 'Eventos de todo el día',
|
|
84
|
+
january: 'Enero',
|
|
85
|
+
february: 'Febrero',
|
|
86
|
+
march: 'Marzo',
|
|
87
|
+
april: 'Abril',
|
|
88
|
+
may: 'Mayo',
|
|
89
|
+
june: 'Junio',
|
|
90
|
+
july: 'Julio',
|
|
91
|
+
august: 'Agosto',
|
|
92
|
+
september: 'Septiembre',
|
|
93
|
+
october: 'Octubre',
|
|
94
|
+
november: 'Noviembre',
|
|
95
|
+
december: 'Diciembre',
|
|
68
96
|
moreEvents: 'Más eventos',
|
|
69
97
|
nMoreEvents: '{{n}} Eventos más'
|
|
70
98
|
},
|
|
99
|
+
};
|
|
100
|
+
const MONTHS = {
|
|
101
|
+
1: 'january',
|
|
102
|
+
2: 'february',
|
|
103
|
+
3: 'march',
|
|
104
|
+
4: 'april',
|
|
105
|
+
5: 'may',
|
|
106
|
+
6: 'june',
|
|
107
|
+
7: 'july',
|
|
108
|
+
8: 'august',
|
|
109
|
+
9: 'september',
|
|
110
|
+
10: 'october',
|
|
111
|
+
11: 'november',
|
|
112
|
+
12: 'december'
|
|
71
113
|
};
|
|
72
114
|
|
|
73
115
|
class TranslationService {
|
|
@@ -132,10 +174,10 @@ class MoreEventsModalComponent {
|
|
|
132
174
|
}
|
|
133
175
|
}
|
|
134
176
|
MoreEventsModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MoreEventsModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
135
|
-
MoreEventsModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MoreEventsModalComponent, selector: "lib-more-events-modal", inputs: { events: "events", date: "date" }, outputs: { close: "close", eventClick: "eventClick" }, ngImport: i0, template: "<div class=\"more-events-modal-component\">\n <div class=\"backdrop\" (click)=\"onClose()\"></div>\n\n <div class=\"modal\">\n <div class=\"header\">\n <div class=\"title\">{{'moreEvents' | translate}}</div>\n <div class=\"subtitle\">{{date.toLocaleDateString()}}</div>\n\n <button class=\"btn-close\" (click)=\"onClose()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n class=\"feather feather-x\" fill=\"yellow\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n\n <div class=\"events-list\">\n <div class=\"event-item\" *ngFor=\"let event of events\" style=\"--color: {{event.color}};\"\n [ngClass]=\"{'is-dark':isDarkColor(event.color)}\" (click)=\"onEventClick(event)\">\n <div class=\"event-title\">{{ event.title }}</div>\n </div>\n </div>\n </div>\n</div>", styles: [".more-events-modal-component{position:absolute;top:0;left:0;z-index:1;display:flex;align-items:center;justify-content:center;width:
|
|
177
|
+
MoreEventsModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MoreEventsModalComponent, selector: "lib-more-events-modal", inputs: { events: "events", date: "date" }, outputs: { close: "close", eventClick: "eventClick" }, ngImport: i0, template: "<div class=\"more-events-modal-component\">\n <div class=\"backdrop\" (click)=\"onClose()\"></div>\n\n <div class=\"modal\">\n <div class=\"header\">\n <div class=\"title\">{{'moreEvents' | translate}}</div>\n <div class=\"subtitle\">{{date.toLocaleDateString()}}</div>\n\n <button class=\"btn-close\" (click)=\"onClose()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n class=\"feather feather-x\" fill=\"yellow\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n\n <div class=\"events-list\">\n <div class=\"event-item\" *ngFor=\"let event of events\" style=\"--color: {{event.color}};\"\n [ngClass]=\"{'is-dark':isDarkColor(event.color)}\" (click)=\"onEventClick(event)\">\n <div class=\"event-title\">{{ event.title }}</div>\n </div>\n </div>\n </div>\n</div>", styles: [".more-events-modal-component{position:absolute;top:0;left:0;z-index:1;display:flex;align-items:center;justify-content:center;width:100%;height:100%;box-shadow:0 2px 8px #00000026}.more-events-modal-component .backdrop{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;background-color:#00000080;cursor:pointer}.modal{z-index:2;display:flex;flex-direction:column;max-width:400px;width:100%;max-height:80%;margin:24px;background-color:#fff;border-radius:8px}.header{position:relative;display:flex;flex-direction:column;padding:16px 64px 16px 16px}.title{font-size:18px;font-weight:700}.subtitle{font-size:13px;color:#666}.btn-close{position:absolute;top:8px;right:8px;display:flex;align-items:center;justify-content:center;width:36px;height:36px;background:none;border:none;border-radius:50%;cursor:pointer}.btn-close:hover{background-color:#f0f0f0}.events-list{flex:1 1 auto;display:flex;flex-direction:column;gap:4px;padding:0 16px 16px;overflow-y:auto}.events-list .event-item{display:flex;padding:8px;background-color:var(--color, #e2e2e2);border-radius:4px;color:#212121;cursor:pointer;-webkit-user-select:none;user-select:none}.events-list .event-item.is-dark{color:#fafafa}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
136
178
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MoreEventsModalComponent, decorators: [{
|
|
137
179
|
type: Component,
|
|
138
|
-
args: [{ selector: 'lib-more-events-modal', template: "<div class=\"more-events-modal-component\">\n <div class=\"backdrop\" (click)=\"onClose()\"></div>\n\n <div class=\"modal\">\n <div class=\"header\">\n <div class=\"title\">{{'moreEvents' | translate}}</div>\n <div class=\"subtitle\">{{date.toLocaleDateString()}}</div>\n\n <button class=\"btn-close\" (click)=\"onClose()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n class=\"feather feather-x\" fill=\"yellow\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n\n <div class=\"events-list\">\n <div class=\"event-item\" *ngFor=\"let event of events\" style=\"--color: {{event.color}};\"\n [ngClass]=\"{'is-dark':isDarkColor(event.color)}\" (click)=\"onEventClick(event)\">\n <div class=\"event-title\">{{ event.title }}</div>\n </div>\n </div>\n </div>\n</div>", styles: [".more-events-modal-component{position:absolute;top:0;left:0;z-index:1;display:flex;align-items:center;justify-content:center;width:
|
|
180
|
+
args: [{ selector: 'lib-more-events-modal', template: "<div class=\"more-events-modal-component\">\n <div class=\"backdrop\" (click)=\"onClose()\"></div>\n\n <div class=\"modal\">\n <div class=\"header\">\n <div class=\"title\">{{'moreEvents' | translate}}</div>\n <div class=\"subtitle\">{{date.toLocaleDateString()}}</div>\n\n <button class=\"btn-close\" (click)=\"onClose()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n class=\"feather feather-x\" fill=\"yellow\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n\n <div class=\"events-list\">\n <div class=\"event-item\" *ngFor=\"let event of events\" style=\"--color: {{event.color}};\"\n [ngClass]=\"{'is-dark':isDarkColor(event.color)}\" (click)=\"onEventClick(event)\">\n <div class=\"event-title\">{{ event.title }}</div>\n </div>\n </div>\n </div>\n</div>", styles: [".more-events-modal-component{position:absolute;top:0;left:0;z-index:1;display:flex;align-items:center;justify-content:center;width:100%;height:100%;box-shadow:0 2px 8px #00000026}.more-events-modal-component .backdrop{position:absolute;top:0;left:0;z-index:1;width:100%;height:100%;background-color:#00000080;cursor:pointer}.modal{z-index:2;display:flex;flex-direction:column;max-width:400px;width:100%;max-height:80%;margin:24px;background-color:#fff;border-radius:8px}.header{position:relative;display:flex;flex-direction:column;padding:16px 64px 16px 16px}.title{font-size:18px;font-weight:700}.subtitle{font-size:13px;color:#666}.btn-close{position:absolute;top:8px;right:8px;display:flex;align-items:center;justify-content:center;width:36px;height:36px;background:none;border:none;border-radius:50%;cursor:pointer}.btn-close:hover{background-color:#f0f0f0}.events-list{flex:1 1 auto;display:flex;flex-direction:column;gap:4px;padding:0 16px 16px;overflow-y:auto}.events-list .event-item{display:flex;padding:8px;background-color:var(--color, #e2e2e2);border-radius:4px;color:#212121;cursor:pointer;-webkit-user-select:none;user-select:none}.events-list .event-item.is-dark{color:#fafafa}\n"] }]
|
|
139
181
|
}], ctorParameters: function () { return []; }, propDecorators: { events: [{
|
|
140
182
|
type: Input
|
|
141
183
|
}], date: [{
|
|
@@ -154,7 +196,6 @@ class CalendarComponent {
|
|
|
154
196
|
};
|
|
155
197
|
this.events = [];
|
|
156
198
|
this.startAt = 'sunday';
|
|
157
|
-
this.monthChange = new EventEmitter();
|
|
158
199
|
this.dayCells = [];
|
|
159
200
|
this.weekDays = [
|
|
160
201
|
{ tag: 'sun' },
|
|
@@ -265,23 +306,26 @@ class CalendarComponent {
|
|
|
265
306
|
this.setMaxEventsInDayCell();
|
|
266
307
|
});
|
|
267
308
|
}
|
|
309
|
+
ngOnChanges(changes) {
|
|
310
|
+
if (changes['currentMonth']) {
|
|
311
|
+
this.initDaysCells();
|
|
312
|
+
}
|
|
313
|
+
}
|
|
268
314
|
onDestroy() {
|
|
269
315
|
window.removeEventListener('resize', this.resizeListener);
|
|
270
316
|
}
|
|
271
317
|
}
|
|
272
318
|
CalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
273
|
-
CalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CalendarComponent, selector: "lib-calendar", inputs: { currentMonth: "currentMonth", events: "events", startAt: "startAt" },
|
|
319
|
+
CalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CalendarComponent, selector: "lib-calendar", inputs: { currentMonth: "currentMonth", events: "events", startAt: "startAt" }, viewQueries: [{ propertyName: "calendarRef", first: true, predicate: ["calendar"], descendants: true }, { propertyName: "calendarBodyRef", first: true, predicate: ["calendarBody"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"calendar-component\">\r\n <div class=\"body\" #calendarBody>\r\n <div class=\"week-days\">\r\n <div class=\"week-day\" *ngFor=\"let day of weekDays\">\r\n {{ day.tag | translate | slice:0:3 }}\r\n </div>\r\n </div>\r\n\r\n <div class=\"days-grid\">\r\n <div class=\"day-cell\" *ngFor=\"let day of dayCells; let i = index\"\r\n [ngClass]=\"{'outside-month': day.isOutsideMonth, 'is-today': day.isToday}\">\r\n <div class=\"day-number\">\r\n {{ day.date.getDate() }}\r\n </div>\r\n\r\n <div class=\"events-list\">\r\n <lib-calendar-event *ngFor=\"let event of day.events | slice:0:maxEventsInDayCell\"\r\n [event]=\"event\"></lib-calendar-event>\r\n\r\n <div class=\"more-events\" *ngIf=\"day.events.length > (maxEventsInDayCell || 0)\"\r\n (click)=\"openMoreEventsModal(day.date, day.events)\">\r\n {{'nMoreEvents' | translate: {n:(day.events.length - (maxEventsInDayCell || 0))} }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"footer\">\r\n Footer\r\n </div>\r\n\r\n <lib-more-events-modal *ngIf=\"showMoreEventsModal && moreEventsModalDate\" [events]=\"moreEventsModalEvents\"\r\n [date]=\"moreEventsModalDate\" (close)=\"closeMoreEventsModal()\"\r\n (eventClick)=\"closeMoreEventsModal()\"></lib-more-events-modal>\r\n</div>", styles: ["*{box-sizing:border-box;margin:0;padding:0}.calendar-component{display:flex;flex-direction:column;width:100%;height:100%}.body{flex:1 1 0;display:flex;flex-direction:column;width:100%;min-height:0;height:100%}.week-days{flex-shrink:0;display:grid;grid-template-columns:repeat(7,1fr);width:100%;background-color:#f4f4f4}.week-day{display:flex;align-items:center;justify-content:center;padding:4px;background-color:#fff;font-size:14px;color:#00000080}.days-grid{flex:1 1 0;display:grid;grid-template-columns:repeat(7,1fr);gap:1px;grid-auto-rows:1fr;width:100%;padding:1px;background-color:#f4f4f4;min-height:0;height:100%}.day-cell{display:flex;flex-direction:column;gap:4px;padding:4px;background-color:#fff;overflow:hidden}.day-cell .day-number{display:flex;align-items:center;justify-content:center;width:fit-content;aspect-ratio:1;padding:2px;border-radius:50%;font-size:12px;line-height:16px;font-weight:600;-webkit-user-select:none;user-select:none}.day-cell.outside-month{background-color:#f8f8f8}.day-cell.is-today .day-number{background-color:#007bff;color:#fff}.day-cell .events-list{flex:1 1 auto;display:flex;flex-direction:column;gap:2px;overflow:hidden;min-height:0;max-height:100%}.day-cell .events-list .more-events{padding:2px 8px;border-radius:4px;font-size:12px;color:#555;cursor:pointer}.day-cell .events-list .more-events:hover{background-color:#eee}.footer{flex-shrink:0;background-color:#add8e6}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CalendarEventComponent, selector: "lib-calendar-event", inputs: ["event"] }, { kind: "component", type: MoreEventsModalComponent, selector: "lib-more-events-modal", inputs: ["events", "date"], outputs: ["close", "eventClick"] }, { kind: "pipe", type: i1.SlicePipe, name: "slice" }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
274
320
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CalendarComponent, decorators: [{
|
|
275
321
|
type: Component,
|
|
276
|
-
args: [{ selector: 'lib-calendar', template: "<div class=\"calendar-component\">\r\n <div class=\"
|
|
322
|
+
args: [{ selector: 'lib-calendar', template: "<div class=\"calendar-component\">\r\n <div class=\"body\" #calendarBody>\r\n <div class=\"week-days\">\r\n <div class=\"week-day\" *ngFor=\"let day of weekDays\">\r\n {{ day.tag | translate | slice:0:3 }}\r\n </div>\r\n </div>\r\n\r\n <div class=\"days-grid\">\r\n <div class=\"day-cell\" *ngFor=\"let day of dayCells; let i = index\"\r\n [ngClass]=\"{'outside-month': day.isOutsideMonth, 'is-today': day.isToday}\">\r\n <div class=\"day-number\">\r\n {{ day.date.getDate() }}\r\n </div>\r\n\r\n <div class=\"events-list\">\r\n <lib-calendar-event *ngFor=\"let event of day.events | slice:0:maxEventsInDayCell\"\r\n [event]=\"event\"></lib-calendar-event>\r\n\r\n <div class=\"more-events\" *ngIf=\"day.events.length > (maxEventsInDayCell || 0)\"\r\n (click)=\"openMoreEventsModal(day.date, day.events)\">\r\n {{'nMoreEvents' | translate: {n:(day.events.length - (maxEventsInDayCell || 0))} }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"footer\">\r\n Footer\r\n </div>\r\n\r\n <lib-more-events-modal *ngIf=\"showMoreEventsModal && moreEventsModalDate\" [events]=\"moreEventsModalEvents\"\r\n [date]=\"moreEventsModalDate\" (close)=\"closeMoreEventsModal()\"\r\n (eventClick)=\"closeMoreEventsModal()\"></lib-more-events-modal>\r\n</div>", styles: ["*{box-sizing:border-box;margin:0;padding:0}.calendar-component{display:flex;flex-direction:column;width:100%;height:100%}.body{flex:1 1 0;display:flex;flex-direction:column;width:100%;min-height:0;height:100%}.week-days{flex-shrink:0;display:grid;grid-template-columns:repeat(7,1fr);width:100%;background-color:#f4f4f4}.week-day{display:flex;align-items:center;justify-content:center;padding:4px;background-color:#fff;font-size:14px;color:#00000080}.days-grid{flex:1 1 0;display:grid;grid-template-columns:repeat(7,1fr);gap:1px;grid-auto-rows:1fr;width:100%;padding:1px;background-color:#f4f4f4;min-height:0;height:100%}.day-cell{display:flex;flex-direction:column;gap:4px;padding:4px;background-color:#fff;overflow:hidden}.day-cell .day-number{display:flex;align-items:center;justify-content:center;width:fit-content;aspect-ratio:1;padding:2px;border-radius:50%;font-size:12px;line-height:16px;font-weight:600;-webkit-user-select:none;user-select:none}.day-cell.outside-month{background-color:#f8f8f8}.day-cell.is-today .day-number{background-color:#007bff;color:#fff}.day-cell .events-list{flex:1 1 auto;display:flex;flex-direction:column;gap:2px;overflow:hidden;min-height:0;max-height:100%}.day-cell .events-list .more-events{padding:2px 8px;border-radius:4px;font-size:12px;color:#555;cursor:pointer}.day-cell .events-list .more-events:hover{background-color:#eee}.footer{flex-shrink:0;background-color:#add8e6}\n"] }]
|
|
277
323
|
}], ctorParameters: function () { return []; }, propDecorators: { currentMonth: [{
|
|
278
324
|
type: Input
|
|
279
325
|
}], events: [{
|
|
280
326
|
type: Input
|
|
281
327
|
}], startAt: [{
|
|
282
328
|
type: Input
|
|
283
|
-
}], monthChange: [{
|
|
284
|
-
type: Output
|
|
285
329
|
}], calendarRef: [{
|
|
286
330
|
type: ViewChild,
|
|
287
331
|
args: ['calendar']
|
|
@@ -290,20 +334,423 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
290
334
|
args: ['calendarBody']
|
|
291
335
|
}] } });
|
|
292
336
|
|
|
337
|
+
class TranslateMonthPipe {
|
|
338
|
+
constructor(translationService) {
|
|
339
|
+
this.translationService = translationService;
|
|
340
|
+
}
|
|
341
|
+
transform(value) {
|
|
342
|
+
const monthTag = MONTHS[value];
|
|
343
|
+
return this.translationService.translate(monthTag);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
TranslateMonthPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TranslateMonthPipe, deps: [{ token: TranslationService }], target: i0.ɵɵFactoryTarget.Pipe });
|
|
347
|
+
TranslateMonthPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: TranslateMonthPipe, name: "translateMonth" });
|
|
348
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: TranslateMonthPipe, decorators: [{
|
|
349
|
+
type: Pipe,
|
|
350
|
+
args: [{
|
|
351
|
+
name: 'translateMonth'
|
|
352
|
+
}]
|
|
353
|
+
}], ctorParameters: function () { return [{ type: TranslationService }]; } });
|
|
354
|
+
|
|
355
|
+
class MonthSelectorComponent {
|
|
356
|
+
constructor() {
|
|
357
|
+
this.monthSelected = new EventEmitter();
|
|
358
|
+
this.mode = 'decade';
|
|
359
|
+
this.currentYear = new Date().getFullYear();
|
|
360
|
+
this.currentMonth = new Date().getMonth() + 1;
|
|
361
|
+
this.selectedMonth = { year: new Date().getFullYear(), month: new Date().getMonth() + 1 };
|
|
362
|
+
this.selectedYear = new Date().getFullYear();
|
|
363
|
+
this.currentDecadeStart = Math.floor(this.selectedYear / 10) * 10;
|
|
364
|
+
this.years = [];
|
|
365
|
+
this.months = Object.keys(MONTHS).map(key => Number(key));
|
|
366
|
+
}
|
|
367
|
+
ngOnInit() {
|
|
368
|
+
setTimeout(() => {
|
|
369
|
+
this.selectedYear = this.selectedMonth.year;
|
|
370
|
+
this.selectDecadeByYear(this.selectedYear);
|
|
371
|
+
this.setYears();
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
toggleMode(event) {
|
|
375
|
+
event.stopPropagation();
|
|
376
|
+
this.mode = this.mode === 'year' ? 'decade' : 'year';
|
|
377
|
+
}
|
|
378
|
+
setYears() {
|
|
379
|
+
this.years = [];
|
|
380
|
+
for (let i = this.currentDecadeStart; i < this.currentDecadeStart + 10; i++) {
|
|
381
|
+
this.years.push(i);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
;
|
|
385
|
+
next(event) {
|
|
386
|
+
event.stopPropagation();
|
|
387
|
+
if (this.mode === 'year') {
|
|
388
|
+
this.selectedYear++;
|
|
389
|
+
}
|
|
390
|
+
else {
|
|
391
|
+
this.currentDecadeStart += 10;
|
|
392
|
+
this.setYears();
|
|
393
|
+
this.selectedYear = this.currentDecadeStart;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
previous(event) {
|
|
397
|
+
event.stopPropagation();
|
|
398
|
+
if (this.mode === 'year') {
|
|
399
|
+
this.selectedYear--;
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
this.currentDecadeStart -= 10;
|
|
403
|
+
this.setYears();
|
|
404
|
+
this.selectedYear = this.currentDecadeStart;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
selectYear(event, year) {
|
|
408
|
+
event.stopPropagation();
|
|
409
|
+
this.selectedYear = year;
|
|
410
|
+
this.mode = 'year';
|
|
411
|
+
}
|
|
412
|
+
selectDecadeByYear(year) {
|
|
413
|
+
this.currentDecadeStart = Math.floor(year / 10) * 10;
|
|
414
|
+
this.setYears();
|
|
415
|
+
this.mode = 'decade';
|
|
416
|
+
}
|
|
417
|
+
selectMonth(month) {
|
|
418
|
+
this.monthSelected.emit({ year: this.selectedYear, month });
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
MonthSelectorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MonthSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
422
|
+
MonthSelectorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MonthSelectorComponent, selector: "lib-month-selector", inputs: { selectedMonth: "selectedMonth" }, outputs: { monthSelected: "monthSelected" }, ngImport: i0, template: "<div class=\"month-selector-component\">\n <div class=\"header\">\n <button class=\"btn-range\" *ngIf=\"mode === 'decade'\" (click)=\"toggleMode($event)\">\n <span>{{currentDecadeStart}} - {{currentDecadeStart + 9}}</span>\n\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M480-360 280-560h400L480-360Z\" />\n </svg>\n </button>\n\n <button class=\"btn-range\" *ngIf=\"mode === 'year'\" (click)=\"toggleMode($event)\">\n <span>{{selectedYear}}</span>\n\n <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"transform: rotate(180deg);\" height=\"24px\"\n viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"currentColor\">\n <path d=\"M480-360 280-560h400L480-360Z\" />\n </svg>\n </button>\n\n <div class=\"nav-controls\">\n <button class=\"btn-prev\" (click)=\"previous($event)\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M560-240 320-480l240-240 56 56-184 184 184 184-56 56Z\" />\n </svg>\n </button>\n\n <button class=\"btn-next\" (click)=\"next($event)\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div class=\"years-grid\" *ngIf=\"mode === 'decade'\">\n <button class=\"btn-year\" *ngFor=\"let year of years\"\n [ngClass]=\"{selected: year === selectedYear, current: year === currentYear }\"\n (click)=\"selectYear($event, year)\">\n {{ year }}\n </button>\n </div>\n\n <div class=\"months-grid\" *ngIf=\"mode === 'year'\">\n <button class=\"btn-month\" *ngFor=\"let month of months\"\n [ngClass]=\"{selected: month === selectedMonth.month && selectedYear === selectedMonth.year, current: currentYear === selectedYear && month === currentMonth}\"\n (click)=\"selectMonth(month)\">\n {{ month | translateMonth | slice:0:3 }}\n </button>\n </div>\n</div>", styles: [".month-selector-component{display:flex;flex-direction:column;width:280px;-webkit-user-select:none;user-select:none}.header{display:flex;align-items:center;justify-content:space-between;padding:8px 16px}.btn-range{display:flex;align-items:center;height:32px;padding:0 4px 0 12px;background:none;border:none;border-radius:50px;cursor:pointer;font-weight:600}.btn-range:hover{background-color:#0000000a}.btn-range span{white-space:nowrap}.nav-controls{display:flex;align-items:center}.btn-prev,.btn-next{display:flex;align-items:center;justify-content:center;width:32px;height:32px;background:none;border:none;border-radius:50%;cursor:pointer}.btn-prev:hover,.btn-next:hover{background-color:#0000000a}.years-grid,.months-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:0 16px 16px}.btn-month,.btn-year{display:flex;align-items:center;justify-content:center;padding:6px 12px;border:none;background:none;border-radius:50px;font-size:14px;cursor:pointer}.btn-month:hover,.btn-year:hover{background-color:#0000000a}.btn-month.selected,.btn-year.selected{border:1px solid rgba(0,0,0,.12)}.btn-month.current,.btn-year.current{background-color:#0000001f}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.SlicePipe, name: "slice" }, { kind: "pipe", type: TranslateMonthPipe, name: "translateMonth" }] });
|
|
423
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MonthSelectorComponent, decorators: [{
|
|
424
|
+
type: Component,
|
|
425
|
+
args: [{ selector: 'lib-month-selector', template: "<div class=\"month-selector-component\">\n <div class=\"header\">\n <button class=\"btn-range\" *ngIf=\"mode === 'decade'\" (click)=\"toggleMode($event)\">\n <span>{{currentDecadeStart}} - {{currentDecadeStart + 9}}</span>\n\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M480-360 280-560h400L480-360Z\" />\n </svg>\n </button>\n\n <button class=\"btn-range\" *ngIf=\"mode === 'year'\" (click)=\"toggleMode($event)\">\n <span>{{selectedYear}}</span>\n\n <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"transform: rotate(180deg);\" height=\"24px\"\n viewBox=\"0 -960 960 960\" width=\"24px\" fill=\"currentColor\">\n <path d=\"M480-360 280-560h400L480-360Z\" />\n </svg>\n </button>\n\n <div class=\"nav-controls\">\n <button class=\"btn-prev\" (click)=\"previous($event)\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M560-240 320-480l240-240 56 56-184 184 184 184-56 56Z\" />\n </svg>\n </button>\n\n <button class=\"btn-next\" (click)=\"next($event)\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div class=\"years-grid\" *ngIf=\"mode === 'decade'\">\n <button class=\"btn-year\" *ngFor=\"let year of years\"\n [ngClass]=\"{selected: year === selectedYear, current: year === currentYear }\"\n (click)=\"selectYear($event, year)\">\n {{ year }}\n </button>\n </div>\n\n <div class=\"months-grid\" *ngIf=\"mode === 'year'\">\n <button class=\"btn-month\" *ngFor=\"let month of months\"\n [ngClass]=\"{selected: month === selectedMonth.month && selectedYear === selectedMonth.year, current: currentYear === selectedYear && month === currentMonth}\"\n (click)=\"selectMonth(month)\">\n {{ month | translateMonth | slice:0:3 }}\n </button>\n </div>\n</div>", styles: [".month-selector-component{display:flex;flex-direction:column;width:280px;-webkit-user-select:none;user-select:none}.header{display:flex;align-items:center;justify-content:space-between;padding:8px 16px}.btn-range{display:flex;align-items:center;height:32px;padding:0 4px 0 12px;background:none;border:none;border-radius:50px;cursor:pointer;font-weight:600}.btn-range:hover{background-color:#0000000a}.btn-range span{white-space:nowrap}.nav-controls{display:flex;align-items:center}.btn-prev,.btn-next{display:flex;align-items:center;justify-content:center;width:32px;height:32px;background:none;border:none;border-radius:50%;cursor:pointer}.btn-prev:hover,.btn-next:hover{background-color:#0000000a}.years-grid,.months-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:0 16px 16px}.btn-month,.btn-year{display:flex;align-items:center;justify-content:center;padding:6px 12px;border:none;background:none;border-radius:50px;font-size:14px;cursor:pointer}.btn-month:hover,.btn-year:hover{background-color:#0000000a}.btn-month.selected,.btn-year.selected{border:1px solid rgba(0,0,0,.12)}.btn-month.current,.btn-year.current{background-color:#0000001f}\n"] }]
|
|
426
|
+
}], ctorParameters: function () { return []; }, propDecorators: { monthSelected: [{
|
|
427
|
+
type: Output
|
|
428
|
+
}], selectedMonth: [{
|
|
429
|
+
type: Input
|
|
430
|
+
}] } });
|
|
431
|
+
|
|
432
|
+
class DurationEventComponent {
|
|
433
|
+
constructor() {
|
|
434
|
+
this.isDarkColor = false;
|
|
435
|
+
this.topPosition = 0;
|
|
436
|
+
this.height = 0;
|
|
437
|
+
this.isEventStartInThisDay = false;
|
|
438
|
+
this.isEventEndInThisDay = false;
|
|
439
|
+
}
|
|
440
|
+
ngOnInit() {
|
|
441
|
+
this.isDarkColor = isDarkColor(this.event.color || '#000000');
|
|
442
|
+
this.isEventStartInThisDay = this.getIsEventStartInThisDay();
|
|
443
|
+
this.isEventEndInThisDay = this.getIsEventEndInThisDay();
|
|
444
|
+
this.topPosition = this.getTopPosition();
|
|
445
|
+
this.height = this.getEventHeight();
|
|
446
|
+
}
|
|
447
|
+
getIsEventStartInThisDay() {
|
|
448
|
+
return this.event.start.getDate() === this.date.getDate() && this.event.start.getMonth() === this.date.getMonth() && this.event.start.getFullYear() === this.date.getFullYear();
|
|
449
|
+
}
|
|
450
|
+
getIsEventEndInThisDay() {
|
|
451
|
+
return this.event.end.getDate() === this.date.getDate() && this.event.end.getMonth() === this.date.getMonth() && this.event.end.getFullYear() === this.date.getFullYear();
|
|
452
|
+
}
|
|
453
|
+
getTopPosition() {
|
|
454
|
+
if (!this.isEventStartInThisDay)
|
|
455
|
+
return 0;
|
|
456
|
+
return this.event.start.getHours() * 60 + this.event.start.getMinutes();
|
|
457
|
+
}
|
|
458
|
+
getEventHeight() {
|
|
459
|
+
const max_minutes_in_day = 24 * 60;
|
|
460
|
+
if (!this.isEventStartInThisDay && !this.isEventEndInThisDay)
|
|
461
|
+
return max_minutes_in_day;
|
|
462
|
+
const result = (this.event.end.getTime() - this.event.start.getTime()) / (1000 * 60);
|
|
463
|
+
if (result < 20)
|
|
464
|
+
return 20;
|
|
465
|
+
if (!this.isEventStartInThisDay)
|
|
466
|
+
return (this.event.end.getTime() - new Date(this.date.getFullYear(), this.date.getMonth(), this.date.getDate(), 0, 0, 0).getTime()) / (1000 * 60);
|
|
467
|
+
const startPosition = this.getTopPosition();
|
|
468
|
+
if (startPosition + result > max_minutes_in_day)
|
|
469
|
+
return max_minutes_in_day - startPosition;
|
|
470
|
+
return result;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
DurationEventComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DurationEventComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
474
|
+
DurationEventComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DurationEventComponent, selector: "lib-duration-event", inputs: { event: "event", date: "date" }, ngImport: i0, template: "<div class=\"duration-event-component\" style=\"--color: {{ event.color }};\" [style.top.px]=\"topPosition\"\n [style.height.px]=\"height\" [ngClass]=\"{'dark-color': isDarkColor}\" [title]=\"event.title\">\n <div class=\"event-title\">{{ event.title }}</div>\n</div>", styles: [".duration-event-component{position:absolute;left:0;z-index:1;width:100%;background-color:var(--color, rgba(0, 0, 0, .05));border-radius:4px;padding:2px 8px;cursor:pointer;-webkit-user-select:none;user-select:none;color:#212121}.duration-event-component.dark-color{color:#fafafa}.event-title{font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
475
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DurationEventComponent, decorators: [{
|
|
476
|
+
type: Component,
|
|
477
|
+
args: [{ selector: 'lib-duration-event', template: "<div class=\"duration-event-component\" style=\"--color: {{ event.color }};\" [style.top.px]=\"topPosition\"\n [style.height.px]=\"height\" [ngClass]=\"{'dark-color': isDarkColor}\" [title]=\"event.title\">\n <div class=\"event-title\">{{ event.title }}</div>\n</div>", styles: [".duration-event-component{position:absolute;left:0;z-index:1;width:100%;background-color:var(--color, rgba(0, 0, 0, .05));border-radius:4px;padding:2px 8px;cursor:pointer;-webkit-user-select:none;user-select:none;color:#212121}.duration-event-component.dark-color{color:#fafafa}.event-title{font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"] }]
|
|
478
|
+
}], ctorParameters: function () { return []; }, propDecorators: { event: [{
|
|
479
|
+
type: Input
|
|
480
|
+
}], date: [{
|
|
481
|
+
type: Input
|
|
482
|
+
}] } });
|
|
483
|
+
|
|
484
|
+
class DayComponent {
|
|
485
|
+
constructor() {
|
|
486
|
+
this.events = [];
|
|
487
|
+
this.hourBlocks = Array.from({ length: 24 }, (_, i) => i);
|
|
488
|
+
this.allDayEvents = [];
|
|
489
|
+
this.allDayHeight = 60;
|
|
490
|
+
this.eventCols = [];
|
|
491
|
+
this.resizing = false;
|
|
492
|
+
this.startY = 0;
|
|
493
|
+
this.startHeight = 0;
|
|
494
|
+
this.onResizeMouseMove = (event) => {
|
|
495
|
+
if (!this.resizing)
|
|
496
|
+
return;
|
|
497
|
+
const delta = event.clientY - this.startY;
|
|
498
|
+
const newHeight = this.startHeight + delta;
|
|
499
|
+
this.allDayHeight = Math.max(60, newHeight); // mínimo 80px
|
|
500
|
+
};
|
|
501
|
+
this.onResizeMouseUp = () => {
|
|
502
|
+
this.resizing = false;
|
|
503
|
+
document.removeEventListener('mousemove', this.onResizeMouseMove);
|
|
504
|
+
document.removeEventListener('mouseup', this.onResizeMouseUp);
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
ngOnInit() {
|
|
508
|
+
this.initEventCols();
|
|
509
|
+
}
|
|
510
|
+
findAvalailableColumn(event) {
|
|
511
|
+
for (let colIndex = 0; colIndex < this.eventCols.length; colIndex++) {
|
|
512
|
+
const col = this.eventCols[colIndex];
|
|
513
|
+
// conflict if event overlaps with any existing event in the column
|
|
514
|
+
const hasConflict = col.events.some(existingEvent => {
|
|
515
|
+
const startsDuringExisting = event.start < existingEvent.end && event.start >= existingEvent.start;
|
|
516
|
+
const endsDuringExisting = event.end > existingEvent.start && event.end <= existingEvent.end;
|
|
517
|
+
const spansExisting = event.start <= existingEvent.start && event.end >= existingEvent.end;
|
|
518
|
+
return startsDuringExisting || endsDuringExisting || spansExisting;
|
|
519
|
+
});
|
|
520
|
+
if (!hasConflict) {
|
|
521
|
+
return colIndex;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return this.eventCols.length;
|
|
525
|
+
}
|
|
526
|
+
addEventToEventCols(event) {
|
|
527
|
+
const colIndex = this.findAvalailableColumn(event);
|
|
528
|
+
if (colIndex === this.eventCols.length) {
|
|
529
|
+
this.eventCols.push({ events: [event] });
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
this.eventCols[colIndex].events.push(event);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
addEvent(event) {
|
|
536
|
+
if (event.allDay)
|
|
537
|
+
this.allDayEvents.push(event);
|
|
538
|
+
else
|
|
539
|
+
this.addEventToEventCols(event);
|
|
540
|
+
}
|
|
541
|
+
initEventCols() {
|
|
542
|
+
this.eventCols = [];
|
|
543
|
+
this.allDayEvents = [];
|
|
544
|
+
this.events.forEach(event => this.addEvent(event));
|
|
545
|
+
}
|
|
546
|
+
ngOnChanges(changes) {
|
|
547
|
+
if (changes['events']) {
|
|
548
|
+
this.initEventCols();
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
onResizeMouseDown(event) {
|
|
552
|
+
this.resizing = true;
|
|
553
|
+
this.startY = event.clientY;
|
|
554
|
+
this.startHeight = this.allDayHeight;
|
|
555
|
+
document.addEventListener('mousemove', this.onResizeMouseMove);
|
|
556
|
+
document.addEventListener('mouseup', this.onResizeMouseUp);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
DayComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
560
|
+
DayComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: DayComponent, selector: "lib-day", inputs: { events: "events", date: "date" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"day-view-component\">\n <section class=\"all-day-events\" [style.height.px]=\"allDayHeight\">\n <div class=\"header\">\n {{'allDayEvents' | translate}}\n </div>\n\n <div class=\"events-container\">\n <lib-calendar-event *ngFor=\"let event of allDayEvents\" [event]=\"event\"></lib-calendar-event>\n </div>\n </section>\n\n <div class=\"resize-divider\" (mousedown)=\"onResizeMouseDown($event)\"></div>\n\n <section class=\"duration-events\">\n <div class=\"hour-blocks\">\n <div class=\"hour-block\" *ngFor=\"let hour of hourBlocks\">\n <span>{{ hour }}:00</span>\n </div>\n </div>\n\n <div class=\"events-wrapper\">\n <div class=\"time-blocks\">\n <div class=\"time-block\" *ngFor=\"let hour of hourBlocks\">\n <div class=\"time-block-middle\"></div>\n </div>\n </div>\n\n <div class=\"events-container\" [style.gridTemplateColumns]=\"'repeat(' + eventCols.length + ', 1fr)'\">\n <div class=\"event-column\" *ngFor=\"let col of eventCols\">\n\n <lib-duration-event *ngFor=\"let event of col.events\" [event]=\"event\"\n [date]=\"date\"></lib-duration-event>\n\n </div>\n </div>\n </div>\n </section>\n</div>", styles: ["*{box-sizing:border-box;margin:0;padding:0}.day-view-component{display:flex;flex-direction:column;width:100%;height:100%;max-height:100%;overflow:hidden}section.all-day-events{position:relative;flex-shrink:0;display:flex;flex-direction:column;width:100%;min-height:60px;border-top:1px solid rgba(0,0,0,.12);overflow:auto}section.all-day-events .header{position:sticky;top:0;left:0;z-index:2;width:100%;flex-shrink:0;padding:2px 8px;background-color:#fff;font-size:12px;color:#000000b3;-webkit-user-select:none;user-select:none}section.all-day-events .events-container{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:4px;padding:4px}section.duration-events{flex-grow:1;display:flex;width:100%;overflow:auto}section.duration-events .hour-blocks{display:flex;flex-direction:column;width:45px;-webkit-user-select:none;user-select:none}section.duration-events .hour-blocks .hour-block{flex-shrink:0;height:60px;padding:4px;border:1px solid rgba(0,0,0,.12);border-top:none;font-size:12px;color:#00000080}section.duration-events .events-wrapper{position:relative;flex-grow:1;width:100%}section.duration-events .events-wrapper .time-blocks{position:absolute;top:0;left:0;width:100%;height:100%;z-index:0;display:flex;flex-direction:column}section.duration-events .events-wrapper .time-blocks .time-block{flex-shrink:0;height:60px;padding:4px;border-bottom:1px solid rgba(0,0,0,.12);border-top:none;font-size:12px;color:#00000080}section.duration-events .events-wrapper .time-blocks .time-block .time-block-middle{width:100%;height:50%;border-bottom:1px dashed rgba(0,0,0,.12)}section.duration-events .events-wrapper .events-container{display:grid;column-gap:1px}section.duration-events .events-wrapper .events-container .event-column{position:relative}.resize-divider{flex-shrink:0;width:100%;height:4px;background-color:#0000001f;cursor:row-resize;transition:transform .2s ease}.resize-divider:hover{z-index:5;background:repeating-linear-gradient(45deg,rgba(0,0,0,.12),rgba(0,0,0,.12) 4px,#ffffff 4px,#ffffff 8px);background-color:#fff;background-size:22px 8px;animation:stripe-move 1s linear infinite;transform:scaleY(2)}@keyframes stripe-move{0%{background-position:0 0}to{background-position:22px 0}}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: CalendarEventComponent, selector: "lib-calendar-event", inputs: ["event"] }, { kind: "component", type: DurationEventComponent, selector: "lib-duration-event", inputs: ["event", "date"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
|
|
561
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: DayComponent, decorators: [{
|
|
562
|
+
type: Component,
|
|
563
|
+
args: [{ selector: 'lib-day', template: "<div class=\"day-view-component\">\n <section class=\"all-day-events\" [style.height.px]=\"allDayHeight\">\n <div class=\"header\">\n {{'allDayEvents' | translate}}\n </div>\n\n <div class=\"events-container\">\n <lib-calendar-event *ngFor=\"let event of allDayEvents\" [event]=\"event\"></lib-calendar-event>\n </div>\n </section>\n\n <div class=\"resize-divider\" (mousedown)=\"onResizeMouseDown($event)\"></div>\n\n <section class=\"duration-events\">\n <div class=\"hour-blocks\">\n <div class=\"hour-block\" *ngFor=\"let hour of hourBlocks\">\n <span>{{ hour }}:00</span>\n </div>\n </div>\n\n <div class=\"events-wrapper\">\n <div class=\"time-blocks\">\n <div class=\"time-block\" *ngFor=\"let hour of hourBlocks\">\n <div class=\"time-block-middle\"></div>\n </div>\n </div>\n\n <div class=\"events-container\" [style.gridTemplateColumns]=\"'repeat(' + eventCols.length + ', 1fr)'\">\n <div class=\"event-column\" *ngFor=\"let col of eventCols\">\n\n <lib-duration-event *ngFor=\"let event of col.events\" [event]=\"event\"\n [date]=\"date\"></lib-duration-event>\n\n </div>\n </div>\n </div>\n </section>\n</div>", styles: ["*{box-sizing:border-box;margin:0;padding:0}.day-view-component{display:flex;flex-direction:column;width:100%;height:100%;max-height:100%;overflow:hidden}section.all-day-events{position:relative;flex-shrink:0;display:flex;flex-direction:column;width:100%;min-height:60px;border-top:1px solid rgba(0,0,0,.12);overflow:auto}section.all-day-events .header{position:sticky;top:0;left:0;z-index:2;width:100%;flex-shrink:0;padding:2px 8px;background-color:#fff;font-size:12px;color:#000000b3;-webkit-user-select:none;user-select:none}section.all-day-events .events-container{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:4px;padding:4px}section.duration-events{flex-grow:1;display:flex;width:100%;overflow:auto}section.duration-events .hour-blocks{display:flex;flex-direction:column;width:45px;-webkit-user-select:none;user-select:none}section.duration-events .hour-blocks .hour-block{flex-shrink:0;height:60px;padding:4px;border:1px solid rgba(0,0,0,.12);border-top:none;font-size:12px;color:#00000080}section.duration-events .events-wrapper{position:relative;flex-grow:1;width:100%}section.duration-events .events-wrapper .time-blocks{position:absolute;top:0;left:0;width:100%;height:100%;z-index:0;display:flex;flex-direction:column}section.duration-events .events-wrapper .time-blocks .time-block{flex-shrink:0;height:60px;padding:4px;border-bottom:1px solid rgba(0,0,0,.12);border-top:none;font-size:12px;color:#00000080}section.duration-events .events-wrapper .time-blocks .time-block .time-block-middle{width:100%;height:50%;border-bottom:1px dashed rgba(0,0,0,.12)}section.duration-events .events-wrapper .events-container{display:grid;column-gap:1px}section.duration-events .events-wrapper .events-container .event-column{position:relative}.resize-divider{flex-shrink:0;width:100%;height:4px;background-color:#0000001f;cursor:row-resize;transition:transform .2s ease}.resize-divider:hover{z-index:5;background:repeating-linear-gradient(45deg,rgba(0,0,0,.12),rgba(0,0,0,.12) 4px,#ffffff 4px,#ffffff 8px);background-color:#fff;background-size:22px 8px;animation:stripe-move 1s linear infinite;transform:scaleY(2)}@keyframes stripe-move{0%{background-position:0 0}to{background-position:22px 0}}\n"] }]
|
|
564
|
+
}], ctorParameters: function () { return []; }, propDecorators: { events: [{
|
|
565
|
+
type: Input
|
|
566
|
+
}], date: [{
|
|
567
|
+
type: Input
|
|
568
|
+
}] } });
|
|
569
|
+
|
|
293
570
|
class SmartCalendarComponent {
|
|
294
571
|
constructor() {
|
|
572
|
+
this.mode = 'month';
|
|
573
|
+
this.currentMonth = {
|
|
574
|
+
year: new Date().getFullYear(),
|
|
575
|
+
month: new Date().getMonth() + 1
|
|
576
|
+
};
|
|
295
577
|
this.events = [];
|
|
578
|
+
this.monthChange = new EventEmitter();
|
|
579
|
+
this.dateChanged = new EventEmitter();
|
|
580
|
+
this.showDateSelector = false;
|
|
581
|
+
this.selectedDate = new Date();
|
|
582
|
+
this.selectedDateEvents = [];
|
|
583
|
+
}
|
|
584
|
+
onDocumentClick(event) {
|
|
585
|
+
var _a;
|
|
586
|
+
if (!this.showDateSelector)
|
|
587
|
+
return;
|
|
588
|
+
const dropdown = (_a = this.dateSelectorDropdown) === null || _a === void 0 ? void 0 : _a.nativeElement;
|
|
589
|
+
const button = document.querySelector('.btn-date-selector');
|
|
590
|
+
if (dropdown && !dropdown.contains(event.target) && button && !button.contains(event.target)) {
|
|
591
|
+
this.showDateSelector = false;
|
|
592
|
+
}
|
|
296
593
|
}
|
|
297
594
|
ngOnInit() {
|
|
595
|
+
this.selectDate(new Date());
|
|
596
|
+
}
|
|
597
|
+
toggleDateSelector() {
|
|
598
|
+
this.showDateSelector = !this.showDateSelector;
|
|
599
|
+
}
|
|
600
|
+
onMonthSelected(newMonth) {
|
|
601
|
+
const oldMonth = Object.assign({}, this.currentMonth);
|
|
602
|
+
this.currentMonth = newMonth;
|
|
603
|
+
this.selectDate(new Date(this.currentMonth.year, this.currentMonth.month - 1, 1));
|
|
604
|
+
this.monthChange.emit({
|
|
605
|
+
newMonth: this.currentMonth,
|
|
606
|
+
oldMonth
|
|
607
|
+
});
|
|
608
|
+
this.showDateSelector = false;
|
|
609
|
+
}
|
|
610
|
+
nextMonth() {
|
|
611
|
+
const oldMonth = Object.assign({}, this.currentMonth);
|
|
612
|
+
if (this.currentMonth.month === 12) {
|
|
613
|
+
this.currentMonth = {
|
|
614
|
+
year: this.currentMonth.year + 1,
|
|
615
|
+
month: 1
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
else {
|
|
619
|
+
this.currentMonth = {
|
|
620
|
+
year: this.currentMonth.year,
|
|
621
|
+
month: this.currentMonth.month + 1
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
this.selectDate(new Date(this.currentMonth.year, this.currentMonth.month - 1, 1));
|
|
625
|
+
this.monthChange.emit({
|
|
626
|
+
newMonth: this.currentMonth,
|
|
627
|
+
oldMonth
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
prevMonth() {
|
|
631
|
+
const oldMonth = Object.assign({}, this.currentMonth);
|
|
632
|
+
if (this.currentMonth.month === 1) {
|
|
633
|
+
this.currentMonth = {
|
|
634
|
+
year: this.currentMonth.year - 1,
|
|
635
|
+
month: 12
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
else {
|
|
639
|
+
this.currentMonth = {
|
|
640
|
+
year: this.currentMonth.year,
|
|
641
|
+
month: this.currentMonth.month - 1
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
this.selectDate(new Date(this.currentMonth.year, this.currentMonth.month - 1, 1));
|
|
645
|
+
this.monthChange.emit({
|
|
646
|
+
newMonth: this.currentMonth,
|
|
647
|
+
oldMonth
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
goToToday() {
|
|
651
|
+
const today = new Date();
|
|
652
|
+
const oldMonth = Object.assign({}, this.currentMonth);
|
|
653
|
+
this.currentMonth = {
|
|
654
|
+
year: today.getFullYear(),
|
|
655
|
+
month: today.getMonth() + 1
|
|
656
|
+
};
|
|
657
|
+
this.selectDate(today);
|
|
658
|
+
if (this.currentMonth.month !== oldMonth.month || this.currentMonth.year !== oldMonth.year)
|
|
659
|
+
this.monthChange.emit({
|
|
660
|
+
newMonth: this.currentMonth,
|
|
661
|
+
oldMonth
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
nextDay() {
|
|
665
|
+
const oldMonth = Object.assign({}, this.currentMonth);
|
|
666
|
+
const newDate = new Date(this.selectedDate);
|
|
667
|
+
newDate.setDate(newDate.getDate() + 1);
|
|
668
|
+
this.selectDate(newDate);
|
|
669
|
+
this.currentMonth = {
|
|
670
|
+
year: newDate.getFullYear(),
|
|
671
|
+
month: newDate.getMonth() + 1
|
|
672
|
+
};
|
|
673
|
+
if (this.currentMonth.month !== oldMonth.month || this.currentMonth.year !== oldMonth.year)
|
|
674
|
+
this.monthChange.emit({
|
|
675
|
+
newMonth: this.currentMonth,
|
|
676
|
+
oldMonth
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
prevDay() {
|
|
680
|
+
const oldMonth = Object.assign({}, this.currentMonth);
|
|
681
|
+
const newDate = new Date(this.selectedDate);
|
|
682
|
+
newDate.setDate(newDate.getDate() - 1);
|
|
683
|
+
this.selectDate(newDate);
|
|
684
|
+
this.currentMonth = {
|
|
685
|
+
year: newDate.getFullYear(),
|
|
686
|
+
month: newDate.getMonth() + 1
|
|
687
|
+
};
|
|
688
|
+
if (this.currentMonth.month !== oldMonth.month || this.currentMonth.year !== oldMonth.year)
|
|
689
|
+
this.monthChange.emit({
|
|
690
|
+
newMonth: this.currentMonth,
|
|
691
|
+
oldMonth
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
onNext() {
|
|
695
|
+
if (this.mode === 'month')
|
|
696
|
+
this.nextMonth();
|
|
697
|
+
else if (this.mode === 'day')
|
|
698
|
+
this.nextDay();
|
|
699
|
+
}
|
|
700
|
+
onPrev() {
|
|
701
|
+
if (this.mode === 'month')
|
|
702
|
+
this.prevMonth();
|
|
703
|
+
else if (this.mode === 'day')
|
|
704
|
+
this.prevDay();
|
|
705
|
+
}
|
|
706
|
+
selectDate(date) {
|
|
707
|
+
this.selectedDate = date;
|
|
708
|
+
this.selectedDateEvents = this.events.filter(event => {
|
|
709
|
+
const eventDate = new Date(event.start);
|
|
710
|
+
// return events that starts, ends or spans the selected date
|
|
711
|
+
return (eventDate.getDate() === date.getDate() &&
|
|
712
|
+
eventDate.getMonth() === date.getMonth() &&
|
|
713
|
+
eventDate.getFullYear() === date.getFullYear()) ||
|
|
714
|
+
(event.end &&
|
|
715
|
+
event.end.getDate() === date.getDate() &&
|
|
716
|
+
event.end.getMonth() === date.getMonth() &&
|
|
717
|
+
event.end.getFullYear() === date.getFullYear()) ||
|
|
718
|
+
(event.start < date && event.end && event.end > date);
|
|
719
|
+
});
|
|
720
|
+
const oldMonth = this.currentMonth;
|
|
721
|
+
this.currentMonth = {
|
|
722
|
+
year: date.getFullYear(),
|
|
723
|
+
month: date.getMonth() + 1
|
|
724
|
+
};
|
|
725
|
+
if (this.currentMonth.month !== oldMonth.month || this.currentMonth.year !== oldMonth.year)
|
|
726
|
+
this.monthChange.emit({
|
|
727
|
+
newMonth: this.currentMonth,
|
|
728
|
+
oldMonth
|
|
729
|
+
});
|
|
730
|
+
this.dateChanged.emit(this.selectedDate);
|
|
298
731
|
}
|
|
299
732
|
}
|
|
300
733
|
SmartCalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SmartCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
301
|
-
SmartCalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: SmartCalendarComponent, selector: "smart-calendar", inputs: { events: "events" }, ngImport: i0, template: "<div class=\"smart-calendar-component\">\n <lib-calendar [events]=\"events\"></lib-calendar>\n</div>", styles: [".smart-calendar-component{width:100%;height:100%;background-color:#fff;border:1px solid #
|
|
734
|
+
SmartCalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: SmartCalendarComponent, selector: "smart-calendar", inputs: { mode: "mode", currentMonth: "currentMonth", events: "events" }, outputs: { monthChange: "monthChange", dateChanged: "dateChanged" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, viewQueries: [{ propertyName: "dateSelectorDropdown", first: true, predicate: ["dateSelectorDropdown"], descendants: true }], ngImport: i0, template: "<div class=\"smart-calendar-component\">\n <div class=\"header\">\n <div class=\"nav-controls\">\n <button class=\"btn-prev\" (click)=\"onPrev()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M560-240 320-480l240-240 56 56-184 184 184 184-56 56Z\" />\n </svg>\n </button>\n\n <button class=\"btn-today\" (click)=\"goToToday()\">{{'today' | translate}}</button>\n\n <button class=\"btn-next\" (click)=\"onNext()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z\" />\n </svg>\n </button>\n </div>\n\n <div class=\"spacer\"></div>\n\n <div class=\"date-selector-container\">\n <button class=\"btn-date-selector\" (click)=\"toggleDateSelector()\">\n <span *ngIf=\"mode === 'month'\">{{ currentMonth.month | translateMonth}} - {{ currentMonth.year }}</span>\n <span *ngIf=\"mode === 'day'\">{{ selectedDate.toDateString() }}</span>\n\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M480-360 280-560h400L480-360Z\" />\n </svg>\n </button>\n\n <div class=\"date-selector-dropdown\" *ngIf=\"showDateSelector\" #dateSelectorDropdown>\n <lib-month-selector [selectedMonth]=\"currentMonth\"\n (monthSelected)=\"onMonthSelected($event)\"></lib-month-selector>\n </div>\n </div>\n\n <div class=\"spacer\"></div>\n\n <div class=\"view-selector\">\n <button class=\"btn-view\" [ngClass]=\"{active: mode === 'month'}\" (click)=\"mode = 'month'\">\n <!-- month view -->\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path\n d=\"M200-80q-33 0-56.5-23.5T120-160v-560q0-33 23.5-56.5T200-800h40v-80h80v80h320v-80h80v80h40q33 0 56.5 23.5T840-720v560q0 33-23.5 56.5T760-80H200Zm0-80h560v-400H200v400Zm0-480h560v-80H200v80Zm0 0v-80 80Zm280 240q-17 0-28.5-11.5T440-440q0-17 11.5-28.5T480-480q17 0 28.5 11.5T520-440q0 17-11.5 28.5T480-400Zm-160 0q-17 0-28.5-11.5T280-440q0-17 11.5-28.5T320-480q17 0 28.5 11.5T360-440q0 17-11.5 28.5T320-400Zm320 0q-17 0-28.5-11.5T600-440q0-17 11.5-28.5T640-480q17 0 28.5 11.5T680-440q0 17-11.5 28.5T640-400ZM480-240q-17 0-28.5-11.5T440-280q0-17 11.5-28.5T480-320q17 0 28.5 11.5T520-280q0 17-11.5 28.5T480-240Zm-160 0q-17 0-28.5-11.5T280-280q0-17 11.5-28.5T320-320q17 0 28.5 11.5T360-280q0 17-11.5 28.5T320-240Zm320 0q-17 0-28.5-11.5T600-280q0-17 11.5-28.5T640-320q17 0 28.5 11.5T680-280q0 17-11.5 28.5T640-240Z\" />\n </svg>\n </button>\n\n <button class=\"btn-view\" [ngClass]=\"{active: mode === 'week'}\" (click)=\"mode = 'week'\">\n <!-- week view -->\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path\n d=\"M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm360-80h100v-480H520v480Zm-180 0h100v-480H340v480Zm-180 0h100v-480H160v480Zm540 0h100v-480H700v480Z\" />\n </svg>\n </button>\n\n <button class=\"btn-view\" [ngClass]=\"{active: mode === 'day'}\" (click)=\"mode = 'day'\">\n <!-- day view -->\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path\n d=\"M120-160v-80h720v80H120Zm0-560v-80h720v80H120Zm80 400q-33 0-56.5-23.5T120-400v-160q0-33 23.5-56.5T200-640h560q33 0 56.5 23.5T840-560v160q0 33-23.5 56.5T760-320H200Zm0-80h560v-160H200v160Zm0-160v160-160Z\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div class=\"view-container\">\n <lib-calendar [events]=\"events\" [currentMonth]=\"currentMonth\" *ngIf=\"mode === 'month'\"></lib-calendar>\n\n <lib-day *ngIf=\"mode === 'day'\" [date]=\"selectedDate\" [events]=\"selectedDateEvents\"></lib-day>\n </div>\n\n</div>", styles: ["*{box-sizing:border-box;margin:0;padding:0}.smart-calendar-component{display:flex;flex-direction:column;width:100%;height:100%;background-color:#fff}.header{flex-shrink:0;display:flex;align-items:center;gap:16px;padding:2px 16px}.header .spacer{flex:1 1 auto}.header .nav-controls{display:flex;align-items:center}.header .nav-controls .btn-prev,.header .nav-controls .btn-next{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border:none;background:none;border-radius:50%;cursor:pointer;-webkit-user-select:none;user-select:none}.header .nav-controls .btn-prev:hover,.header .nav-controls .btn-next:hover{background-color:#eee}.header .nav-controls .btn-today{display:flex;align-items:center;height:30px;padding:0 12px;border:none;background:none;border-radius:50px;cursor:pointer;font-weight:600;-webkit-user-select:none;user-select:none}.header .nav-controls .btn-today:hover{background-color:#eee}.header .view-selector{display:flex;align-items:center}.header .view-selector .btn-view{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border:1px solid #cccccc;background:none;cursor:pointer;-webkit-user-select:none;user-select:none}.header .view-selector .btn-view:first-child{border-top-left-radius:4px;border-bottom-left-radius:4px;border-right:none}.header .view-selector .btn-view:last-child{border-top-right-radius:4px;border-bottom-right-radius:4px;border-left:none}.header .view-selector .btn-view:hover{background-color:#eee}.header .view-selector .btn-view svg{width:22px;height:22px}.header .view-selector .btn-view.active{background-color:#0000001a}.header .date-selector-container{position:relative}.header .date-selector-container .date-selector-dropdown{position:absolute;top:100%;left:50%;transform:translate(-50%);background-color:#fff;border-radius:4px;box-shadow:0 2px 24px #0000004d;z-index:3}.header .date-selector-container .date-selector-dropdown:before{content:\"\";position:absolute;top:-6px;left:50%;transform:translate(-50%) rotate(45deg);width:12px;height:12px;background-color:#fff;border-radius:2px}.header .btn-date-selector{display:flex;align-items:center;gap:8px;height:30px;padding:0 8px 0 12px;border:none;background:none;border-radius:50px;cursor:pointer;font-weight:600;-webkit-user-select:none;user-select:none}.header .btn-date-selector:hover{background-color:#eee}.view-container{flex:1 1 auto;overflow:hidden}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CalendarComponent, selector: "lib-calendar", inputs: ["currentMonth", "events", "startAt"] }, { kind: "component", type: MonthSelectorComponent, selector: "lib-month-selector", inputs: ["selectedMonth"], outputs: ["monthSelected"] }, { kind: "component", type: DayComponent, selector: "lib-day", inputs: ["events", "date"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: TranslateMonthPipe, name: "translateMonth" }] });
|
|
302
735
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SmartCalendarComponent, decorators: [{
|
|
303
736
|
type: Component,
|
|
304
|
-
args: [{ selector: 'smart-calendar', template: "<div class=\"smart-calendar-component\">\n <lib-calendar [events]=\"events\"></lib-calendar>\n</div>", styles: [".smart-calendar-component{width:100%;height:100%;background-color:#fff;border:1px solid #
|
|
305
|
-
}], ctorParameters: function () { return []; }, propDecorators: {
|
|
737
|
+
args: [{ selector: 'smart-calendar', template: "<div class=\"smart-calendar-component\">\n <div class=\"header\">\n <div class=\"nav-controls\">\n <button class=\"btn-prev\" (click)=\"onPrev()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M560-240 320-480l240-240 56 56-184 184 184 184-56 56Z\" />\n </svg>\n </button>\n\n <button class=\"btn-today\" (click)=\"goToToday()\">{{'today' | translate}}</button>\n\n <button class=\"btn-next\" (click)=\"onNext()\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z\" />\n </svg>\n </button>\n </div>\n\n <div class=\"spacer\"></div>\n\n <div class=\"date-selector-container\">\n <button class=\"btn-date-selector\" (click)=\"toggleDateSelector()\">\n <span *ngIf=\"mode === 'month'\">{{ currentMonth.month | translateMonth}} - {{ currentMonth.year }}</span>\n <span *ngIf=\"mode === 'day'\">{{ selectedDate.toDateString() }}</span>\n\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path d=\"M480-360 280-560h400L480-360Z\" />\n </svg>\n </button>\n\n <div class=\"date-selector-dropdown\" *ngIf=\"showDateSelector\" #dateSelectorDropdown>\n <lib-month-selector [selectedMonth]=\"currentMonth\"\n (monthSelected)=\"onMonthSelected($event)\"></lib-month-selector>\n </div>\n </div>\n\n <div class=\"spacer\"></div>\n\n <div class=\"view-selector\">\n <button class=\"btn-view\" [ngClass]=\"{active: mode === 'month'}\" (click)=\"mode = 'month'\">\n <!-- month view -->\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path\n d=\"M200-80q-33 0-56.5-23.5T120-160v-560q0-33 23.5-56.5T200-800h40v-80h80v80h320v-80h80v80h40q33 0 56.5 23.5T840-720v560q0 33-23.5 56.5T760-80H200Zm0-80h560v-400H200v400Zm0-480h560v-80H200v80Zm0 0v-80 80Zm280 240q-17 0-28.5-11.5T440-440q0-17 11.5-28.5T480-480q17 0 28.5 11.5T520-440q0 17-11.5 28.5T480-400Zm-160 0q-17 0-28.5-11.5T280-440q0-17 11.5-28.5T320-480q17 0 28.5 11.5T360-440q0 17-11.5 28.5T320-400Zm320 0q-17 0-28.5-11.5T600-440q0-17 11.5-28.5T640-480q17 0 28.5 11.5T680-440q0 17-11.5 28.5T640-400ZM480-240q-17 0-28.5-11.5T440-280q0-17 11.5-28.5T480-320q17 0 28.5 11.5T520-280q0 17-11.5 28.5T480-240Zm-160 0q-17 0-28.5-11.5T280-280q0-17 11.5-28.5T320-320q17 0 28.5 11.5T360-280q0 17-11.5 28.5T320-240Zm320 0q-17 0-28.5-11.5T600-280q0-17 11.5-28.5T640-320q17 0 28.5 11.5T680-280q0 17-11.5 28.5T640-240Z\" />\n </svg>\n </button>\n\n <button class=\"btn-view\" [ngClass]=\"{active: mode === 'week'}\" (click)=\"mode = 'week'\">\n <!-- week view -->\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path\n d=\"M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm360-80h100v-480H520v480Zm-180 0h100v-480H340v480Zm-180 0h100v-480H160v480Zm540 0h100v-480H700v480Z\" />\n </svg>\n </button>\n\n <button class=\"btn-view\" [ngClass]=\"{active: mode === 'day'}\" (click)=\"mode = 'day'\">\n <!-- day view -->\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\" width=\"24px\"\n fill=\"currentColor\">\n <path\n d=\"M120-160v-80h720v80H120Zm0-560v-80h720v80H120Zm80 400q-33 0-56.5-23.5T120-400v-160q0-33 23.5-56.5T200-640h560q33 0 56.5 23.5T840-560v160q0 33-23.5 56.5T760-320H200Zm0-80h560v-160H200v160Zm0-160v160-160Z\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div class=\"view-container\">\n <lib-calendar [events]=\"events\" [currentMonth]=\"currentMonth\" *ngIf=\"mode === 'month'\"></lib-calendar>\n\n <lib-day *ngIf=\"mode === 'day'\" [date]=\"selectedDate\" [events]=\"selectedDateEvents\"></lib-day>\n </div>\n\n</div>", styles: ["*{box-sizing:border-box;margin:0;padding:0}.smart-calendar-component{display:flex;flex-direction:column;width:100%;height:100%;background-color:#fff}.header{flex-shrink:0;display:flex;align-items:center;gap:16px;padding:2px 16px}.header .spacer{flex:1 1 auto}.header .nav-controls{display:flex;align-items:center}.header .nav-controls .btn-prev,.header .nav-controls .btn-next{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border:none;background:none;border-radius:50%;cursor:pointer;-webkit-user-select:none;user-select:none}.header .nav-controls .btn-prev:hover,.header .nav-controls .btn-next:hover{background-color:#eee}.header .nav-controls .btn-today{display:flex;align-items:center;height:30px;padding:0 12px;border:none;background:none;border-radius:50px;cursor:pointer;font-weight:600;-webkit-user-select:none;user-select:none}.header .nav-controls .btn-today:hover{background-color:#eee}.header .view-selector{display:flex;align-items:center}.header .view-selector .btn-view{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border:1px solid #cccccc;background:none;cursor:pointer;-webkit-user-select:none;user-select:none}.header .view-selector .btn-view:first-child{border-top-left-radius:4px;border-bottom-left-radius:4px;border-right:none}.header .view-selector .btn-view:last-child{border-top-right-radius:4px;border-bottom-right-radius:4px;border-left:none}.header .view-selector .btn-view:hover{background-color:#eee}.header .view-selector .btn-view svg{width:22px;height:22px}.header .view-selector .btn-view.active{background-color:#0000001a}.header .date-selector-container{position:relative}.header .date-selector-container .date-selector-dropdown{position:absolute;top:100%;left:50%;transform:translate(-50%);background-color:#fff;border-radius:4px;box-shadow:0 2px 24px #0000004d;z-index:3}.header .date-selector-container .date-selector-dropdown:before{content:\"\";position:absolute;top:-6px;left:50%;transform:translate(-50%) rotate(45deg);width:12px;height:12px;background-color:#fff;border-radius:2px}.header .btn-date-selector{display:flex;align-items:center;gap:8px;height:30px;padding:0 8px 0 12px;border:none;background:none;border-radius:50px;cursor:pointer;font-weight:600;-webkit-user-select:none;user-select:none}.header .btn-date-selector:hover{background-color:#eee}.view-container{flex:1 1 auto;overflow:hidden}\n"] }]
|
|
738
|
+
}], ctorParameters: function () { return []; }, propDecorators: { mode: [{
|
|
739
|
+
type: Input
|
|
740
|
+
}], currentMonth: [{
|
|
741
|
+
type: Input
|
|
742
|
+
}], events: [{
|
|
306
743
|
type: Input
|
|
744
|
+
}], monthChange: [{
|
|
745
|
+
type: Output
|
|
746
|
+
}], dateChanged: [{
|
|
747
|
+
type: Output
|
|
748
|
+
}], dateSelectorDropdown: [{
|
|
749
|
+
type: ViewChild,
|
|
750
|
+
args: ['dateSelectorDropdown', { static: false }]
|
|
751
|
+
}], onDocumentClick: [{
|
|
752
|
+
type: HostListener,
|
|
753
|
+
args: ['document:click', ['$event']]
|
|
307
754
|
}] } });
|
|
308
755
|
|
|
309
756
|
class SmartAngularCalendarModule {
|
|
@@ -313,7 +760,11 @@ SmartAngularCalendarModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.
|
|
|
313
760
|
CalendarComponent,
|
|
314
761
|
TranslatePipe,
|
|
315
762
|
CalendarEventComponent,
|
|
316
|
-
MoreEventsModalComponent
|
|
763
|
+
MoreEventsModalComponent,
|
|
764
|
+
TranslateMonthPipe,
|
|
765
|
+
MonthSelectorComponent,
|
|
766
|
+
DayComponent,
|
|
767
|
+
DurationEventComponent], imports: [CommonModule], exports: [SmartCalendarComponent] });
|
|
317
768
|
SmartAngularCalendarModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SmartAngularCalendarModule, imports: [CommonModule] });
|
|
318
769
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SmartAngularCalendarModule, decorators: [{
|
|
319
770
|
type: NgModule,
|
|
@@ -323,7 +774,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
323
774
|
CalendarComponent,
|
|
324
775
|
TranslatePipe,
|
|
325
776
|
CalendarEventComponent,
|
|
326
|
-
MoreEventsModalComponent
|
|
777
|
+
MoreEventsModalComponent,
|
|
778
|
+
TranslateMonthPipe,
|
|
779
|
+
MonthSelectorComponent,
|
|
780
|
+
DayComponent,
|
|
781
|
+
DurationEventComponent
|
|
327
782
|
],
|
|
328
783
|
imports: [
|
|
329
784
|
CommonModule
|