@idea-ionic/agenda 7.3.0 → 8.0.2
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/README.md +2 -10
- package/esm2022/src/agenda.component.mjs +20 -60
- package/esm2022/src/agenda.module.mjs +4 -4
- package/esm2022/src/calendar.component.mjs +78 -95
- package/esm2022/src/calendarCreation.component.mjs +61 -87
- package/esm2022/src/calendarItem.component.mjs +82 -100
- package/esm2022/src/calendars.service.mjs +117 -162
- package/esm2022/src/dateFormatter.provider.mjs +3 -3
- package/fesm2022/idea-ionic-agenda.mjs +344 -494
- package/fesm2022/idea-ionic-agenda.mjs.map +1 -1
- package/package.json +24 -23
- package/src/agenda.component.d.ts +7 -46
- package/src/calendar.component.d.ts +11 -42
- package/src/calendarCreation.component.d.ts +6 -38
- package/src/calendarItem.component.d.ts +8 -19
- package/src/calendars.service.d.ts +7 -10
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, EventEmitter, Component, ChangeDetectionStrategy, Input, Output,
|
|
3
|
-
import * as
|
|
2
|
+
import { Injectable, EventEmitter, inject, ChangeDetectorRef, Component, ChangeDetectionStrategy, Input, Output, NgModule } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/common';
|
|
4
4
|
import { formatDate, CommonModule } from '@angular/common';
|
|
5
|
-
import * as
|
|
5
|
+
import * as i1$1 from '@angular/forms';
|
|
6
6
|
import { FormsModule } from '@angular/forms';
|
|
7
7
|
import * as i2 from '@ionic/angular';
|
|
8
|
-
import { IonicModule } from '@ionic/angular';
|
|
8
|
+
import { Platform, ModalController, AlertController, IonicModule } from '@ionic/angular';
|
|
9
9
|
import * as i4 from 'angular-calendar';
|
|
10
|
-
import { CalendarDateFormatter, CalendarView,
|
|
10
|
+
import { CalendarDateFormatter, CalendarView, CalendarModule, DateAdapter } from 'angular-calendar';
|
|
11
11
|
import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
|
|
12
12
|
import * as i3 from '@idea-ionic/common';
|
|
13
|
-
import { IDEAEnvironment, IDEASuggestionsComponent, IDEATranslationsModule, IDEAColorPickerModule, IDEACheckerModule, IDEAUserAvatarModule } from '@idea-ionic/common';
|
|
14
|
-
import { Subject,
|
|
13
|
+
import { IDEATranslationsService, IDEAEnvironment, IDEALoadingService, IDEAAWSAPIService, IDEASuggestionsComponent, IDEATinCanService, IDEAMessageService, IDEATranslationsModule, IDEAColorPickerModule, IDEACheckerModule, IDEAUserAvatarModule } from '@idea-ionic/common';
|
|
14
|
+
import { Subject, fromEvent, finalize, takeUntil } from 'rxjs';
|
|
15
15
|
import { isFuture, isToday, isSameDay, endOfWeek, addMinutes, addDays } from 'date-fns';
|
|
16
16
|
import ColorParse from 'color-parse';
|
|
17
17
|
import { ExternalCalendarSources, Calendar, Suggestion, Check, ExternalCalendarInfo } from 'idea-toolbox';
|
|
@@ -31,18 +31,15 @@ class CustomDateFormatter extends CalendarDateFormatter {
|
|
|
31
31
|
this.dayViewHour = ({ date, locale }) => locale === 'it' ? formatDate(date, 'HH:mm', locale) : formatDate(date, 'h aa', locale);
|
|
32
32
|
this.dayViewTitle = ({ date, locale }) => locale === 'it' ? formatDate(date, 'EEEE, dd MMM yyyy', locale) : formatDate(date, 'EEEE, MMM dd, yyyy', locale);
|
|
33
33
|
}
|
|
34
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
35
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
34
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: CustomDateFormatter, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
35
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: CustomDateFormatter }); }
|
|
36
36
|
}
|
|
37
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
37
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: CustomDateFormatter, decorators: [{
|
|
38
38
|
type: Injectable
|
|
39
39
|
}] });
|
|
40
40
|
|
|
41
41
|
class IDEAAgendaComponent {
|
|
42
|
-
constructor(
|
|
43
|
-
this.cdr = cdr;
|
|
44
|
-
this.platform = platform;
|
|
45
|
-
this.t = t;
|
|
42
|
+
constructor() {
|
|
46
43
|
/**
|
|
47
44
|
* The events to display in the calendar.
|
|
48
45
|
*/
|
|
@@ -120,28 +117,22 @@ class IDEAAgendaComponent {
|
|
|
120
117
|
* Trigger before the rendering of the month view.
|
|
121
118
|
*/
|
|
122
119
|
this.beforeMonthViewRenderEmitter = new EventEmitter();
|
|
123
|
-
/**
|
|
124
|
-
* Helper to use the enum in the UX.
|
|
125
|
-
*/
|
|
126
120
|
this.CalendarView = CalendarView;
|
|
127
|
-
|
|
128
|
-
* The currently selected date.
|
|
129
|
-
*/
|
|
121
|
+
this.Attendance = EventAttendance;
|
|
130
122
|
this.viewDate = new Date();
|
|
131
|
-
/**
|
|
132
|
-
* A controller to refresh the current view.
|
|
133
|
-
*/
|
|
134
123
|
this.refresh = new Subject();
|
|
135
|
-
this.Attendance = EventAttendance;
|
|
136
124
|
this.darkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
125
|
+
this._cdr = inject(ChangeDetectorRef);
|
|
126
|
+
this._platform = inject(Platform);
|
|
127
|
+
this._translate = inject(IDEATranslationsService);
|
|
137
128
|
}
|
|
138
129
|
ngOnInit() {
|
|
139
|
-
this.locale = this.
|
|
130
|
+
this.locale = this._translate.getCurrentLang();
|
|
140
131
|
// in case of Italian locale the starting day for the week is monday (1), otherwise sunday (0)
|
|
141
132
|
this.weekStartsOn = this.locale === 'it' ? 1 : 0;
|
|
142
133
|
}
|
|
143
134
|
isMobile() {
|
|
144
|
-
return this.
|
|
135
|
+
return this._platform.is('mobile');
|
|
145
136
|
}
|
|
146
137
|
/**
|
|
147
138
|
* Run some checks before the month view is rendered (e.g. disable invalid days).
|
|
@@ -173,58 +164,34 @@ class IDEAAgendaComponent {
|
|
|
173
164
|
});
|
|
174
165
|
});
|
|
175
166
|
}
|
|
176
|
-
/**
|
|
177
|
-
* Check whether a date is valid based on the configured parameters.
|
|
178
|
-
*/
|
|
179
167
|
dateIsValid(date, sameDayIsValid) {
|
|
180
168
|
if (!this.onlyFuture)
|
|
181
169
|
return true;
|
|
182
170
|
return isFuture(date) || (sameDayIsValid ? isToday(date) : false);
|
|
183
171
|
}
|
|
184
|
-
/**
|
|
185
|
-
* Change the current view for the agenda.
|
|
186
|
-
*/
|
|
187
172
|
setView(view) {
|
|
188
173
|
this.view = view;
|
|
189
174
|
}
|
|
190
|
-
/**
|
|
191
|
-
* Emit the change of the view date and close the detail component of the month view, if needed.
|
|
192
|
-
*/
|
|
193
175
|
viewDateChanged(newDate) {
|
|
194
176
|
if (this.view === CalendarView.Month)
|
|
195
177
|
this.activeDayIsOpen = false;
|
|
196
178
|
this.changeDate.emit(newDate);
|
|
197
179
|
}
|
|
198
|
-
/**
|
|
199
|
-
* A day was selected: manage the detailed view.
|
|
200
|
-
*/
|
|
201
180
|
changeDay({ date, events }) {
|
|
202
|
-
// skip if the date isn't valid
|
|
203
181
|
if (!this.dateIsValid(date, true))
|
|
204
182
|
return;
|
|
205
|
-
// if the selected day changed, if the new day has events, open the details in month view (otherwise close them)
|
|
206
183
|
if ((isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) || !events || events.length === 0)
|
|
207
184
|
this.activeDayIsOpen = false;
|
|
208
185
|
else
|
|
209
186
|
this.activeDayIsOpen = true;
|
|
210
|
-
// update the current date in the agenda
|
|
211
187
|
this.viewDate = date;
|
|
212
188
|
}
|
|
213
|
-
/**
|
|
214
|
-
* The time of an event was changed.
|
|
215
|
-
*/
|
|
216
189
|
eventTimesChanged({ event, newStart, newEnd }) {
|
|
217
|
-
// update the event
|
|
218
190
|
event.start = newStart;
|
|
219
191
|
event.end = newEnd;
|
|
220
|
-
// re-map the array to trigger the UI refresh
|
|
221
192
|
this.events = this.events.slice();
|
|
222
|
-
// trigger the event to the parent component
|
|
223
193
|
this.changeEvent.emit(event);
|
|
224
194
|
}
|
|
225
|
-
/**
|
|
226
|
-
* Given a color, it returns an opaque version of it.
|
|
227
|
-
*/
|
|
228
195
|
getAlternateColor(color, amount, opacity) {
|
|
229
196
|
if (!color?.trim())
|
|
230
197
|
return undefined;
|
|
@@ -234,9 +201,6 @@ class IDEAAgendaComponent {
|
|
|
234
201
|
const b = Math.max(Math.min(255, Number(alt.values[2]) + amount), 0);
|
|
235
202
|
return `rgba(${r}, ${g}, ${b}, ${opacity || 1})`;
|
|
236
203
|
}
|
|
237
|
-
/**
|
|
238
|
-
* Get the content of the tooltip based on the event.
|
|
239
|
-
*/
|
|
240
204
|
getTooltipContent(event) {
|
|
241
205
|
if (!event)
|
|
242
206
|
return '';
|
|
@@ -251,15 +215,9 @@ class IDEAAgendaComponent {
|
|
|
251
215
|
}
|
|
252
216
|
return str;
|
|
253
217
|
}
|
|
254
|
-
/**
|
|
255
|
-
* Get a shortened version of the description as preview.
|
|
256
|
-
*/
|
|
257
218
|
getPreviewDescription(description) {
|
|
258
219
|
return description && description.length > 100 ? description.slice(0, 100).concat('...') : description;
|
|
259
220
|
}
|
|
260
|
-
/**
|
|
261
|
-
* Handle the drag&drop to create a new event.
|
|
262
|
-
*/
|
|
263
221
|
startDragToCreate(event, segmentDate, segmentElement) {
|
|
264
222
|
if (!this.allowDragToCreate)
|
|
265
223
|
return;
|
|
@@ -291,7 +249,7 @@ class IDEAAgendaComponent {
|
|
|
291
249
|
};
|
|
292
250
|
const refreshView = () => {
|
|
293
251
|
this.events = [...this.events];
|
|
294
|
-
this.
|
|
252
|
+
this._cdr.detectChanges();
|
|
295
253
|
};
|
|
296
254
|
if (event.type === 'touchstart') {
|
|
297
255
|
fromEvent(document, 'touchmove')
|
|
@@ -311,13 +269,13 @@ class IDEAAgendaComponent {
|
|
|
311
269
|
fixedEnd.setMinutes(agendaBooking.start.getMinutes() + segmentSizeInMinutes);
|
|
312
270
|
return fixedEnd;
|
|
313
271
|
}
|
|
314
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
315
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.0", type: IDEAAgendaComponent, selector: "idea-agenda", inputs: { events: "events", excludeDays: "excludeDays", dayStartHour: "dayStartHour", dayEndHour: "dayEndHour", hourSegments: "hourSegments", activeDayIsOpen: "activeDayIsOpen", view: "view", allowedViews: "allowedViews", onlyFuture: "onlyFuture", titleNotes: "titleNotes", newEventTemplate: "newEventTemplate", allowDragToCreate: "allowDragToCreate", parentContent: "parentContent" }, outputs: { selectEvent: "selectEvent", selectDay: "selectDay", selectSlot: "selectSlot", newEventByDrag: "newEventByDrag", changeEvent: "changeEvent", changeDate: "changeDate", beforeWeekOrDayViewRenderEmitter: "beforeWeekOrDayViewRenderEmitter", beforeMonthViewRenderEmitter: "beforeMonthViewRenderEmitter" }, ngImport: i0, template: "<div class=\"agenda\">\n <!-- TOOLBAR -->\n <ion-row class=\"ion-align-items-center\">\n <ion-col\n class=\"ion-align-self-center ion-text-right\"\n [size]=\"5\"\n [sizeSm]=\"3\"\n [pushSm]=\"5\"\n [sizeLg]=\"2\"\n [pushLg]=\"8\"\n >\n <ion-item lines=\"none\" class=\"calendarViewSelector\" *ngIf=\"allowedViews.length > 1\">\n <ion-select\n interface=\"popover\"\n [value]=\"view\"\n (ionChange)=\"$event?.detail ? setView($event.detail.value) : null\"\n >\n <ion-select-option *ngFor=\"let view of allowedViews\" [value]=\"view\">\n {{ 'IDEA_AGENDA.' + view | uppercase | translate }}\n </ion-select-option>\n </ion-select>\n </ion-item>\n </ion-col>\n <ion-col\n class=\"ion-align-self-center ion-text-right\"\n [size]=\"7\"\n [sizeSm]=\"4\"\n [pushSm]=\"5\"\n [sizeLg]=\"2\"\n [pushLg]=\"8\"\n >\n <ion-button\n fill=\"clear\"\n color=\"dark\"\n size=\"small\"\n mwlCalendarPreviousView\n [view]=\"view\"\n [(viewDate)]=\"viewDate\"\n (viewDateChange)=\"viewDateChanged($event)\"\n >\n <ion-icon name=\"chevron-back-outline\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n <ion-button\n fill=\"clear\"\n color=\"dark\"\n size=\"small\"\n mwlCalendarToday\n [(viewDate)]=\"viewDate\"\n (viewDateChange)=\"viewDateChanged($event)\"\n >\n <ion-icon name=\"today-outline\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n <ion-button\n fill=\"clear\"\n color=\"dark\"\n size=\"small\"\n mwlCalendarNextView\n [view]=\"view\"\n [(viewDate)]=\"viewDate\"\n (viewDateChange)=\"viewDateChanged($event)\"\n >\n <ion-icon name=\"chevron-forward-outline\" slot=\"icon-only\"></ion-icon>\n </ion-button>\n </ion-col>\n <ion-col class=\"ion-align-self-center titleCol\" [size]=\"12\" [sizeSm]=\"5\" [pullSm]=\"7\" [sizeLg]=\"8\" [pullLg]=\"4\">\n <h2>{{ viewDate | calendarDate : view + 'ViewTitle' : locale }}</h2>\n <p *ngIf=\"titleNotes\">{{ titleNotes }}</p>\n </ion-col>\n </ion-row>\n <!-- TEMPLATES (touch only what's necessary and leave everything else as it is) -->\n <ng-template #eventTitleTemplate let-event=\"event\" let-view=\"view\">\n <span\n class=\"cal-event-title\"\n [class.noWrap]=\"event.allDay\"\n [attr.aria-hidden]=\"{} | calendarA11y : 'hideEventTitle'\"\n >\n {{ event.title | calendarEventTitle : view : event }}\n <p *ngIf=\"!event.allDay\">{{ getPreviewDescription(event.description) }}</p>\n </span>\n </ng-template>\n <ng-template\n #eventTemplate\n let-weekEvent=\"weekEvent\"\n let-tooltipPlacement=\"tooltipPlacement\"\n let-eventClicked=\"eventClicked\"\n let-tooltipTemplate=\"tooltipTemplate\"\n let-tooltipAppendToBody=\"tooltipAppendToBody\"\n let-tooltipDisabled=\"tooltipDisabled\"\n let-tooltipDelay=\"tooltipDelay\"\n let-column=\"column\"\n let-daysInWeek=\"daysInWeek\"\n >\n <div\n class=\"cal-event\"\n [class.external]=\"weekEvent.event.external\"\n [class.needsAction]=\"Attendance.NEEDS_ACTION === weekEvent.event.attendance\"\n [class.declined]=\"Attendance.DECLINED === weekEvent.event.attendance\"\n [class.tentative]=\"Attendance.TENTATIVE === weekEvent.event.attendance\"\n [style.border-left-color]=\"weekEvent.event.color?.primary\"\n [style.color]=\"getAlternateColor(weekEvent.event.color?.primary, darkMode ? 80 : -40)\"\n [style.background-color]=\"getAlternateColor(weekEvent.event.color?.primary, darkMode ? 60 : 80, 0.2)\"\n [mwlCalendarTooltip]=\"!tooltipDisabled && !isMobile() ? getTooltipContent(weekEvent.event) : ''\"\n [tooltipPlacement]=\"tooltipPlacement\"\n [tooltipEvent]=\"weekEvent.tempEvent || weekEvent.event\"\n [tooltipTemplate]=\"tooltipTemplate\"\n [tooltipAppendToBody]=\"tooltipAppendToBody\"\n [tooltipDelay]=\"tooltipDelay\"\n (mwlClick)=\"eventClicked.emit({ sourceEvent: $event })\"\n (mwlKeydownEnter)=\"eventClicked.emit({ sourceEvent: $event })\"\n tabindex=\"0\"\n role=\"application\"\n [attr.aria-label]=\"\n { event: weekEvent.tempEvent || weekEvent.event, locale: locale } | calendarA11y : 'eventDescription'\n \"\n >\n <mwl-calendar-event-actions [event]=\"weekEvent.tempEvent || weekEvent.event\"></mwl-calendar-event-actions>\n &ngsp;\n <mwl-calendar-event-title\n [event]=\"weekEvent.tempEvent || weekEvent.event\"\n [customTemplate]=\"eventTitleTemplate\"\n [view]=\"daysInWeek === 1 ? 'day' : 'week'\"\n >\n </mwl-calendar-event-title>\n <div class=\"eventGadgets\" *ngIf=\"!weekEvent.event.allDay\">\n <ion-icon *ngFor=\"let icon of weekEvent.event.icons\" [name]=\"icon.name\" [title]=\"icon.title\"></ion-icon>\n <idea-user-avatar\n size=\"mini\"\n *ngFor=\"let avatar of weekEvent.event.avatars\"\n [src]=\"avatar.url\"\n [name]=\"avatar.title\"\n ></idea-user-avatar>\n </div>\n </div>\n </ng-template>\n <ng-template\n #hourSegmentTemplate\n let-segment=\"segment\"\n let-locale=\"locale\"\n let-segmentHeight=\"segmentHeight\"\n let-isTimeLabel=\"isTimeLabel\"\n >\n <div\n #segmentElement\n class=\"cal-hour-segment\"\n [style.height.px]=\"segmentHeight\"\n [class.cal-hour-start]=\"segment.isStart\"\n [class.cal-after-hour-start]=\"!segment.isStart\"\n [ngClass]=\"segment.cssClass\"\n (mousedown)=\"allowDragToCreate ? startDragToCreate($event, segment.date, segmentElement) : null\"\n (touchstart)=\"allowDragToCreate ? startDragToCreate($event, segment.date, segmentElement) : null\"\n >\n <div class=\"cal-time\" *ngIf=\"isTimeLabel\">\n {{ segment.date | calendarDate : 'weekViewHour' : locale }}\n </div>\n </div>\n </ng-template>\n <!-- VIEWS -->\n <div [ngSwitch]=\"view\">\n <mwl-calendar-month-view\n *ngSwitchCase=\"CalendarView.Month\"\n [viewDate]=\"viewDate\"\n [events]=\"events\"\n [refresh]=\"refresh\"\n [activeDayIsOpen]=\"activeDayIsOpen\"\n [locale]=\"locale\"\n [excludeDays]=\"excludeDays\"\n [weekStartsOn]=\"weekStartsOn\"\n [eventTitleTemplate]=\"eventTitleTemplate\"\n (eventClicked)=\"selectEvent.emit($event.event)\"\n (eventTimesChanged)=\"eventTimesChanged($event)\"\n (dayClicked)=\"changeDay($event.day)\"\n (beforeViewRender)=\"beforeMonthViewRender($event)\"\n >\n </mwl-calendar-month-view>\n <mwl-calendar-week-view\n *ngSwitchCase=\"CalendarView.Week\"\n [viewDate]=\"viewDate\"\n [events]=\"events\"\n [refresh]=\"refresh\"\n [locale]=\"locale\"\n [excludeDays]=\"excludeDays\"\n [weekStartsOn]=\"weekStartsOn\"\n [dayStartHour]=\"dayStartHour\"\n [dayEndHour]=\"dayEndHour\"\n [hourSegments]=\"hourSegments\"\n [eventTemplate]=\"eventTemplate\"\n [hourSegmentTemplate]=\"hourSegmentTemplate\"\n (eventClicked)=\"selectEvent.emit($event.event)\"\n (eventTimesChanged)=\"eventTimesChanged($event)\"\n (dayHeaderClicked)=\"dateIsValid($event.day.date) ? selectDay.emit($event.day.date) : null\"\n (hourSegmentClicked)=\"dateIsValid($event.date) ? selectSlot.emit($event.date) : null\"\n (beforeViewRender)=\"beforeWeekOrDayViewRender($event)\"\n >\n </mwl-calendar-week-view>\n <mwl-calendar-day-view\n *ngSwitchCase=\"CalendarView.Day\"\n [viewDate]=\"viewDate\"\n [events]=\"events\"\n [refresh]=\"refresh\"\n [locale]=\"locale\"\n [dayStartHour]=\"dayStartHour\"\n [dayEndHour]=\"dayEndHour\"\n [hourSegments]=\"hourSegments\"\n [eventTemplate]=\"eventTemplate\"\n [hourSegmentTemplate]=\"hourSegmentTemplate\"\n (eventClicked)=\"selectEvent.emit($event.event)\"\n (eventTimesChanged)=\"eventTimesChanged($event)\"\n (hourSegmentClicked)=\"dateIsValid($event.date) ? selectSlot.emit($event.date) : null\"\n (beforeViewRender)=\"beforeWeekOrDayViewRender($event)\"\n >\n </mwl-calendar-day-view>\n </div>\n</div>\n", styles: [".agenda{margin-top:15px}.agenda ion-col.titleCol{padding-left:8px}.agenda ion-col.titleCol h2,.agenda ion-col.titleCol p{margin:0}.agenda ion-col.titleCol h2{font-size:1.2em}.agenda ion-col.titleCol p{font-size:.8em;font-style:italic}.agenda .calendarViewSelector{background-color:transparent;--ion-background-color: transparent;--background: transparent}.agenda .calendarViewSelector ion-select{max-width:100%;width:100%;padding-left:0;font-weight:500}.agenda .eventGadgets{margin-top:4px;margin-left:5px;text-align:right}.agenda .eventGadgets idea-user-avatar{display:block;float:left;margin:2px 1px}.agenda .eventGadgets ion-icon{padding-right:2px;opacity:.7;font-size:1.15em}@media only screen and (max-width: 575px){.agenda ion-col.titleCol{padding:0 8px 12px;text-align:center}}\n"], dependencies: [{ kind: "directive", type: i3$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3$1.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3$1.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i2.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "expandedIcon", "fill", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "legacy", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: i2.IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "directive", type: i2.SelectValueAccessor, selector: "ion-select, ion-radio-group, ion-segment, ion-datetime" }, { kind: "component", type: i3.IDEAUserAvatarComponent, selector: "idea-user-avatar", inputs: ["src", "name", "size", "color"] }, { kind: "component", type: i4.ɵCalendarEventActionsComponent, selector: "mwl-calendar-event-actions", inputs: ["event", "customTemplate"] }, { kind: "component", type: i4.ɵCalendarEventTitleComponent, selector: "mwl-calendar-event-title", inputs: ["event", "customTemplate", "view"] }, { kind: "directive", type: i4.ɵCalendarTooltipDirective, selector: "[mwlCalendarTooltip]", inputs: ["mwlCalendarTooltip", "tooltipPlacement", "tooltipTemplate", "tooltipEvent", "tooltipAppendToBody", "tooltipDelay"] }, { kind: "directive", type: i4.ɵCalendarPreviousViewDirective, selector: "[mwlCalendarPreviousView]", inputs: ["view", "viewDate", "excludeDays", "daysInWeek"], outputs: ["viewDateChange"] }, { kind: "directive", type: i4.ɵCalendarNextViewDirective, selector: "[mwlCalendarNextView]", inputs: ["view", "viewDate", "excludeDays", "daysInWeek"], outputs: ["viewDateChange"] }, { kind: "directive", type: i4.ɵCalendarTodayDirective, selector: "[mwlCalendarToday]", inputs: ["viewDate"], outputs: ["viewDateChange"] }, { kind: "directive", type: i4.ɵClickDirective, selector: "[mwlClick]", inputs: ["clickListenerDisabled"], outputs: ["mwlClick"] }, { kind: "directive", type: i4.ɵKeydownEnterDirective, selector: "[mwlKeydownEnter]", outputs: ["mwlKeydownEnter"] }, { kind: "component", type: i4.CalendarMonthViewComponent, selector: "mwl-calendar-month-view", inputs: ["viewDate", "events", "excludeDays", "activeDayIsOpen", "activeDay", "refresh", "locale", "tooltipPlacement", "tooltipTemplate", "tooltipAppendToBody", "tooltipDelay", "weekStartsOn", "headerTemplate", "cellTemplate", "openDayEventsTemplate", "eventTitleTemplate", "eventActionsTemplate", "weekendDays"], outputs: ["beforeViewRender", "dayClicked", "eventClicked", "columnHeaderClicked", "eventTimesChanged"] }, { kind: "component", type: i4.CalendarWeekViewComponent, selector: "mwl-calendar-week-view", inputs: ["viewDate", "events", "excludeDays", "refresh", "locale", "tooltipPlacement", "tooltipTemplate", "tooltipAppendToBody", "tooltipDelay", "weekStartsOn", "headerTemplate", "eventTemplate", "eventTitleTemplate", "eventActionsTemplate", "precision", "weekendDays", "snapDraggedEvents", "hourSegments", "hourDuration", "hourSegmentHeight", "minimumEventHeight", "dayStartHour", "dayStartMinute", "dayEndHour", "dayEndMinute", "hourSegmentTemplate", "eventSnapSize", "allDayEventsLabelTemplate", "daysInWeek", "currentTimeMarkerTemplate", "validateEventTimesChanged", "resizeCursors"], outputs: ["dayHeaderClicked", "eventClicked", "eventTimesChanged", "beforeViewRender", "hourSegmentClicked"] }, { kind: "component", type: i4.CalendarDayViewComponent, selector: "mwl-calendar-day-view", inputs: ["viewDate", "events", "hourSegments", "hourSegmentHeight", "hourDuration", "minimumEventHeight", "dayStartHour", "dayStartMinute", "dayEndHour", "dayEndMinute", "refresh", "locale", "eventSnapSize", "tooltipPlacement", "tooltipTemplate", "tooltipAppendToBody", "tooltipDelay", "hourSegmentTemplate", "eventTemplate", "eventTitleTemplate", "eventActionsTemplate", "snapDraggedEvents", "allDayEventsLabelTemplate", "currentTimeMarkerTemplate", "validateEventTimesChanged", "resizeCursors"], outputs: ["eventClicked", "hourSegmentClicked", "eventTimesChanged", "beforeViewRender"] }, { kind: "pipe", type: i3$1.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i3.IDEATranslatePipe, name: "translate" }, { kind: "pipe", type: i4.ɵCalendarDatePipe, name: "calendarDate" }, { kind: "pipe", type: i4.ɵCalendarEventTitlePipe, name: "calendarEventTitle" }, { kind: "pipe", type: i4.ɵCalendarA11yPipe, name: "calendarA11y" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
272
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEAAgendaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
273
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.1", type: IDEAAgendaComponent, selector: "idea-agenda", inputs: { events: "events", excludeDays: "excludeDays", dayStartHour: "dayStartHour", dayEndHour: "dayEndHour", hourSegments: "hourSegments", activeDayIsOpen: "activeDayIsOpen", view: "view", allowedViews: "allowedViews", onlyFuture: "onlyFuture", titleNotes: "titleNotes", newEventTemplate: "newEventTemplate", allowDragToCreate: "allowDragToCreate", parentContent: "parentContent" }, outputs: { selectEvent: "selectEvent", selectDay: "selectDay", selectSlot: "selectSlot", newEventByDrag: "newEventByDrag", changeEvent: "changeEvent", changeDate: "changeDate", beforeWeekOrDayViewRenderEmitter: "beforeWeekOrDayViewRenderEmitter", beforeMonthViewRenderEmitter: "beforeMonthViewRenderEmitter" }, ngImport: i0, template: "<div class=\"agenda\">\n <!-- TOOLBAR -->\n <ion-row class=\"ion-align-items-center\">\n <ion-col\n class=\"ion-align-self-center ion-text-right\"\n [size]=\"5\"\n [sizeSm]=\"3\"\n [pushSm]=\"5\"\n [sizeLg]=\"2\"\n [pushLg]=\"8\"\n >\n @if (allowedViews.length > 1) {\n <ion-item lines=\"none\" class=\"calendarViewSelector\">\n <ion-select\n interface=\"popover\"\n [value]=\"view\"\n (ionChange)=\"$event?.detail ? setView($event.detail.value) : null\"\n >\n @for (view of allowedViews; track view) {\n <ion-select-option [value]=\"view\">\n {{ 'IDEA_AGENDA.' + view | uppercase | translate }}\n </ion-select-option>\n }\n </ion-select>\n </ion-item>\n }\n </ion-col>\n <ion-col\n class=\"ion-align-self-center ion-text-right\"\n [size]=\"7\"\n [sizeSm]=\"4\"\n [pushSm]=\"5\"\n [sizeLg]=\"2\"\n [pushLg]=\"8\"\n >\n <ion-button\n fill=\"clear\"\n color=\"dark\"\n size=\"small\"\n mwlCalendarPreviousView\n [view]=\"view\"\n [(viewDate)]=\"viewDate\"\n (viewDateChange)=\"viewDateChanged($event)\"\n >\n <ion-icon name=\"chevron-back-outline\" slot=\"icon-only\" />\n </ion-button>\n <ion-button\n fill=\"clear\"\n color=\"dark\"\n size=\"small\"\n mwlCalendarToday\n [(viewDate)]=\"viewDate\"\n (viewDateChange)=\"viewDateChanged($event)\"\n >\n <ion-icon name=\"today-outline\" slot=\"icon-only\" />\n </ion-button>\n <ion-button\n fill=\"clear\"\n color=\"dark\"\n size=\"small\"\n mwlCalendarNextView\n [view]=\"view\"\n [(viewDate)]=\"viewDate\"\n (viewDateChange)=\"viewDateChanged($event)\"\n >\n <ion-icon name=\"chevron-forward-outline\" slot=\"icon-only\" />\n </ion-button>\n </ion-col>\n <ion-col class=\"ion-align-self-center titleCol\" [size]=\"12\" [sizeSm]=\"5\" [pullSm]=\"7\" [sizeLg]=\"8\" [pullLg]=\"4\">\n <h2>{{ viewDate | calendarDate: view + 'ViewTitle' : locale }}</h2>\n @if (titleNotes) {\n <p>{{ titleNotes }}</p>\n }\n </ion-col>\n </ion-row>\n <!-- TEMPLATES (touch only what's necessary and leave everything else as it is) -->\n <ng-template #eventTitleTemplate let-event=\"event\" let-view=\"view\">\n <span\n class=\"cal-event-title\"\n [class.noWrap]=\"event.allDay\"\n [attr.aria-hidden]=\"{} | calendarA11y: 'hideEventTitle'\"\n >\n {{ event.title | calendarEventTitle: view : event }}\n @if (!event.allDay) {\n <p>{{ getPreviewDescription(event.description) }}</p>\n }\n </span>\n </ng-template>\n <ng-template\n #eventTemplate\n let-weekEvent=\"weekEvent\"\n let-tooltipPlacement=\"tooltipPlacement\"\n let-eventClicked=\"eventClicked\"\n let-tooltipTemplate=\"tooltipTemplate\"\n let-tooltipAppendToBody=\"tooltipAppendToBody\"\n let-tooltipDisabled=\"tooltipDisabled\"\n let-tooltipDelay=\"tooltipDelay\"\n let-column=\"column\"\n let-daysInWeek=\"daysInWeek\"\n >\n <div\n class=\"cal-event\"\n [class.external]=\"weekEvent.event.external\"\n [class.needsAction]=\"Attendance.NEEDS_ACTION === weekEvent.event.attendance\"\n [class.declined]=\"Attendance.DECLINED === weekEvent.event.attendance\"\n [class.tentative]=\"Attendance.TENTATIVE === weekEvent.event.attendance\"\n [style.border-left-color]=\"weekEvent.event.color?.primary\"\n [style.color]=\"getAlternateColor(weekEvent.event.color?.primary, darkMode ? 80 : -40)\"\n [style.background-color]=\"getAlternateColor(weekEvent.event.color?.primary, darkMode ? 60 : 80, 0.2)\"\n [mwlCalendarTooltip]=\"!tooltipDisabled && !isMobile() ? getTooltipContent(weekEvent.event) : ''\"\n [tooltipPlacement]=\"tooltipPlacement\"\n [tooltipEvent]=\"weekEvent.tempEvent || weekEvent.event\"\n [tooltipTemplate]=\"tooltipTemplate\"\n [tooltipAppendToBody]=\"tooltipAppendToBody\"\n [tooltipDelay]=\"tooltipDelay\"\n (mwlClick)=\"eventClicked.emit({ sourceEvent: $event })\"\n (mwlKeydownEnter)=\"eventClicked.emit({ sourceEvent: $event })\"\n tabindex=\"0\"\n role=\"application\"\n [attr.aria-label]=\"\n { event: weekEvent.tempEvent || weekEvent.event, locale: locale } | calendarA11y: 'eventDescription'\n \"\n >\n <mwl-calendar-event-actions [event]=\"weekEvent.tempEvent || weekEvent.event\" />\n &ngsp;\n <mwl-calendar-event-title\n [event]=\"weekEvent.tempEvent || weekEvent.event\"\n [customTemplate]=\"eventTitleTemplate\"\n [view]=\"daysInWeek === 1 ? 'day' : 'week'\"\n >\n </mwl-calendar-event-title>\n @if (!weekEvent.event.allDay) {\n <div class=\"eventGadgets\">\n @for (icon of weekEvent.event.icons; track icon) {\n <ion-icon [name]=\"icon.name\" [title]=\"icon.title\" />\n }\n @for (avatar of weekEvent.event.avatars; track avatar) {\n <idea-user-avatar size=\"mini\" [src]=\"avatar.url\" [name]=\"avatar.title\" />\n }\n </div>\n }\n </div>\n </ng-template>\n <ng-template\n #hourSegmentTemplate\n let-segment=\"segment\"\n let-locale=\"locale\"\n let-segmentHeight=\"segmentHeight\"\n let-isTimeLabel=\"isTimeLabel\"\n >\n <div\n #segmentElement\n class=\"cal-hour-segment\"\n [style.height.px]=\"segmentHeight\"\n [class.cal-hour-start]=\"segment.isStart\"\n [class.cal-after-hour-start]=\"!segment.isStart\"\n [ngClass]=\"segment.cssClass\"\n (mousedown)=\"allowDragToCreate ? startDragToCreate($event, segment.date, segmentElement) : null\"\n (touchstart)=\"allowDragToCreate ? startDragToCreate($event, segment.date, segmentElement) : null\"\n >\n @if (isTimeLabel) {\n <div class=\"cal-time\">\n {{ segment.date | calendarDate: 'weekViewHour' : locale }}\n </div>\n }\n </div>\n </ng-template>\n <!-- VIEWS -->\n <div>\n @switch (view) {\n @case (CalendarView.Month) {\n <mwl-calendar-month-view\n [viewDate]=\"viewDate\"\n [events]=\"events\"\n [refresh]=\"refresh\"\n [activeDayIsOpen]=\"activeDayIsOpen\"\n [locale]=\"locale\"\n [excludeDays]=\"excludeDays\"\n [weekStartsOn]=\"weekStartsOn\"\n [eventTitleTemplate]=\"eventTitleTemplate\"\n (eventClicked)=\"selectEvent.emit($event.event)\"\n (eventTimesChanged)=\"eventTimesChanged($event)\"\n (dayClicked)=\"changeDay($event.day)\"\n (beforeViewRender)=\"beforeMonthViewRender($event)\"\n >\n </mwl-calendar-month-view>\n }\n @case (CalendarView.Week) {\n <mwl-calendar-week-view\n [viewDate]=\"viewDate\"\n [events]=\"events\"\n [refresh]=\"refresh\"\n [locale]=\"locale\"\n [excludeDays]=\"excludeDays\"\n [weekStartsOn]=\"weekStartsOn\"\n [dayStartHour]=\"dayStartHour\"\n [dayEndHour]=\"dayEndHour\"\n [hourSegments]=\"hourSegments\"\n [eventTemplate]=\"eventTemplate\"\n [hourSegmentTemplate]=\"hourSegmentTemplate\"\n (eventClicked)=\"selectEvent.emit($event.event)\"\n (eventTimesChanged)=\"eventTimesChanged($event)\"\n (dayHeaderClicked)=\"dateIsValid($event.day.date) ? selectDay.emit($event.day.date) : null\"\n (hourSegmentClicked)=\"dateIsValid($event.date) ? selectSlot.emit($event.date) : null\"\n (beforeViewRender)=\"beforeWeekOrDayViewRender($event)\"\n >\n </mwl-calendar-week-view>\n }\n @case (CalendarView.Day) {\n <mwl-calendar-day-view\n [viewDate]=\"viewDate\"\n [events]=\"events\"\n [refresh]=\"refresh\"\n [locale]=\"locale\"\n [dayStartHour]=\"dayStartHour\"\n [dayEndHour]=\"dayEndHour\"\n [hourSegments]=\"hourSegments\"\n [eventTemplate]=\"eventTemplate\"\n [hourSegmentTemplate]=\"hourSegmentTemplate\"\n (eventClicked)=\"selectEvent.emit($event.event)\"\n (eventTimesChanged)=\"eventTimesChanged($event)\"\n (hourSegmentClicked)=\"dateIsValid($event.date) ? selectSlot.emit($event.date) : null\"\n (beforeViewRender)=\"beforeWeekOrDayViewRender($event)\"\n >\n </mwl-calendar-day-view>\n }\n }\n </div>\n</div>\n", styles: [".agenda{margin-top:15px}.agenda ion-col.titleCol{padding-left:8px}.agenda ion-col.titleCol h2,.agenda ion-col.titleCol p{margin:0}.agenda ion-col.titleCol h2{font-size:1.2em}.agenda ion-col.titleCol p{font-size:.8em;font-style:italic}.agenda .calendarViewSelector{background-color:transparent;--ion-background-color: transparent;--background: transparent}.agenda .calendarViewSelector ion-select{max-width:100%;width:100%;padding-left:0;font-weight:500}.agenda .eventGadgets{margin-top:4px;margin-left:5px;text-align:right}.agenda .eventGadgets idea-user-avatar{display:block;float:left;margin:2px 1px}.agenda .eventGadgets ion-icon{padding-right:2px;opacity:.7;font-size:1.15em}@media only screen and (max-width: 575px){.agenda ion-col.titleCol{padding:0 8px 12px;text-align:center}}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonSelect, selector: "ion-select", inputs: ["cancelText", "color", "compareWith", "disabled", "expandedIcon", "fill", "interface", "interfaceOptions", "justify", "label", "labelPlacement", "mode", "multiple", "name", "okText", "placeholder", "selectedText", "shape", "toggleIcon", "value"] }, { kind: "component", type: i2.IonSelectOption, selector: "ion-select-option", inputs: ["disabled", "value"] }, { kind: "directive", type: i2.SelectValueAccessor, selector: "ion-select, ion-radio-group, ion-segment, ion-datetime" }, { kind: "component", type: i3.IDEAUserAvatarComponent, selector: "idea-user-avatar", inputs: ["src", "name", "size", "color"] }, { kind: "component", type: i4.ɵCalendarEventActionsComponent, selector: "mwl-calendar-event-actions", inputs: ["event", "customTemplate"] }, { kind: "component", type: i4.ɵCalendarEventTitleComponent, selector: "mwl-calendar-event-title", inputs: ["event", "customTemplate", "view"] }, { kind: "directive", type: i4.ɵCalendarTooltipDirective, selector: "[mwlCalendarTooltip]", inputs: ["mwlCalendarTooltip", "tooltipPlacement", "tooltipTemplate", "tooltipEvent", "tooltipAppendToBody", "tooltipDelay"] }, { kind: "directive", type: i4.ɵCalendarPreviousViewDirective, selector: "[mwlCalendarPreviousView]", inputs: ["view", "viewDate", "excludeDays", "daysInWeek"], outputs: ["viewDateChange"] }, { kind: "directive", type: i4.ɵCalendarNextViewDirective, selector: "[mwlCalendarNextView]", inputs: ["view", "viewDate", "excludeDays", "daysInWeek"], outputs: ["viewDateChange"] }, { kind: "directive", type: i4.ɵCalendarTodayDirective, selector: "[mwlCalendarToday]", inputs: ["viewDate"], outputs: ["viewDateChange"] }, { kind: "directive", type: i4.ɵClickDirective, selector: "[mwlClick]", inputs: ["clickListenerDisabled"], outputs: ["mwlClick"] }, { kind: "directive", type: i4.ɵKeydownEnterDirective, selector: "[mwlKeydownEnter]", outputs: ["mwlKeydownEnter"] }, { kind: "component", type: i4.CalendarMonthViewComponent, selector: "mwl-calendar-month-view", inputs: ["viewDate", "events", "excludeDays", "activeDayIsOpen", "activeDay", "refresh", "locale", "tooltipPlacement", "tooltipTemplate", "tooltipAppendToBody", "tooltipDelay", "weekStartsOn", "headerTemplate", "cellTemplate", "openDayEventsTemplate", "eventTitleTemplate", "eventActionsTemplate", "weekendDays"], outputs: ["beforeViewRender", "dayClicked", "eventClicked", "columnHeaderClicked", "eventTimesChanged"] }, { kind: "component", type: i4.CalendarWeekViewComponent, selector: "mwl-calendar-week-view", inputs: ["viewDate", "events", "excludeDays", "refresh", "locale", "tooltipPlacement", "tooltipTemplate", "tooltipAppendToBody", "tooltipDelay", "weekStartsOn", "headerTemplate", "eventTemplate", "eventTitleTemplate", "eventActionsTemplate", "precision", "weekendDays", "snapDraggedEvents", "hourSegments", "hourDuration", "hourSegmentHeight", "minimumEventHeight", "dayStartHour", "dayStartMinute", "dayEndHour", "dayEndMinute", "hourSegmentTemplate", "eventSnapSize", "allDayEventsLabelTemplate", "daysInWeek", "currentTimeMarkerTemplate", "validateEventTimesChanged", "resizeCursors"], outputs: ["dayHeaderClicked", "eventClicked", "eventTimesChanged", "beforeViewRender", "hourSegmentClicked"] }, { kind: "component", type: i4.CalendarDayViewComponent, selector: "mwl-calendar-day-view", inputs: ["viewDate", "events", "hourSegments", "hourSegmentHeight", "hourDuration", "minimumEventHeight", "dayStartHour", "dayStartMinute", "dayEndHour", "dayEndMinute", "refresh", "locale", "eventSnapSize", "tooltipPlacement", "tooltipTemplate", "tooltipAppendToBody", "tooltipDelay", "hourSegmentTemplate", "eventTemplate", "eventTitleTemplate", "eventActionsTemplate", "snapDraggedEvents", "allDayEventsLabelTemplate", "currentTimeMarkerTemplate", "validateEventTimesChanged", "resizeCursors"], outputs: ["eventClicked", "hourSegmentClicked", "eventTimesChanged", "beforeViewRender"] }, { kind: "pipe", type: i1.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i3.IDEATranslatePipe, name: "translate" }, { kind: "pipe", type: i4.ɵCalendarDatePipe, name: "calendarDate" }, { kind: "pipe", type: i4.ɵCalendarEventTitlePipe, name: "calendarEventTitle" }, { kind: "pipe", type: i4.ɵCalendarA11yPipe, name: "calendarA11y" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
316
274
|
}
|
|
317
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
275
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEAAgendaComponent, decorators: [{
|
|
318
276
|
type: Component,
|
|
319
|
-
args: [{ selector: 'idea-agenda', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"agenda\">\n <!-- TOOLBAR -->\n <ion-row class=\"ion-align-items-center\">\n <ion-col\n class=\"ion-align-self-center ion-text-right\"\n [size]=\"5\"\n [sizeSm]=\"3\"\n [pushSm]=\"5\"\n [sizeLg]=\"2\"\n [pushLg]=\"8\"\n >\n <ion-item lines=\"none\" class=\"calendarViewSelector\"
|
|
320
|
-
}],
|
|
277
|
+
args: [{ selector: 'idea-agenda', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"agenda\">\n <!-- TOOLBAR -->\n <ion-row class=\"ion-align-items-center\">\n <ion-col\n class=\"ion-align-self-center ion-text-right\"\n [size]=\"5\"\n [sizeSm]=\"3\"\n [pushSm]=\"5\"\n [sizeLg]=\"2\"\n [pushLg]=\"8\"\n >\n @if (allowedViews.length > 1) {\n <ion-item lines=\"none\" class=\"calendarViewSelector\">\n <ion-select\n interface=\"popover\"\n [value]=\"view\"\n (ionChange)=\"$event?.detail ? setView($event.detail.value) : null\"\n >\n @for (view of allowedViews; track view) {\n <ion-select-option [value]=\"view\">\n {{ 'IDEA_AGENDA.' + view | uppercase | translate }}\n </ion-select-option>\n }\n </ion-select>\n </ion-item>\n }\n </ion-col>\n <ion-col\n class=\"ion-align-self-center ion-text-right\"\n [size]=\"7\"\n [sizeSm]=\"4\"\n [pushSm]=\"5\"\n [sizeLg]=\"2\"\n [pushLg]=\"8\"\n >\n <ion-button\n fill=\"clear\"\n color=\"dark\"\n size=\"small\"\n mwlCalendarPreviousView\n [view]=\"view\"\n [(viewDate)]=\"viewDate\"\n (viewDateChange)=\"viewDateChanged($event)\"\n >\n <ion-icon name=\"chevron-back-outline\" slot=\"icon-only\" />\n </ion-button>\n <ion-button\n fill=\"clear\"\n color=\"dark\"\n size=\"small\"\n mwlCalendarToday\n [(viewDate)]=\"viewDate\"\n (viewDateChange)=\"viewDateChanged($event)\"\n >\n <ion-icon name=\"today-outline\" slot=\"icon-only\" />\n </ion-button>\n <ion-button\n fill=\"clear\"\n color=\"dark\"\n size=\"small\"\n mwlCalendarNextView\n [view]=\"view\"\n [(viewDate)]=\"viewDate\"\n (viewDateChange)=\"viewDateChanged($event)\"\n >\n <ion-icon name=\"chevron-forward-outline\" slot=\"icon-only\" />\n </ion-button>\n </ion-col>\n <ion-col class=\"ion-align-self-center titleCol\" [size]=\"12\" [sizeSm]=\"5\" [pullSm]=\"7\" [sizeLg]=\"8\" [pullLg]=\"4\">\n <h2>{{ viewDate | calendarDate: view + 'ViewTitle' : locale }}</h2>\n @if (titleNotes) {\n <p>{{ titleNotes }}</p>\n }\n </ion-col>\n </ion-row>\n <!-- TEMPLATES (touch only what's necessary and leave everything else as it is) -->\n <ng-template #eventTitleTemplate let-event=\"event\" let-view=\"view\">\n <span\n class=\"cal-event-title\"\n [class.noWrap]=\"event.allDay\"\n [attr.aria-hidden]=\"{} | calendarA11y: 'hideEventTitle'\"\n >\n {{ event.title | calendarEventTitle: view : event }}\n @if (!event.allDay) {\n <p>{{ getPreviewDescription(event.description) }}</p>\n }\n </span>\n </ng-template>\n <ng-template\n #eventTemplate\n let-weekEvent=\"weekEvent\"\n let-tooltipPlacement=\"tooltipPlacement\"\n let-eventClicked=\"eventClicked\"\n let-tooltipTemplate=\"tooltipTemplate\"\n let-tooltipAppendToBody=\"tooltipAppendToBody\"\n let-tooltipDisabled=\"tooltipDisabled\"\n let-tooltipDelay=\"tooltipDelay\"\n let-column=\"column\"\n let-daysInWeek=\"daysInWeek\"\n >\n <div\n class=\"cal-event\"\n [class.external]=\"weekEvent.event.external\"\n [class.needsAction]=\"Attendance.NEEDS_ACTION === weekEvent.event.attendance\"\n [class.declined]=\"Attendance.DECLINED === weekEvent.event.attendance\"\n [class.tentative]=\"Attendance.TENTATIVE === weekEvent.event.attendance\"\n [style.border-left-color]=\"weekEvent.event.color?.primary\"\n [style.color]=\"getAlternateColor(weekEvent.event.color?.primary, darkMode ? 80 : -40)\"\n [style.background-color]=\"getAlternateColor(weekEvent.event.color?.primary, darkMode ? 60 : 80, 0.2)\"\n [mwlCalendarTooltip]=\"!tooltipDisabled && !isMobile() ? getTooltipContent(weekEvent.event) : ''\"\n [tooltipPlacement]=\"tooltipPlacement\"\n [tooltipEvent]=\"weekEvent.tempEvent || weekEvent.event\"\n [tooltipTemplate]=\"tooltipTemplate\"\n [tooltipAppendToBody]=\"tooltipAppendToBody\"\n [tooltipDelay]=\"tooltipDelay\"\n (mwlClick)=\"eventClicked.emit({ sourceEvent: $event })\"\n (mwlKeydownEnter)=\"eventClicked.emit({ sourceEvent: $event })\"\n tabindex=\"0\"\n role=\"application\"\n [attr.aria-label]=\"\n { event: weekEvent.tempEvent || weekEvent.event, locale: locale } | calendarA11y: 'eventDescription'\n \"\n >\n <mwl-calendar-event-actions [event]=\"weekEvent.tempEvent || weekEvent.event\" />\n &ngsp;\n <mwl-calendar-event-title\n [event]=\"weekEvent.tempEvent || weekEvent.event\"\n [customTemplate]=\"eventTitleTemplate\"\n [view]=\"daysInWeek === 1 ? 'day' : 'week'\"\n >\n </mwl-calendar-event-title>\n @if (!weekEvent.event.allDay) {\n <div class=\"eventGadgets\">\n @for (icon of weekEvent.event.icons; track icon) {\n <ion-icon [name]=\"icon.name\" [title]=\"icon.title\" />\n }\n @for (avatar of weekEvent.event.avatars; track avatar) {\n <idea-user-avatar size=\"mini\" [src]=\"avatar.url\" [name]=\"avatar.title\" />\n }\n </div>\n }\n </div>\n </ng-template>\n <ng-template\n #hourSegmentTemplate\n let-segment=\"segment\"\n let-locale=\"locale\"\n let-segmentHeight=\"segmentHeight\"\n let-isTimeLabel=\"isTimeLabel\"\n >\n <div\n #segmentElement\n class=\"cal-hour-segment\"\n [style.height.px]=\"segmentHeight\"\n [class.cal-hour-start]=\"segment.isStart\"\n [class.cal-after-hour-start]=\"!segment.isStart\"\n [ngClass]=\"segment.cssClass\"\n (mousedown)=\"allowDragToCreate ? startDragToCreate($event, segment.date, segmentElement) : null\"\n (touchstart)=\"allowDragToCreate ? startDragToCreate($event, segment.date, segmentElement) : null\"\n >\n @if (isTimeLabel) {\n <div class=\"cal-time\">\n {{ segment.date | calendarDate: 'weekViewHour' : locale }}\n </div>\n }\n </div>\n </ng-template>\n <!-- VIEWS -->\n <div>\n @switch (view) {\n @case (CalendarView.Month) {\n <mwl-calendar-month-view\n [viewDate]=\"viewDate\"\n [events]=\"events\"\n [refresh]=\"refresh\"\n [activeDayIsOpen]=\"activeDayIsOpen\"\n [locale]=\"locale\"\n [excludeDays]=\"excludeDays\"\n [weekStartsOn]=\"weekStartsOn\"\n [eventTitleTemplate]=\"eventTitleTemplate\"\n (eventClicked)=\"selectEvent.emit($event.event)\"\n (eventTimesChanged)=\"eventTimesChanged($event)\"\n (dayClicked)=\"changeDay($event.day)\"\n (beforeViewRender)=\"beforeMonthViewRender($event)\"\n >\n </mwl-calendar-month-view>\n }\n @case (CalendarView.Week) {\n <mwl-calendar-week-view\n [viewDate]=\"viewDate\"\n [events]=\"events\"\n [refresh]=\"refresh\"\n [locale]=\"locale\"\n [excludeDays]=\"excludeDays\"\n [weekStartsOn]=\"weekStartsOn\"\n [dayStartHour]=\"dayStartHour\"\n [dayEndHour]=\"dayEndHour\"\n [hourSegments]=\"hourSegments\"\n [eventTemplate]=\"eventTemplate\"\n [hourSegmentTemplate]=\"hourSegmentTemplate\"\n (eventClicked)=\"selectEvent.emit($event.event)\"\n (eventTimesChanged)=\"eventTimesChanged($event)\"\n (dayHeaderClicked)=\"dateIsValid($event.day.date) ? selectDay.emit($event.day.date) : null\"\n (hourSegmentClicked)=\"dateIsValid($event.date) ? selectSlot.emit($event.date) : null\"\n (beforeViewRender)=\"beforeWeekOrDayViewRender($event)\"\n >\n </mwl-calendar-week-view>\n }\n @case (CalendarView.Day) {\n <mwl-calendar-day-view\n [viewDate]=\"viewDate\"\n [events]=\"events\"\n [refresh]=\"refresh\"\n [locale]=\"locale\"\n [dayStartHour]=\"dayStartHour\"\n [dayEndHour]=\"dayEndHour\"\n [hourSegments]=\"hourSegments\"\n [eventTemplate]=\"eventTemplate\"\n [hourSegmentTemplate]=\"hourSegmentTemplate\"\n (eventClicked)=\"selectEvent.emit($event.event)\"\n (eventTimesChanged)=\"eventTimesChanged($event)\"\n (hourSegmentClicked)=\"dateIsValid($event.date) ? selectSlot.emit($event.date) : null\"\n (beforeViewRender)=\"beforeWeekOrDayViewRender($event)\"\n >\n </mwl-calendar-day-view>\n }\n }\n </div>\n</div>\n", styles: [".agenda{margin-top:15px}.agenda ion-col.titleCol{padding-left:8px}.agenda ion-col.titleCol h2,.agenda ion-col.titleCol p{margin:0}.agenda ion-col.titleCol h2{font-size:1.2em}.agenda ion-col.titleCol p{font-size:.8em;font-style:italic}.agenda .calendarViewSelector{background-color:transparent;--ion-background-color: transparent;--background: transparent}.agenda .calendarViewSelector ion-select{max-width:100%;width:100%;padding-left:0;font-weight:500}.agenda .eventGadgets{margin-top:4px;margin-left:5px;text-align:right}.agenda .eventGadgets idea-user-avatar{display:block;float:left;margin:2px 1px}.agenda .eventGadgets ion-icon{padding-right:2px;opacity:.7;font-size:1.15em}@media only screen and (max-width: 575px){.agenda ion-col.titleCol{padding:0 8px 12px;text-align:center}}\n"] }]
|
|
278
|
+
}], propDecorators: { events: [{
|
|
321
279
|
type: Input
|
|
322
280
|
}], excludeDays: [{
|
|
323
281
|
type: Input
|
|
@@ -389,14 +347,13 @@ const ceilToNearest = (amount, precision) => Math.ceil(amount / precision) * pre
|
|
|
389
347
|
* In both cases, the value should be set to `http://localhost:8100` (or according to the local URL).
|
|
390
348
|
*/
|
|
391
349
|
class IDEACalendarsService {
|
|
392
|
-
constructor(
|
|
393
|
-
this.
|
|
394
|
-
this.
|
|
395
|
-
this.
|
|
396
|
-
this.
|
|
397
|
-
this.
|
|
398
|
-
this.
|
|
399
|
-
this.env = inject(IDEAEnvironment);
|
|
350
|
+
constructor() {
|
|
351
|
+
this._env = inject(IDEAEnvironment);
|
|
352
|
+
this._modal = inject(ModalController);
|
|
353
|
+
this._alert = inject(AlertController);
|
|
354
|
+
this._loading = inject(IDEALoadingService);
|
|
355
|
+
this._API = inject(IDEAAWSAPIService);
|
|
356
|
+
this._translate = inject(IDEATranslationsService);
|
|
400
357
|
}
|
|
401
358
|
/**
|
|
402
359
|
* Get the ion-icon of an external service from its name.
|
|
@@ -420,184 +377,140 @@ class IDEACalendarsService {
|
|
|
420
377
|
/**
|
|
421
378
|
* Create a new calendar.
|
|
422
379
|
*/
|
|
423
|
-
postCalendar(cal) {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
.then((res) => resolve(new Calendar(res)))
|
|
427
|
-
.catch(err => reject(err));
|
|
428
|
-
});
|
|
380
|
+
async postCalendar(cal) {
|
|
381
|
+
const calendar = await this._API.postResource(this.getRequestURL(cal), { idea: true, body: cal });
|
|
382
|
+
return new Calendar(calendar);
|
|
429
383
|
}
|
|
430
384
|
/**
|
|
431
385
|
* Update an existing calendar.
|
|
432
386
|
*/
|
|
433
|
-
putCalendar(cal) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
.catch(err => reject(err));
|
|
438
|
-
});
|
|
387
|
+
async putCalendar(cal) {
|
|
388
|
+
const body = { idea: true, resourceId: cal.calendarId, body: cal };
|
|
389
|
+
const calendar = await this._API.putResource(this.getRequestURL(cal), body);
|
|
390
|
+
return new Calendar(calendar);
|
|
439
391
|
}
|
|
440
392
|
/**
|
|
441
393
|
* Delete a calendar.
|
|
442
394
|
*/
|
|
443
|
-
deleteCalendar(cal) {
|
|
444
|
-
|
|
445
|
-
this.API.deleteResource(this.getRequestURL(cal), { idea: true, resourceId: cal.calendarId })
|
|
446
|
-
.then(() => resolve())
|
|
447
|
-
.catch(err => reject(err));
|
|
448
|
-
});
|
|
395
|
+
async deleteCalendar(cal) {
|
|
396
|
+
await this._API.deleteResource(this.getRequestURL(cal), { idea: true, resourceId: cal.calendarId });
|
|
449
397
|
}
|
|
450
398
|
/**
|
|
451
399
|
* Associate an external calendar with the given calendar.
|
|
452
400
|
*/
|
|
453
|
-
setExternalCalendar(cal, externalId) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
resourceId: cal.calendarId,
|
|
458
|
-
body: { action: 'SET_EXTERNAL_CALENDAR', externalId }
|
|
459
|
-
})
|
|
460
|
-
.then(res => resolve(new Calendar(res)))
|
|
461
|
-
.catch(err => reject(err));
|
|
462
|
-
});
|
|
401
|
+
async setExternalCalendar(cal, externalId) {
|
|
402
|
+
const body = { idea: true, resourceId: cal.calendarId, body: { action: 'SET_EXTERNAL_CALENDAR', externalId } };
|
|
403
|
+
const calendar = await this._API.patchResource(this.getRequestURL(cal), body);
|
|
404
|
+
return new Calendar(calendar);
|
|
463
405
|
}
|
|
464
406
|
/**
|
|
465
407
|
* Link the calendar with the chosen external service (auth flow).
|
|
466
408
|
*/
|
|
467
|
-
linkExtService(cal) {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
.then(alert => alert.present());
|
|
509
|
-
});
|
|
409
|
+
async linkExtService(cal) {
|
|
410
|
+
if (!cal.external)
|
|
411
|
+
throw new Error('NOT_EXTERNAL');
|
|
412
|
+
const baseURL = window.location.protocol.concat('//', window.location.hostname);
|
|
413
|
+
let url;
|
|
414
|
+
switch (cal.external.service) {
|
|
415
|
+
case ExternalCalendarSources.GOOGLE:
|
|
416
|
+
url =
|
|
417
|
+
'https://accounts.google.com/o/oauth2/v2/auth?' +
|
|
418
|
+
`client_id=${encodeURIComponent(this._env.google.apiClientId)}` +
|
|
419
|
+
'&response_type=code' +
|
|
420
|
+
`&redirect_uri=${encodeURIComponent(baseURL.concat('/echo/google-calendars-integration'))}` +
|
|
421
|
+
'&include_granted_scopes=true' +
|
|
422
|
+
'&access_type=offline&prompt=consent' +
|
|
423
|
+
`&scope=${encodeURIComponent(this._env.google.apiScope)}` +
|
|
424
|
+
`&state=${encodeURIComponent(cal.calendarId)}`;
|
|
425
|
+
break;
|
|
426
|
+
case ExternalCalendarSources.MICROSOFT:
|
|
427
|
+
url =
|
|
428
|
+
'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?' +
|
|
429
|
+
`client_id=${encodeURIComponent(this._env.microsoft.apiClientId)}` +
|
|
430
|
+
'&response_type=code' +
|
|
431
|
+
`&redirect_uri=${encodeURIComponent(baseURL.concat('/echo/microsoft-calendars-integration'))}` +
|
|
432
|
+
'&response_mode=query' +
|
|
433
|
+
`&scope=${encodeURIComponent(this._env.microsoft.apiScope)}` +
|
|
434
|
+
`&state=${encodeURIComponent(cal.calendarId)}`;
|
|
435
|
+
break;
|
|
436
|
+
}
|
|
437
|
+
if (!url)
|
|
438
|
+
throw new Error('INVALID_SERVICE');
|
|
439
|
+
await Browser.open({ url });
|
|
440
|
+
// since we don't know when/if the auth flow will finish, we wait
|
|
441
|
+
await this.showAlertLinkingCalendar();
|
|
442
|
+
}
|
|
443
|
+
async showAlertLinkingCalendar() {
|
|
444
|
+
return new Promise(async (resolve) => {
|
|
445
|
+
const header = this._translate._('IDEA_AGENDA.CALENDARS.LINKING_CALENDAR');
|
|
446
|
+
const message = this._translate._('IDEA_AGENDA.CALENDARS.LINKING_CALENDAR_CONFIRM_ONCE_DONE');
|
|
447
|
+
const buttons = [{ text: this._translate._('COMMON.DONE'), handler: resolve }];
|
|
448
|
+
const alert = await this._alert.create({ header, message, buttons, backdropDismiss: false });
|
|
449
|
+
alert.present();
|
|
510
450
|
});
|
|
511
451
|
}
|
|
512
452
|
/**
|
|
513
453
|
* Get the external calendars list of the external service.
|
|
514
454
|
*/
|
|
515
|
-
getExternalCalendars(cal) {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
})
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
case ExternalCalendarSources.GOOGLE:
|
|
531
|
-
this.API.rawRequest()
|
|
532
|
-
.get('https://www.googleapis.com/calendar/v3/users/me/calendarList', { headers })
|
|
533
|
-
.toPromise()
|
|
534
|
-
.then((res) => resolve(res.items.map((c) => ({ name: c.summary, id: c.id }))))
|
|
535
|
-
.catch(err => reject(err));
|
|
536
|
-
break;
|
|
537
|
-
case ExternalCalendarSources.MICROSOFT:
|
|
538
|
-
this.API.rawRequest()
|
|
539
|
-
.get('https://graph.microsoft.com/v1.0/me/calendars', { headers })
|
|
540
|
-
.toPromise()
|
|
541
|
-
.then((res) => resolve(res.value.map((c) => ({ name: c.name, id: c.id }))))
|
|
542
|
-
.catch(err => reject(err));
|
|
543
|
-
break;
|
|
544
|
-
}
|
|
545
|
-
})
|
|
546
|
-
.catch(err => reject(err));
|
|
547
|
-
});
|
|
455
|
+
async getExternalCalendars(cal) {
|
|
456
|
+
if (!cal.external)
|
|
457
|
+
throw new Error('NOT_EXTERNAL');
|
|
458
|
+
// get the access token to make requests; in case it fails, proceed to link the external service
|
|
459
|
+
const body = { idea: true, resourceId: cal.calendarId, body: { action: 'GET_ACCESS_TOKEN' } };
|
|
460
|
+
const result = await this._API.patchResource(this.getRequestURL(cal), body);
|
|
461
|
+
const headers = { Authorization: 'Bearer '.concat(result.token) };
|
|
462
|
+
if (cal.external.service === ExternalCalendarSources.GOOGLE) {
|
|
463
|
+
const res = await (await fetch('https://www.googleapis.com/calendar/v3/users/me/calendarList', { headers })).json();
|
|
464
|
+
return res.items.map((c) => ({ name: c.summary, id: c.id }));
|
|
465
|
+
}
|
|
466
|
+
else if (cal.external.service === ExternalCalendarSources.MICROSOFT) {
|
|
467
|
+
const res = await (await fetch('https://graph.microsoft.com/v1.0/me/calendars', { headers })).json();
|
|
468
|
+
return res.value.map((c) => ({ name: c.name, id: c.id }));
|
|
469
|
+
}
|
|
548
470
|
}
|
|
549
471
|
/**
|
|
550
472
|
* If the external service is linked, choose an external calendar and set it for the chosen calendar.
|
|
551
473
|
* @return the updated calendar.
|
|
552
474
|
*/
|
|
553
|
-
chooseAndSetExternalCalendar(cal) {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
if (!extCalId)
|
|
559
|
-
return resolve(null);
|
|
560
|
-
// an external calendar was chosen: set it right away
|
|
561
|
-
this.setExternalCalendar(cal, extCalId)
|
|
562
|
-
.then(res => resolve(res))
|
|
563
|
-
.catch(err => reject(err));
|
|
564
|
-
})
|
|
565
|
-
.catch(err => reject(err));
|
|
566
|
-
});
|
|
475
|
+
async chooseAndSetExternalCalendar(cal) {
|
|
476
|
+
const extCalId = await this.openModalAndPickExternalCalendar(cal);
|
|
477
|
+
if (!extCalId)
|
|
478
|
+
return;
|
|
479
|
+
return await this.setExternalCalendar(cal, extCalId);
|
|
567
480
|
}
|
|
568
481
|
/**
|
|
569
482
|
* Open the modal to pick a calendar from the external service.
|
|
570
483
|
* @return the id of the external calendar.
|
|
571
484
|
*/
|
|
572
485
|
async openModalAndPickExternalCalendar(cal) {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
this.
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
})
|
|
598
|
-
.catch(err => reject(err))
|
|
599
|
-
.finally(() => this.loading.hide());
|
|
486
|
+
let extCals;
|
|
487
|
+
try {
|
|
488
|
+
await this._loading.show();
|
|
489
|
+
extCals = await this.getExternalCalendars(cal);
|
|
490
|
+
if (!extCals.length)
|
|
491
|
+
throw new Error('NO_EXTERNAL_CALENDARS');
|
|
492
|
+
}
|
|
493
|
+
catch (error) {
|
|
494
|
+
throw error;
|
|
495
|
+
}
|
|
496
|
+
finally {
|
|
497
|
+
this._loading.hide();
|
|
498
|
+
}
|
|
499
|
+
const modal = await this._modal.create({
|
|
500
|
+
component: IDEASuggestionsComponent,
|
|
501
|
+
componentProps: {
|
|
502
|
+
data: extCals.map(c => new Suggestion({ value: c.id, name: c.name })),
|
|
503
|
+
searchPlaceholder: this._translate._('IDEA_AGENDA.CALENDARS.CHOOSE_AN_EXTERNAL_CALENDAR_TO_LINK'),
|
|
504
|
+
sortData: true,
|
|
505
|
+
hideIdFromUI: true,
|
|
506
|
+
hideClearButton: true,
|
|
507
|
+
mustChoose: true
|
|
508
|
+
},
|
|
509
|
+
backdropDismiss: false
|
|
600
510
|
});
|
|
511
|
+
modal.present();
|
|
512
|
+
const res = await modal.onDidDismiss();
|
|
513
|
+
return res.data ? res.data.value : null;
|
|
601
514
|
}
|
|
602
515
|
/**
|
|
603
516
|
* First sync of the extenal calendar.
|
|
@@ -610,7 +523,8 @@ class IDEACalendarsService {
|
|
|
610
523
|
*/
|
|
611
524
|
syncCalendarHelper(cal, done) {
|
|
612
525
|
// this is a recursive operation: the API returns if the sync has to continue or it finished
|
|
613
|
-
this.
|
|
526
|
+
this._API
|
|
527
|
+
.patchResource(this.getRequestURL(cal), {
|
|
614
528
|
idea: true,
|
|
615
529
|
resourceId: cal.calendarId,
|
|
616
530
|
body: { action: 'SYNC_EXTERNAL_CALENDAR', firstSync: true }
|
|
@@ -623,123 +537,105 @@ class IDEACalendarsService {
|
|
|
623
537
|
})
|
|
624
538
|
.catch(err => done(err));
|
|
625
539
|
}
|
|
626
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
627
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
540
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEACalendarsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
541
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEACalendarsService }); }
|
|
628
542
|
}
|
|
629
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
543
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEACalendarsService, decorators: [{
|
|
630
544
|
type: Injectable
|
|
631
|
-
}]
|
|
545
|
+
}] });
|
|
632
546
|
|
|
633
547
|
class IDEACalendarComponent {
|
|
634
|
-
constructor(
|
|
635
|
-
this.calendars = calendars;
|
|
636
|
-
this.modalCtrl = modalCtrl;
|
|
637
|
-
this.alertCtrl = alertCtrl;
|
|
638
|
-
this.tc = tc;
|
|
639
|
-
this.loading = loading;
|
|
640
|
-
this.message = message;
|
|
641
|
-
this.API = API;
|
|
642
|
-
this.t = t;
|
|
643
|
-
/**
|
|
644
|
-
* Errors while validating the entity.
|
|
645
|
-
*/
|
|
548
|
+
constructor() {
|
|
646
549
|
this.errors = new Set();
|
|
647
|
-
/**
|
|
648
|
-
* The default color for a calendar.
|
|
649
|
-
*/
|
|
650
550
|
this.DEFAULT_COLOR = '#555';
|
|
551
|
+
this._calendars = inject(IDEACalendarsService);
|
|
552
|
+
this._modal = inject(ModalController);
|
|
553
|
+
this._alert = inject(AlertController);
|
|
554
|
+
this._tc = inject(IDEATinCanService);
|
|
555
|
+
this._loading = inject(IDEALoadingService);
|
|
556
|
+
this._message = inject(IDEAMessageService);
|
|
557
|
+
this._API = inject(IDEAAWSAPIService);
|
|
558
|
+
this._translate = inject(IDEATranslationsService);
|
|
559
|
+
}
|
|
560
|
+
async ngOnInit() {
|
|
561
|
+
this.membership = this._tc.get('membership');
|
|
562
|
+
this.calendarWC = new Calendar(this.calendar);
|
|
563
|
+
try {
|
|
564
|
+
const memberships = await this._API.getResource(`teams/${this.membership.teamId}/memberships`);
|
|
565
|
+
this.membershipsChecks = memberships.map(m => new Check({
|
|
566
|
+
value: m.userId,
|
|
567
|
+
name: m.name,
|
|
568
|
+
checked: (this.calendarWC.usersCanManageAppointments || []).some(x => x === m.userId)
|
|
569
|
+
}));
|
|
570
|
+
}
|
|
571
|
+
catch (error) {
|
|
572
|
+
this._message.error('COMMON.COULDNT_LOAD_LIST');
|
|
573
|
+
}
|
|
651
574
|
}
|
|
652
|
-
ngOnInit() {
|
|
653
|
-
this.membership = this.tc.get('membership');
|
|
654
|
-
// work on a copy
|
|
655
|
-
this._calendar = new Calendar(this.calendar);
|
|
656
|
-
// load the teammates to use for shared calendars permissions
|
|
657
|
-
this.API.getResource(`teams/${this.membership.teamId}/memberships`)
|
|
658
|
-
.then((memberships) => (this.membershipsChecks = memberships.map(m => new Check({
|
|
659
|
-
value: m.userId,
|
|
660
|
-
name: m.name,
|
|
661
|
-
checked: (this._calendar.usersCanManageAppointments || []).some(x => x === m.userId)
|
|
662
|
-
}))))
|
|
663
|
-
.catch(() => { });
|
|
664
|
-
}
|
|
665
|
-
/**
|
|
666
|
-
* Set the support array to display errors in the UI.
|
|
667
|
-
*/
|
|
668
575
|
hasFieldAnError(field) {
|
|
669
576
|
return this.errors.has(field);
|
|
670
577
|
}
|
|
671
|
-
/**
|
|
672
|
-
* Save a calendar with the new info.
|
|
673
|
-
*/
|
|
674
578
|
async save() {
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
if (this._calendar.isShared() && this.advancedPermissions)
|
|
680
|
-
this._calendar.usersCanManageAppointments = this.membershipsChecks
|
|
579
|
+
if (!this.calendarWC.color)
|
|
580
|
+
this.calendarWC.color = this.DEFAULT_COLOR;
|
|
581
|
+
if (this.calendarWC.isShared() && this.advancedPermissions)
|
|
582
|
+
this.calendarWC.usersCanManageAppointments = this.membershipsChecks
|
|
681
583
|
.filter(x => x.checked)
|
|
682
584
|
.map(x => String(x.value));
|
|
683
585
|
else
|
|
684
|
-
delete this.
|
|
685
|
-
|
|
686
|
-
this.errors = new Set(this._calendar.validate());
|
|
586
|
+
delete this.calendarWC.usersCanManageAppointments;
|
|
587
|
+
this.errors = new Set(this.calendarWC.validate());
|
|
687
588
|
if (this.errors.size)
|
|
688
|
-
return this.
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
.putCalendar(this._calendar)
|
|
693
|
-
.then((res) => {
|
|
589
|
+
return this._message.error('COMMON.FORM_HAS_ERROR_TO_CHECK');
|
|
590
|
+
try {
|
|
591
|
+
await this._loading.show();
|
|
592
|
+
const res = await this._calendars.putCalendar(this.calendarWC);
|
|
694
593
|
this.calendar.load(res);
|
|
695
|
-
this.
|
|
696
|
-
this.
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
|
|
594
|
+
this._message.success('IDEA_AGENDA.CALENDARS.CALENDAR_SAVED');
|
|
595
|
+
this._modal.dismiss(this.calendar);
|
|
596
|
+
}
|
|
597
|
+
catch (error) {
|
|
598
|
+
this._message.error('COMMON.OPERATION_FAILED');
|
|
599
|
+
}
|
|
600
|
+
finally {
|
|
601
|
+
this._loading.hide();
|
|
602
|
+
}
|
|
700
603
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
}
|
|
726
|
-
]
|
|
727
|
-
})
|
|
728
|
-
.then(alert => alert.present());
|
|
604
|
+
async delete() {
|
|
605
|
+
const doDelete = async () => {
|
|
606
|
+
try {
|
|
607
|
+
await this._loading.show();
|
|
608
|
+
await this._calendars.deleteCalendar(this.calendarWC);
|
|
609
|
+
this._message.success('IDEA_AGENDA.CALENDARS.CALENDAR_DELETED');
|
|
610
|
+
this._modal.dismiss(true);
|
|
611
|
+
}
|
|
612
|
+
catch (error) {
|
|
613
|
+
this._message.error('COMMON.OPERATION_FAILED');
|
|
614
|
+
}
|
|
615
|
+
finally {
|
|
616
|
+
this._loading.hide();
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
const header = this._translate._('COMMON.ARE_YOU_SURE');
|
|
620
|
+
const subHeader = this._translate._('IDEA_AGENDA.CALENDARS.DELETE_CALENDAR');
|
|
621
|
+
const message = this._translate._('IDEA_AGENDA.CALENDARS.DELETE_CALENDAR_HINT');
|
|
622
|
+
const buttons = [
|
|
623
|
+
{ text: this._translate._('COMMON.CANCEL'), role: 'cancel' },
|
|
624
|
+
{ text: this._translate._('COMMON.DELETE'), handler: doDelete }
|
|
625
|
+
];
|
|
626
|
+
const alert = await this._alert.create({ header, subHeader, message, buttons });
|
|
627
|
+
alert.present();
|
|
729
628
|
}
|
|
730
|
-
/**
|
|
731
|
-
* Close the component.
|
|
732
|
-
*/
|
|
733
629
|
close() {
|
|
734
|
-
this.
|
|
630
|
+
this._modal.dismiss();
|
|
735
631
|
}
|
|
736
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
737
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
632
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEACalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
633
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.1", type: IDEACalendarComponent, selector: "idea-calendar", inputs: { calendar: "calendar", advancedPermissions: "advancedPermissions", hideColor: "hideColor" }, ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"ideaToolbar\">\n <ion-buttons slot=\"start\">\n <ion-button [title]=\"'COMMON.CLOSE' | translate\" (click)=\"close()\">\n <ion-icon name=\"close-circle\" slot=\"icon-only\" />\n </ion-button>\n </ion-buttons>\n <ion-title>{{ 'IDEA_AGENDA.CALENDARS.EDIT_CALENDAR' | translate }}</ion-title>\n <ion-buttons slot=\"end\">\n <ion-button [title]=\"'COMMON.SAVE' | translate\" (click)=\"save()\">\n <ion-icon name=\"checkmark-circle\" slot=\"icon-only\" />\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n<ion-content>\n @if (calendarWC) {\n <div class=\"maxWidthContainer\">\n <ion-list class=\"aList\">\n <ion-item\n lines=\"inset\"\n [class.fieldHasError]=\"hasFieldAnError('name')\"\n [title]=\"'IDEA_AGENDA.CALENDARS.NAME_HINT' | translate\"\n >\n <ion-input\n labelPlacement=\"stacked\"\n [label]=\"'IDEA_AGENDA.CALENDARS.NAME' | translate\"\n [placeholder]=\"'IDEA_AGENDA.CALENDARS.NAME_HINT' | translate\"\n [(ngModel)]=\"calendarWC.name\"\n />\n </ion-item>\n <ion-item\n lines=\"inset\"\n [class.fieldHasError]=\"hasFieldAnError('description')\"\n [title]=\"'IDEA_AGENDA.CALENDARS.DESCRIPTION_HINT' | translate\"\n >\n <ion-input\n labelPlacement=\"stacked\"\n [label]=\"'IDEA_AGENDA.CALENDARS.DESCRIPTION' | translate\"\n [placeholder]=\"'IDEA_AGENDA.CALENDARS.DESCRIPTION_HINT' | translate\"\n [(ngModel)]=\"calendarWC.description\"\n />\n </ion-item>\n @if (!hideColor) {\n <idea-color-picker\n [lines]=\"'inset'\"\n [current]=\"calendarWC.color\"\n [label]=\"'IDEA_AGENDA.CALENDARS.COLOR' | translate\"\n [class.fieldHasError]=\"hasFieldAnError('color')\"\n (select)=\"$event ? (calendarWC.color = $event) : null\"\n />\n }\n @if (membershipsChecks && calendarWC.isShared() && advancedPermissions) {\n <idea-checker\n [data]=\"membershipsChecks\"\n [label]=\"'IDEA_AGENDA.CALENDARS.USERS_ALLOWED_TO_MANAGE_APPOINTMENTS' | translate\"\n [searchPlaceholder]=\"'IDEA_AGENDA.CALENDARS.WHO_CAN_MANAGE_APPOINTMENTS' | translate\"\n [noneText]=\"'IDEA_AGENDA.CALENDARS.NOBODY' | translate\"\n [allText]=\"'IDEA_AGENDA.CALENDARS.EVERYONE' | translate\"\n [allowSelectDeselectAll]=\"true\"\n [lines]=\"'inset'\"\n />\n }\n </ion-list>\n @if (calendarWC.external?.service) {\n <ion-list class=\"aList\">\n <ion-list-header>\n <ion-label>\n <h2>{{ 'IDEA_AGENDA.CALENDARS.INFO_ON_CALENDAR' | translate }}</h2>\n </ion-label>\n </ion-list-header>\n @if (calendar.userId) {\n <ion-item lines=\"inset\">\n <ion-label>\n {{ 'IDEA_AGENDA.CALENDARS.PRIVATE_CALENDAR' | translate }}\n <p>{{ 'IDEA_AGENDA.CALENDARS.PRIVATE_CALENDAR_HINT' | translate }}</p>\n </ion-label>\n <ion-icon slot=\"end\" name=\"person\" />\n </ion-item>\n }\n @if (calendar.teamId) {\n <ion-item lines=\"inset\">\n <ion-label>\n {{ 'IDEA_AGENDA.CALENDARS.TEAM_CALENDAR' | translate }}\n <p>{{ 'IDEA_AGENDA.CALENDARS.TEAM_CALENDAR_HINT' | translate }}</p>\n </ion-label>\n <ion-icon slot=\"end\" name=\"people\" />\n </ion-item>\n }\n <ion-item lines=\"inset\">\n <ion-label>\n {{ 'IDEA_AGENDA.CALENDARS.LINKED_TO' | translate }}\n {{ 'IDEA_AGENDA.CALENDARS.SERVICES.' + calendarWC.external.service | translate }}\n <p>{{ calendarWC.external.name }} ({{ calendarWC.external.email }})</p>\n </ion-label>\n <ion-icon slot=\"end\" [name]=\"calendars.getServiceIcon(calendarWC.external.service)\" />\n </ion-item>\n <ion-item lines=\"inset\">\n <ion-label>\n {{ 'IDEA_AGENDA.CALENDARS.ACCESS_LEVELS.' + calendarWC.external.userAccess | translate }}\n <p>{{ 'IDEA_AGENDA.CALENDARS.BASED_ON_EXTERNAL_SERVICE_SHARING_PERMISSION' | translate }}</p>\n </ion-label>\n <ion-icon slot=\"end\" name=\"shield\" />\n </ion-item>\n </ion-list>\n }\n <ion-list class=\"aList\">\n <ion-list-header>\n <ion-label color=\"danger\">\n <h2>{{ 'IDEA_AGENDA.CALENDARS.DANGEROUS_ZONE' | translate }}</h2>\n </ion-label>\n </ion-list-header>\n <ion-item lines=\"inset\">\n <ion-label class=\"ion-text-wrap\">\n {{ 'IDEA_AGENDA.CALENDARS.DELETE_CALENDAR' | translate }}\n <p>{{ 'IDEA_AGENDA.CALENDARS.DELETE_CALENDAR_HINT' | translate }}</p>\n </ion-label>\n <ion-button\n color=\"danger\"\n [title]=\"'IDEA_AGENDA.CALENDARS.DELETE_CALENDAR_HINT' | translate\"\n (click)=\"delete()\"\n >\n {{ 'COMMON.DELETE' | translate }}\n </ion-button>\n </ion-item>\n </ion-list>\n </div>\n }\n</ion-content>\n", styles: [".maxWidthContainer{max-width:500px;padding-top:20px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonInput, selector: "ion-input", inputs: ["autocapitalize", "autocomplete", "autocorrect", "autofocus", "clearInput", "clearInputIcon", "clearOnEdit", "color", "counter", "counterFormatter", "debounce", "disabled", "enterkeyhint", "errorText", "fill", "helperText", "inputmode", "label", "labelPlacement", "max", "maxlength", "min", "minlength", "mode", "multiple", "name", "pattern", "placeholder", "readonly", "required", "shape", "spellcheck", "step", "type", "value"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: i2.IonListHeader, selector: "ion-list-header", inputs: ["color", "lines", "mode"] }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "directive", type: i2.TextValueAccessor, selector: "ion-input:not([type=number]),ion-textarea,ion-searchbar" }, { kind: "component", type: i3.IDEAColorPickerComponent, selector: "idea-color-picker", inputs: ["colors", "current", "label", "placeholder", "icon", "iconColor", "disabled", "obligatory", "lines", "color"], outputs: ["select", "iconSelect"] }, { kind: "component", type: i3.IDEACheckerComponent, selector: "idea-checker", inputs: ["data", "dataProvider", "label", "icon", "iconColor", "searchPlaceholder", "noPreviewText", "noElementsFoundText", "noneEqualsAll", "noneText", "allText", "lines", "color", "disabled", "tappableWhenDisabled", "obligatory", "sortData", "numMaxElementsInPreview", "showAvatars", "limitSelectionToNum", "allowSelectDeselectAll", "category1", "category2", "showCategoriesFilters"], outputs: ["change", "iconSelect"] }, { kind: "pipe", type: i3.IDEATranslatePipe, name: "translate" }] }); }
|
|
738
634
|
}
|
|
739
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
635
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEACalendarComponent, decorators: [{
|
|
740
636
|
type: Component,
|
|
741
|
-
args: [{ selector: 'idea-calendar', template: "<ion-header>\n <ion-toolbar color=\"ideaToolbar\">\n <ion-buttons slot=\"start\">\n <ion-button [title]=\"
|
|
742
|
-
}],
|
|
637
|
+
args: [{ selector: 'idea-calendar', template: "<ion-header>\n <ion-toolbar color=\"ideaToolbar\">\n <ion-buttons slot=\"start\">\n <ion-button [title]=\"'COMMON.CLOSE' | translate\" (click)=\"close()\">\n <ion-icon name=\"close-circle\" slot=\"icon-only\" />\n </ion-button>\n </ion-buttons>\n <ion-title>{{ 'IDEA_AGENDA.CALENDARS.EDIT_CALENDAR' | translate }}</ion-title>\n <ion-buttons slot=\"end\">\n <ion-button [title]=\"'COMMON.SAVE' | translate\" (click)=\"save()\">\n <ion-icon name=\"checkmark-circle\" slot=\"icon-only\" />\n </ion-button>\n </ion-buttons>\n </ion-toolbar>\n</ion-header>\n<ion-content>\n @if (calendarWC) {\n <div class=\"maxWidthContainer\">\n <ion-list class=\"aList\">\n <ion-item\n lines=\"inset\"\n [class.fieldHasError]=\"hasFieldAnError('name')\"\n [title]=\"'IDEA_AGENDA.CALENDARS.NAME_HINT' | translate\"\n >\n <ion-input\n labelPlacement=\"stacked\"\n [label]=\"'IDEA_AGENDA.CALENDARS.NAME' | translate\"\n [placeholder]=\"'IDEA_AGENDA.CALENDARS.NAME_HINT' | translate\"\n [(ngModel)]=\"calendarWC.name\"\n />\n </ion-item>\n <ion-item\n lines=\"inset\"\n [class.fieldHasError]=\"hasFieldAnError('description')\"\n [title]=\"'IDEA_AGENDA.CALENDARS.DESCRIPTION_HINT' | translate\"\n >\n <ion-input\n labelPlacement=\"stacked\"\n [label]=\"'IDEA_AGENDA.CALENDARS.DESCRIPTION' | translate\"\n [placeholder]=\"'IDEA_AGENDA.CALENDARS.DESCRIPTION_HINT' | translate\"\n [(ngModel)]=\"calendarWC.description\"\n />\n </ion-item>\n @if (!hideColor) {\n <idea-color-picker\n [lines]=\"'inset'\"\n [current]=\"calendarWC.color\"\n [label]=\"'IDEA_AGENDA.CALENDARS.COLOR' | translate\"\n [class.fieldHasError]=\"hasFieldAnError('color')\"\n (select)=\"$event ? (calendarWC.color = $event) : null\"\n />\n }\n @if (membershipsChecks && calendarWC.isShared() && advancedPermissions) {\n <idea-checker\n [data]=\"membershipsChecks\"\n [label]=\"'IDEA_AGENDA.CALENDARS.USERS_ALLOWED_TO_MANAGE_APPOINTMENTS' | translate\"\n [searchPlaceholder]=\"'IDEA_AGENDA.CALENDARS.WHO_CAN_MANAGE_APPOINTMENTS' | translate\"\n [noneText]=\"'IDEA_AGENDA.CALENDARS.NOBODY' | translate\"\n [allText]=\"'IDEA_AGENDA.CALENDARS.EVERYONE' | translate\"\n [allowSelectDeselectAll]=\"true\"\n [lines]=\"'inset'\"\n />\n }\n </ion-list>\n @if (calendarWC.external?.service) {\n <ion-list class=\"aList\">\n <ion-list-header>\n <ion-label>\n <h2>{{ 'IDEA_AGENDA.CALENDARS.INFO_ON_CALENDAR' | translate }}</h2>\n </ion-label>\n </ion-list-header>\n @if (calendar.userId) {\n <ion-item lines=\"inset\">\n <ion-label>\n {{ 'IDEA_AGENDA.CALENDARS.PRIVATE_CALENDAR' | translate }}\n <p>{{ 'IDEA_AGENDA.CALENDARS.PRIVATE_CALENDAR_HINT' | translate }}</p>\n </ion-label>\n <ion-icon slot=\"end\" name=\"person\" />\n </ion-item>\n }\n @if (calendar.teamId) {\n <ion-item lines=\"inset\">\n <ion-label>\n {{ 'IDEA_AGENDA.CALENDARS.TEAM_CALENDAR' | translate }}\n <p>{{ 'IDEA_AGENDA.CALENDARS.TEAM_CALENDAR_HINT' | translate }}</p>\n </ion-label>\n <ion-icon slot=\"end\" name=\"people\" />\n </ion-item>\n }\n <ion-item lines=\"inset\">\n <ion-label>\n {{ 'IDEA_AGENDA.CALENDARS.LINKED_TO' | translate }}\n {{ 'IDEA_AGENDA.CALENDARS.SERVICES.' + calendarWC.external.service | translate }}\n <p>{{ calendarWC.external.name }} ({{ calendarWC.external.email }})</p>\n </ion-label>\n <ion-icon slot=\"end\" [name]=\"calendars.getServiceIcon(calendarWC.external.service)\" />\n </ion-item>\n <ion-item lines=\"inset\">\n <ion-label>\n {{ 'IDEA_AGENDA.CALENDARS.ACCESS_LEVELS.' + calendarWC.external.userAccess | translate }}\n <p>{{ 'IDEA_AGENDA.CALENDARS.BASED_ON_EXTERNAL_SERVICE_SHARING_PERMISSION' | translate }}</p>\n </ion-label>\n <ion-icon slot=\"end\" name=\"shield\" />\n </ion-item>\n </ion-list>\n }\n <ion-list class=\"aList\">\n <ion-list-header>\n <ion-label color=\"danger\">\n <h2>{{ 'IDEA_AGENDA.CALENDARS.DANGEROUS_ZONE' | translate }}</h2>\n </ion-label>\n </ion-list-header>\n <ion-item lines=\"inset\">\n <ion-label class=\"ion-text-wrap\">\n {{ 'IDEA_AGENDA.CALENDARS.DELETE_CALENDAR' | translate }}\n <p>{{ 'IDEA_AGENDA.CALENDARS.DELETE_CALENDAR_HINT' | translate }}</p>\n </ion-label>\n <ion-button\n color=\"danger\"\n [title]=\"'IDEA_AGENDA.CALENDARS.DELETE_CALENDAR_HINT' | translate\"\n (click)=\"delete()\"\n >\n {{ 'COMMON.DELETE' | translate }}\n </ion-button>\n </ion-item>\n </ion-list>\n </div>\n }\n</ion-content>\n", styles: [".maxWidthContainer{max-width:500px;padding-top:20px}\n"] }]
|
|
638
|
+
}], propDecorators: { calendar: [{
|
|
743
639
|
type: Input
|
|
744
640
|
}], advancedPermissions: [{
|
|
745
641
|
type: Input
|
|
@@ -748,123 +644,104 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.0", ngImpor
|
|
|
748
644
|
}] } });
|
|
749
645
|
|
|
750
646
|
class IDEACalendarItemComponent {
|
|
751
|
-
constructor(
|
|
752
|
-
this.calendars = calendars;
|
|
753
|
-
this.alertCtrl = alertCtrl;
|
|
754
|
-
this.modalCtrl = modalCtrl;
|
|
755
|
-
this.message = message;
|
|
756
|
-
this.loading = loading;
|
|
757
|
-
this.t = t;
|
|
647
|
+
constructor() {
|
|
758
648
|
/**
|
|
759
649
|
* Report to parent components a change.
|
|
760
650
|
*/
|
|
761
651
|
this.somethingChanged = new EventEmitter();
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
652
|
+
this._alert = inject(AlertController);
|
|
653
|
+
this._modal = inject(ModalController);
|
|
654
|
+
this._message = inject(IDEAMessageService);
|
|
655
|
+
this._loading = inject(IDEALoadingService);
|
|
656
|
+
this._translate = inject(IDEATranslationsService);
|
|
657
|
+
this._calendars = inject(IDEACalendarsService);
|
|
658
|
+
}
|
|
659
|
+
async manageCalendar() {
|
|
767
660
|
if (this.disabled)
|
|
768
661
|
return;
|
|
769
|
-
this.
|
|
770
|
-
.create({
|
|
662
|
+
const modal = await this._modal.create({
|
|
771
663
|
component: IDEACalendarComponent,
|
|
772
664
|
componentProps: {
|
|
773
665
|
calendar: this.calendar,
|
|
774
666
|
advancedPermissions: this.advancedPermissions,
|
|
775
667
|
hideColor: this.hideColor
|
|
776
668
|
}
|
|
777
|
-
})
|
|
778
|
-
.then(modal => {
|
|
779
|
-
modal.onDidDismiss().then(res => {
|
|
780
|
-
const cal = res.data;
|
|
781
|
-
// nothing changed
|
|
782
|
-
if (cal === undefined)
|
|
783
|
-
return;
|
|
784
|
-
// the calendar was deleted
|
|
785
|
-
else if (cal === null)
|
|
786
|
-
this.calendar = null;
|
|
787
|
-
// the calendar was updated
|
|
788
|
-
else
|
|
789
|
-
this.calendar.load(cal);
|
|
790
|
-
// report changes to parent components
|
|
791
|
-
this.somethingChanged.emit();
|
|
792
|
-
});
|
|
793
|
-
modal.present();
|
|
794
669
|
});
|
|
670
|
+
modal.onDidDismiss().then(res => {
|
|
671
|
+
const cal = res.data;
|
|
672
|
+
if (cal === undefined)
|
|
673
|
+
return;
|
|
674
|
+
else if (cal === null)
|
|
675
|
+
this.calendar = null;
|
|
676
|
+
else
|
|
677
|
+
this.calendar.load(cal);
|
|
678
|
+
this.somethingChanged.emit();
|
|
679
|
+
});
|
|
680
|
+
modal.present();
|
|
795
681
|
}
|
|
796
|
-
|
|
797
|
-
* Continue the auth flow to link an external service and set an external calendar;
|
|
798
|
-
* otherwise, the calendar can be deleted.
|
|
799
|
-
*/
|
|
800
|
-
linkExtCalendarOrDelete() {
|
|
682
|
+
async linkExtCalendarOrDelete() {
|
|
801
683
|
if (this.disabled)
|
|
802
684
|
return;
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
.chooseAndSetExternalCalendar(this.calendar)
|
|
806
|
-
.then(async (cal) => {
|
|
685
|
+
try {
|
|
686
|
+
const cal = await this._calendars.chooseAndSetExternalCalendar(this.calendar);
|
|
807
687
|
if (!cal)
|
|
808
|
-
|
|
688
|
+
throw new Error('NO_EXTERNAL_CALENDAR_CHOSEN');
|
|
809
689
|
this.calendar.load(cal);
|
|
810
|
-
this.
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
.
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
.
|
|
818
|
-
|
|
819
|
-
|
|
690
|
+
this._message.success('IDEA_AGENDA.CALENDARS.CALENDAR_LINKED');
|
|
691
|
+
try {
|
|
692
|
+
await this._loading.show(this._translate._('IDEA_AGENDA.CALENDARS.FIRST_SYNC_MAY_TAKE_A_WHILE'));
|
|
693
|
+
await this._calendars.syncCalendar(this.calendar);
|
|
694
|
+
this._message.success('IDEA_AGENDA.CALENDARS.FIRST_SYNC_COMPLETED');
|
|
695
|
+
}
|
|
696
|
+
catch (error) {
|
|
697
|
+
this._message.error('COMMON.OPERATION_FAILED');
|
|
698
|
+
}
|
|
699
|
+
finally {
|
|
700
|
+
this._loading.hide();
|
|
820
701
|
this.somethingChanged.emit();
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
]
|
|
857
|
-
})
|
|
858
|
-
.then(alert => alert.present());
|
|
859
|
-
});
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
catch (error) {
|
|
705
|
+
const doDelete = async () => {
|
|
706
|
+
try {
|
|
707
|
+
await this._loading.show();
|
|
708
|
+
await this._calendars.deleteCalendar(this.calendar);
|
|
709
|
+
this._message.success('COMMON.OPERATION_COMPLETED');
|
|
710
|
+
this.somethingChanged.emit();
|
|
711
|
+
}
|
|
712
|
+
catch (error) {
|
|
713
|
+
this._message.error('COMMON.OPERATION_FAILED');
|
|
714
|
+
}
|
|
715
|
+
finally {
|
|
716
|
+
this._loading.hide();
|
|
717
|
+
}
|
|
718
|
+
};
|
|
719
|
+
const doLink = async () => {
|
|
720
|
+
try {
|
|
721
|
+
await this._calendars.linkExtService(this.calendar);
|
|
722
|
+
this.linkExtCalendarOrDelete();
|
|
723
|
+
}
|
|
724
|
+
catch (error) {
|
|
725
|
+
this._message.error('COMMON.OPERATION_FAILED');
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
const header = this._translate._('IDEA_AGENDA.CALENDARS.CALENDAR_NOT_YET_LINKED');
|
|
729
|
+
const message = this._translate._('IDEA_AGENDA.CALENDARS.DO_YOU_WANT_PROCEED_LINKING_OR_DELETE');
|
|
730
|
+
const buttons = [
|
|
731
|
+
{ text: this._translate._('COMMON.DELETE'), handler: doDelete },
|
|
732
|
+
{ text: this._translate._('IDEA_AGENDA.CALENDARS.LINK'), handler: doLink }
|
|
733
|
+
];
|
|
734
|
+
const alert = await this._alert.create({ header, message, buttons });
|
|
735
|
+
alert.present();
|
|
736
|
+
}
|
|
860
737
|
}
|
|
861
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
862
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
738
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEACalendarItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
739
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.1", type: IDEACalendarItemComponent, selector: "idea-calendar-item", inputs: { calendar: "calendar", disabled: "disabled", advancedPermissions: "advancedPermissions", hideColor: "hideColor" }, outputs: { somethingChanged: "somethingChanged" }, ngImport: i0, template: "@if (calendar) {\n <ion-item\n class=\"calendarItem\"\n [button]=\"!disabled\"\n [title]=\"'IDEA_AGENDA.CALENDARS.EDIT_CALENDAR' | translate\"\n (click)=\"calendar.external && !calendar.external.calendarId ? linkExtCalendarOrDelete() : manageCalendar()\"\n >\n @if (!hideColor) {\n <ion-avatar slot=\"start\" class=\"colorCircle\" [style.background-color]=\"calendar.color\" />\n }\n <ion-label>\n {{ calendar.name }}\n <p>\n @if (calendar.external && !calendar.external.calendarId) {\n <ion-text color=\"danger\">\n {{ 'IDEA_AGENDA.CALENDARS.TAP_TO_CONFIGURE' | translate }}\n </ion-text>\n }\n {{ calendar.description }}\n </p>\n </ion-label>\n @if (calendar.external && !calendar.external.calendarId) {\n <ion-icon\n slot=\"end\"\n color=\"danger\"\n name=\"flash-off\"\n [title]=\"'IDEA_AGENDA.CALENDARS.CALENDAR_NOT_YET_LINKED_HINT' | translate\"\n />\n }\n @if (calendar.external?.service) {\n <ion-icon\n slot=\"end\"\n [name]=\"calendars.getServiceIcon(calendar.external.service)\"\n [title]=\"\n ('IDEA_AGENDA.CALENDARS.LINKED_TO' | translate) +\n ' ' +\n ('IDEA_AGENDA.CALENDARS.SERVICES.' + calendar.external.service | translate)\n \"\n />\n }\n </ion-item>\n}\n", styles: [".calendarItem ion-avatar.colorCircle{width:20px;height:20px;background-color:#555}\n"], dependencies: [{ kind: "component", type: i2.IonAvatar, selector: "ion-avatar" }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i2.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "pipe", type: i3.IDEATranslatePipe, name: "translate" }] }); }
|
|
863
740
|
}
|
|
864
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
741
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEACalendarItemComponent, decorators: [{
|
|
865
742
|
type: Component,
|
|
866
|
-
args: [{ selector: 'idea-calendar-item', template: "<ion-item\n
|
|
867
|
-
}],
|
|
743
|
+
args: [{ selector: 'idea-calendar-item', template: "@if (calendar) {\n <ion-item\n class=\"calendarItem\"\n [button]=\"!disabled\"\n [title]=\"'IDEA_AGENDA.CALENDARS.EDIT_CALENDAR' | translate\"\n (click)=\"calendar.external && !calendar.external.calendarId ? linkExtCalendarOrDelete() : manageCalendar()\"\n >\n @if (!hideColor) {\n <ion-avatar slot=\"start\" class=\"colorCircle\" [style.background-color]=\"calendar.color\" />\n }\n <ion-label>\n {{ calendar.name }}\n <p>\n @if (calendar.external && !calendar.external.calendarId) {\n <ion-text color=\"danger\">\n {{ 'IDEA_AGENDA.CALENDARS.TAP_TO_CONFIGURE' | translate }}\n </ion-text>\n }\n {{ calendar.description }}\n </p>\n </ion-label>\n @if (calendar.external && !calendar.external.calendarId) {\n <ion-icon\n slot=\"end\"\n color=\"danger\"\n name=\"flash-off\"\n [title]=\"'IDEA_AGENDA.CALENDARS.CALENDAR_NOT_YET_LINKED_HINT' | translate\"\n />\n }\n @if (calendar.external?.service) {\n <ion-icon\n slot=\"end\"\n [name]=\"calendars.getServiceIcon(calendar.external.service)\"\n [title]=\"\n ('IDEA_AGENDA.CALENDARS.LINKED_TO' | translate) +\n ' ' +\n ('IDEA_AGENDA.CALENDARS.SERVICES.' + calendar.external.service | translate)\n \"\n />\n }\n </ion-item>\n}\n", styles: [".calendarItem ion-avatar.colorCircle{width:20px;height:20px;background-color:#555}\n"] }]
|
|
744
|
+
}], propDecorators: { calendar: [{
|
|
868
745
|
type: Input
|
|
869
746
|
}], disabled: [{
|
|
870
747
|
type: Input
|
|
@@ -877,127 +754,100 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.0", ngImpor
|
|
|
877
754
|
}] } });
|
|
878
755
|
|
|
879
756
|
class IDEACalendarCreationComponent {
|
|
880
|
-
constructor(
|
|
881
|
-
this.calendars = calendars;
|
|
882
|
-
this.modalCtrl = modalCtrl;
|
|
883
|
-
this.tc = tc;
|
|
884
|
-
this.loading = loading;
|
|
885
|
-
this.message = message;
|
|
886
|
-
this.API = API;
|
|
887
|
-
this.t = t;
|
|
888
|
-
/**
|
|
889
|
-
* The default color for a new calendar.
|
|
890
|
-
*/
|
|
757
|
+
constructor() {
|
|
891
758
|
this.DEFAULT_COLOR = '#555';
|
|
892
|
-
/**
|
|
893
|
-
* The possible external services for the new calendar.
|
|
894
|
-
*/
|
|
895
759
|
this.SOURCES = Object.keys(ExternalCalendarSources);
|
|
760
|
+
this._calendars = inject(IDEACalendarsService);
|
|
761
|
+
this._modal = inject(ModalController);
|
|
762
|
+
this._tc = inject(IDEATinCanService);
|
|
763
|
+
this._loading = inject(IDEALoadingService);
|
|
764
|
+
this._message = inject(IDEAMessageService);
|
|
765
|
+
this._translate = inject(IDEATranslationsService);
|
|
896
766
|
}
|
|
897
767
|
ngOnInit() {
|
|
898
768
|
this.calendar = new Calendar();
|
|
899
|
-
this.membership = this.
|
|
769
|
+
this.membership = this._tc.get('membership');
|
|
900
770
|
if (this.fixScope === CalendarScopes.SHARED)
|
|
901
771
|
this.calendar.teamId = this.membership.teamId;
|
|
902
772
|
if (this.fixScope === CalendarScopes.PRIVATE)
|
|
903
773
|
this.calendar.userId = this.membership.userId;
|
|
904
774
|
}
|
|
905
|
-
/**
|
|
906
|
-
* If allowed by the component configuration, reset the scope of the calendar (private/shared).
|
|
907
|
-
*/
|
|
908
775
|
resetScope() {
|
|
909
776
|
if (this.canChangeScope())
|
|
910
777
|
this.calendar.teamId = this.calendar.userId = null;
|
|
911
778
|
}
|
|
912
|
-
/**
|
|
913
|
-
* Whether we can change the scope of the calendar (private/shared).
|
|
914
|
-
*/
|
|
915
779
|
canChangeScope() {
|
|
916
780
|
return !this.fixScope && this.scopeIsSet();
|
|
917
781
|
}
|
|
918
|
-
/**
|
|
919
|
-
* Whether the scope has been set already.
|
|
920
|
-
*/
|
|
921
782
|
scopeIsSet() {
|
|
922
783
|
return Boolean(this.calendar.userId) || Boolean(this.calendar.teamId);
|
|
923
784
|
}
|
|
924
|
-
/**
|
|
925
|
-
* Add a new calendar based on the configuration set.
|
|
926
|
-
*/
|
|
927
785
|
async saveNewCalendar(service) {
|
|
928
|
-
// be sure the scope of the calendar was chosen
|
|
929
786
|
if (!this.scopeIsSet())
|
|
930
787
|
return;
|
|
931
|
-
// be sure we are allowed to create the calendar
|
|
932
788
|
if (!service && this.onlyExternalCalendars)
|
|
933
789
|
return;
|
|
934
|
-
// flag the calendar so it has to be linked to an externals service (the procedure follows the creation)
|
|
935
790
|
if (service) {
|
|
936
791
|
this.calendar.external = new ExternalCalendarInfo({ service });
|
|
937
792
|
this.calendar.name = '-'; // it will be substituted with the external name
|
|
938
793
|
}
|
|
939
794
|
else {
|
|
940
|
-
// default values for local calendars
|
|
941
795
|
this.calendar.name = this.calendar.userId
|
|
942
|
-
? this.
|
|
943
|
-
: this.
|
|
796
|
+
? this._translate._('IDEA_AGENDA.CALENDARS.DEFAULT_PERSONAL_CALENDAR_NAME')
|
|
797
|
+
: this._translate._('IDEA_AGENDA.CALENDARS.DEFAULT_TEAM_CALENDAR_NAME');
|
|
944
798
|
this.calendar.color = this.DEFAULT_COLOR;
|
|
945
799
|
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
.postCalendar(this.calendar)
|
|
950
|
-
.then(cal => {
|
|
800
|
+
try {
|
|
801
|
+
await this._loading.show();
|
|
802
|
+
const cal = await this._calendars.postCalendar(this.calendar);
|
|
951
803
|
this.calendar.load(cal);
|
|
952
|
-
this.
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
return
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
.linkExtService(this.calendar)
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
return this.modalCtrl.dismiss(this.calendar);
|
|
965
|
-
// if an external calendar was set, update the calendar
|
|
804
|
+
this._message.success('IDEA_AGENDA.CALENDARS.CALENDAR_CREATED');
|
|
805
|
+
if (!cal.external) {
|
|
806
|
+
this._modal.dismiss(this.calendar);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
try {
|
|
810
|
+
await this._calendars.linkExtService(this.calendar);
|
|
811
|
+
const res = await this._calendars.chooseAndSetExternalCalendar(this.calendar);
|
|
812
|
+
if (!res) {
|
|
813
|
+
this._modal.dismiss(this.calendar);
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
966
816
|
this.calendar.load(res);
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
.
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
.
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
this.
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
this.
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
817
|
+
await this._loading.show(this._translate._('IDEA_AGENDA.CALENDARS.FIRST_SYNC_MAY_TAKE_A_WHILE'));
|
|
818
|
+
try {
|
|
819
|
+
await this._calendars.syncCalendar(this.calendar);
|
|
820
|
+
this._message.success('IDEA_AGENDA.CALENDARS.FIRST_SYNC_COMPLETED');
|
|
821
|
+
}
|
|
822
|
+
catch (error) {
|
|
823
|
+
this._message.error('COMMON.OPERATION_FAILED');
|
|
824
|
+
}
|
|
825
|
+
finally {
|
|
826
|
+
this._modal.dismiss(this.calendar);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
catch (error) {
|
|
830
|
+
this._message.error('COMMON.OPERATION_FAILED');
|
|
831
|
+
this._modal.dismiss(this.calendar);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
catch (error) {
|
|
835
|
+
this._message.error('COMMON.OPERATION_FAILED');
|
|
836
|
+
}
|
|
837
|
+
finally {
|
|
838
|
+
this._loading.hide();
|
|
839
|
+
}
|
|
987
840
|
}
|
|
988
|
-
/**
|
|
989
|
-
* Close the component.
|
|
990
|
-
*/
|
|
991
841
|
close() {
|
|
992
|
-
this.
|
|
842
|
+
this._modal.dismiss();
|
|
993
843
|
}
|
|
994
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
995
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
844
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEACalendarCreationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
845
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.1", type: IDEACalendarCreationComponent, selector: "idea-calendar-creation", inputs: { fixScope: "fixScope", onlyExternalCalendars: "onlyExternalCalendars" }, ngImport: i0, template: "<ion-header>\n <ion-toolbar color=\"ideaToolbar\">\n <ion-buttons slot=\"start\">\n @if (!canChangeScope()) {\n <ion-button [title]=\"'COMMON.CLOSE' | translate\" (click)=\"close()\">\n <ion-icon name=\"close\" slot=\"icon-only\" />\n </ion-button>\n }\n @if (canChangeScope()) {\n <ion-button (click)=\"resetScope()\">\n <ion-icon name=\"arrow-back\" slot=\"icon-only\" />\n </ion-button>\n }\n </ion-buttons>\n <ion-title>\n @if (!scopeIsSet()) {\n <span>{{ 'IDEA_AGENDA.CALENDARS.ADD_A_CALENDAR' | translate }}</span>\n }\n @if (calendar.userId) {\n <span>{{ 'IDEA_AGENDA.CALENDARS.PERSONAL_CALENDAR' | translate }}</span>\n }\n @if (calendar.teamId) {\n <span>\n {{ 'IDEA_AGENDA.CALENDARS.TEAM_CALENDAR' | translate: { team: tc.get('team').name } }}\n </span>\n }\n </ion-title>\n </ion-toolbar>\n</ion-header>\n<ion-content>\n <!-- 1st STEP -->\n @if (!scopeIsSet()) {\n <ion-grid class=\"ion-padding choiceGrid\">\n <ion-row>\n <ion-col class=\"ion-text-center\">\n <h1>{{ 'IDEA_AGENDA.CALENDARS.CREATE_PRIVATE_OR_TEAM' | translate }}</h1>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-align-items-center\">\n <ion-col class=\"ion-text-center\" [size]=\"12\" [sizeSm]=\"6\">\n <ion-card [button]=\"true\" (click)=\"calendar.userId = membership.userId\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon name=\"person\" />\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <h1>{{ 'IDEA_AGENDA.CALENDARS.PERSONAL_CALENDAR' | translate }}</h1>\n <p>{{ 'IDEA_AGENDA.CALENDARS.PERSONAL_CALENDAR_HINT' | translate }}</p>\n </ion-card-content>\n </ion-card>\n </ion-col>\n <ion-col class=\"ion-text-center\" [size]=\"12\" [sizeSm]=\"6\">\n <ion-card [button]=\"true\" (click)=\"calendar.teamId = membership.teamId\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon name=\"people\" />\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <h1>{{ 'IDEA_AGENDA.CALENDARS.TEAM_CALENDAR' | translate }}</h1>\n <p>{{ 'IDEA_AGENDA.CALENDARS.TEAM_CALENDAR_HINT' | translate }}</p>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n }\n <!-- 2nd STEP -->\n @if (scopeIsSet()) {\n <ion-grid class=\"ion-padding choiceGrid\">\n <ion-row>\n <ion-col class=\"ion-text-center\">\n <h1>{{ 'IDEA_AGENDA.CALENDARS.WHICH_EXTERNAL_SERVICE_TO_LINK' | translate }}</h1>\n <p>{{ 'IDEA_AGENDA.CALENDARS.WHICH_EXTERNAL_SERVICE_TO_LINK_HINT' | translate }}</p>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-align-items-center\">\n @if (!onlyExternalCalendars) {\n <ion-col class=\"ion-text-center\" [size]=\"12\">\n <ion-card class=\"step2\" [button]=\"true\" (click)=\"saveNewCalendar()\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon name=\"remove\" />\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <h1>{{ 'IDEA_AGENDA.CALENDARS.DONT_LINK' | translate }}</h1>\n <p>{{ 'IDEA_AGENDA.CALENDARS.DONT_LINK_HINT' | translate }}</p>\n </ion-card-content>\n </ion-card>\n </ion-col>\n }\n @for (s of SOURCES; track s) {\n <ion-col class=\"ion-text-center\" [size]=\"12\">\n <ion-card class=\"step2\" [button]=\"true\" (click)=\"saveNewCalendar(s)\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon [name]=\"calendars.getServiceIcon(s)\" />\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <h1>\n {{ 'IDEA_AGENDA.CALENDARS.LINK_TO' | translate }}\n {{ 'IDEA_AGENDA.CALENDARS.SERVICES.' + s | translate }}\n </h1>\n <p>{{ 'IDEA_AGENDA.CALENDARS.LINK_TO_HINT' | translate }}</p>\n </ion-card-content>\n </ion-card>\n </ion-col>\n }\n </ion-row>\n </ion-grid>\n }\n</ion-content>\n", styles: ["ion-content{--background: var(--ion-color-white-shade)}.choiceGrid ion-row ion-col>h1{margin:10px 0 0;font-size:1.1em}.choiceGrid ion-row ion-col>p{margin-top:0;margin-bottom:0;font-size:.9em}.choiceGrid ion-row:first-child ion-col{padding-bottom:25px}.choiceGrid ion-card{--ion-item-background: var(--ion-color-white);--color: var(--ion-color-dark-tint);height:240px;margin:0 auto;text-align:center}.choiceGrid ion-card ion-card-header{padding-bottom:10px}.choiceGrid ion-card ion-card-header ion-card-title{font-size:2.5em}.choiceGrid ion-card ion-card-content h1{font-size:1.4em;height:60px}.choiceGrid ion-card.step2{height:135px}.choiceGrid ion-card.step2 ion-card-header{padding-top:10px;padding-bottom:0}.choiceGrid ion-card.step2 ion-card-content h1{height:auto}\n"], dependencies: [{ kind: "component", type: i2.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i2.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i2.IonCard, selector: "ion-card", inputs: ["button", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: i2.IonCardContent, selector: "ion-card-content", inputs: ["mode"] }, { kind: "component", type: i2.IonCardHeader, selector: "ion-card-header", inputs: ["color", "mode", "translucent"] }, { kind: "component", type: i2.IonCardTitle, selector: "ion-card-title", inputs: ["color", "mode"] }, { kind: "component", type: i2.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i2.IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i2.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i2.IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i2.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i2.IonRow, selector: "ion-row" }, { kind: "component", type: i2.IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: i2.IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "pipe", type: i3.IDEATranslatePipe, name: "translate" }] }); }
|
|
996
846
|
}
|
|
997
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
847
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEACalendarCreationComponent, decorators: [{
|
|
998
848
|
type: Component,
|
|
999
|
-
args: [{ selector: 'idea-calendar-creation', template: "<ion-header>\n <ion-toolbar color=\"ideaToolbar\">\n <ion-buttons slot=\"start\">\n
|
|
1000
|
-
}],
|
|
849
|
+
args: [{ selector: 'idea-calendar-creation', template: "<ion-header>\n <ion-toolbar color=\"ideaToolbar\">\n <ion-buttons slot=\"start\">\n @if (!canChangeScope()) {\n <ion-button [title]=\"'COMMON.CLOSE' | translate\" (click)=\"close()\">\n <ion-icon name=\"close\" slot=\"icon-only\" />\n </ion-button>\n }\n @if (canChangeScope()) {\n <ion-button (click)=\"resetScope()\">\n <ion-icon name=\"arrow-back\" slot=\"icon-only\" />\n </ion-button>\n }\n </ion-buttons>\n <ion-title>\n @if (!scopeIsSet()) {\n <span>{{ 'IDEA_AGENDA.CALENDARS.ADD_A_CALENDAR' | translate }}</span>\n }\n @if (calendar.userId) {\n <span>{{ 'IDEA_AGENDA.CALENDARS.PERSONAL_CALENDAR' | translate }}</span>\n }\n @if (calendar.teamId) {\n <span>\n {{ 'IDEA_AGENDA.CALENDARS.TEAM_CALENDAR' | translate: { team: tc.get('team').name } }}\n </span>\n }\n </ion-title>\n </ion-toolbar>\n</ion-header>\n<ion-content>\n <!-- 1st STEP -->\n @if (!scopeIsSet()) {\n <ion-grid class=\"ion-padding choiceGrid\">\n <ion-row>\n <ion-col class=\"ion-text-center\">\n <h1>{{ 'IDEA_AGENDA.CALENDARS.CREATE_PRIVATE_OR_TEAM' | translate }}</h1>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-align-items-center\">\n <ion-col class=\"ion-text-center\" [size]=\"12\" [sizeSm]=\"6\">\n <ion-card [button]=\"true\" (click)=\"calendar.userId = membership.userId\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon name=\"person\" />\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <h1>{{ 'IDEA_AGENDA.CALENDARS.PERSONAL_CALENDAR' | translate }}</h1>\n <p>{{ 'IDEA_AGENDA.CALENDARS.PERSONAL_CALENDAR_HINT' | translate }}</p>\n </ion-card-content>\n </ion-card>\n </ion-col>\n <ion-col class=\"ion-text-center\" [size]=\"12\" [sizeSm]=\"6\">\n <ion-card [button]=\"true\" (click)=\"calendar.teamId = membership.teamId\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon name=\"people\" />\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <h1>{{ 'IDEA_AGENDA.CALENDARS.TEAM_CALENDAR' | translate }}</h1>\n <p>{{ 'IDEA_AGENDA.CALENDARS.TEAM_CALENDAR_HINT' | translate }}</p>\n </ion-card-content>\n </ion-card>\n </ion-col>\n </ion-row>\n </ion-grid>\n }\n <!-- 2nd STEP -->\n @if (scopeIsSet()) {\n <ion-grid class=\"ion-padding choiceGrid\">\n <ion-row>\n <ion-col class=\"ion-text-center\">\n <h1>{{ 'IDEA_AGENDA.CALENDARS.WHICH_EXTERNAL_SERVICE_TO_LINK' | translate }}</h1>\n <p>{{ 'IDEA_AGENDA.CALENDARS.WHICH_EXTERNAL_SERVICE_TO_LINK_HINT' | translate }}</p>\n </ion-col>\n </ion-row>\n <ion-row class=\"ion-align-items-center\">\n @if (!onlyExternalCalendars) {\n <ion-col class=\"ion-text-center\" [size]=\"12\">\n <ion-card class=\"step2\" [button]=\"true\" (click)=\"saveNewCalendar()\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon name=\"remove\" />\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <h1>{{ 'IDEA_AGENDA.CALENDARS.DONT_LINK' | translate }}</h1>\n <p>{{ 'IDEA_AGENDA.CALENDARS.DONT_LINK_HINT' | translate }}</p>\n </ion-card-content>\n </ion-card>\n </ion-col>\n }\n @for (s of SOURCES; track s) {\n <ion-col class=\"ion-text-center\" [size]=\"12\">\n <ion-card class=\"step2\" [button]=\"true\" (click)=\"saveNewCalendar(s)\">\n <ion-card-header>\n <ion-card-title>\n <ion-icon [name]=\"calendars.getServiceIcon(s)\" />\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <h1>\n {{ 'IDEA_AGENDA.CALENDARS.LINK_TO' | translate }}\n {{ 'IDEA_AGENDA.CALENDARS.SERVICES.' + s | translate }}\n </h1>\n <p>{{ 'IDEA_AGENDA.CALENDARS.LINK_TO_HINT' | translate }}</p>\n </ion-card-content>\n </ion-card>\n </ion-col>\n }\n </ion-row>\n </ion-grid>\n }\n</ion-content>\n", styles: ["ion-content{--background: var(--ion-color-white-shade)}.choiceGrid ion-row ion-col>h1{margin:10px 0 0;font-size:1.1em}.choiceGrid ion-row ion-col>p{margin-top:0;margin-bottom:0;font-size:.9em}.choiceGrid ion-row:first-child ion-col{padding-bottom:25px}.choiceGrid ion-card{--ion-item-background: var(--ion-color-white);--color: var(--ion-color-dark-tint);height:240px;margin:0 auto;text-align:center}.choiceGrid ion-card ion-card-header{padding-bottom:10px}.choiceGrid ion-card ion-card-header ion-card-title{font-size:2.5em}.choiceGrid ion-card ion-card-content h1{font-size:1.4em;height:60px}.choiceGrid ion-card.step2{height:135px}.choiceGrid ion-card.step2 ion-card-header{padding-top:10px;padding-bottom:0}.choiceGrid ion-card.step2 ion-card-content h1{height:auto}\n"] }]
|
|
850
|
+
}], propDecorators: { fixScope: [{
|
|
1001
851
|
type: Input
|
|
1002
852
|
}], onlyExternalCalendars: [{
|
|
1003
853
|
type: Input
|
|
@@ -1012,15 +862,15 @@ var CalendarScopes;
|
|
|
1012
862
|
})(CalendarScopes || (CalendarScopes = {}));
|
|
1013
863
|
|
|
1014
864
|
class IDEAAgendaModule {
|
|
1015
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
1016
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "
|
|
865
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEAAgendaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
866
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.1.1", ngImport: i0, type: IDEAAgendaModule, declarations: [IDEAAgendaComponent, IDEACalendarComponent, IDEACalendarItemComponent, IDEACalendarCreationComponent], imports: [CommonModule,
|
|
1017
867
|
FormsModule,
|
|
1018
868
|
IonicModule,
|
|
1019
869
|
IDEATranslationsModule,
|
|
1020
870
|
IDEAColorPickerModule,
|
|
1021
871
|
IDEACheckerModule,
|
|
1022
872
|
IDEAUserAvatarModule, i4.CalendarModule], exports: [IDEAAgendaComponent, IDEACalendarComponent, IDEACalendarItemComponent, IDEACalendarCreationComponent] }); }
|
|
1023
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "
|
|
873
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEAAgendaModule, providers: [{ provide: CalendarDateFormatter, useClass: CustomDateFormatter }, IDEACalendarsService], imports: [CommonModule,
|
|
1024
874
|
FormsModule,
|
|
1025
875
|
IonicModule,
|
|
1026
876
|
IDEATranslationsModule,
|
|
@@ -1029,7 +879,7 @@ class IDEAAgendaModule {
|
|
|
1029
879
|
IDEAUserAvatarModule,
|
|
1030
880
|
CalendarModule.forRoot({ provide: DateAdapter, useFactory: adapterFactory })] }); }
|
|
1031
881
|
}
|
|
1032
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
882
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEAAgendaModule, decorators: [{
|
|
1033
883
|
type: NgModule,
|
|
1034
884
|
args: [{
|
|
1035
885
|
imports: [
|