@solcre-org/core-ui 2.15.46 → 2.16.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/assets/css/inc/components/bottom-alert.css +1 -1
- package/assets/css/inc/components/calendar.css +423 -14
- package/assets/css/inc/components/data-entry.general.css +1 -0
- package/assets/css/inc/components/header-mobile.css +12 -3
- package/assets/css/inc/components/modal.css +1 -1
- package/assets/css/inc/components/popup.css +5 -0
- package/assets/css/inc/components/table.css +8 -3
- package/assets/css/inc/generic/screen.css +3 -4
- package/assets/css/main.css +1 -0
- package/assets/i18n/en/common.json +14 -14
- package/fesm2022/solcre-org-core-ui.mjs +623 -13
- package/fesm2022/solcre-org-core-ui.mjs.map +1 -1
- package/index.d.ts +261 -2
- package/package.json +1 -1
|
@@ -2721,6 +2721,47 @@ function getCountryCodeStrings() {
|
|
|
2721
2721
|
return ALL_COUNTRY_CODES.map(code => code.toString());
|
|
2722
2722
|
}
|
|
2723
2723
|
|
|
2724
|
+
var DayState;
|
|
2725
|
+
(function (DayState) {
|
|
2726
|
+
DayState["DEFAULT"] = "default";
|
|
2727
|
+
DayState["ACTIVE"] = "active";
|
|
2728
|
+
DayState["CURRENT"] = "current";
|
|
2729
|
+
DayState["DISABLED"] = "disabled";
|
|
2730
|
+
DayState["SELECTED"] = "selected";
|
|
2731
|
+
})(DayState || (DayState = {}));
|
|
2732
|
+
|
|
2733
|
+
var DayType;
|
|
2734
|
+
(function (DayType) {
|
|
2735
|
+
DayType["PREVIOUS_MONTH"] = "previous";
|
|
2736
|
+
DayType["CURRENT_MONTH"] = "current";
|
|
2737
|
+
DayType["NEXT_MONTH"] = "next";
|
|
2738
|
+
})(DayType || (DayType = {}));
|
|
2739
|
+
|
|
2740
|
+
var CalendarEventType;
|
|
2741
|
+
(function (CalendarEventType) {
|
|
2742
|
+
CalendarEventType["BLOCKED"] = "blocked";
|
|
2743
|
+
CalendarEventType["UNAVAILABLE"] = "unavailable";
|
|
2744
|
+
CalendarEventType["EVENT"] = "event";
|
|
2745
|
+
CalendarEventType["PENDING"] = "pending";
|
|
2746
|
+
CalendarEventType["USER_EVENT"] = "user-event";
|
|
2747
|
+
CalendarEventType["CONFIRMED"] = "confirmed";
|
|
2748
|
+
CalendarEventType["CANCELLED"] = "cancelled";
|
|
2749
|
+
CalendarEventType["COMPLETED"] = "completed";
|
|
2750
|
+
CalendarEventType["REJECTED"] = "rejected";
|
|
2751
|
+
CalendarEventType["EXPIRED"] = "expired";
|
|
2752
|
+
})(CalendarEventType || (CalendarEventType = {}));
|
|
2753
|
+
|
|
2754
|
+
var WeekDay;
|
|
2755
|
+
(function (WeekDay) {
|
|
2756
|
+
WeekDay[WeekDay["MONDAY"] = 0] = "MONDAY";
|
|
2757
|
+
WeekDay[WeekDay["TUESDAY"] = 1] = "TUESDAY";
|
|
2758
|
+
WeekDay[WeekDay["WEDNESDAY"] = 2] = "WEDNESDAY";
|
|
2759
|
+
WeekDay[WeekDay["THURSDAY"] = 3] = "THURSDAY";
|
|
2760
|
+
WeekDay[WeekDay["FRIDAY"] = 4] = "FRIDAY";
|
|
2761
|
+
WeekDay[WeekDay["SATURDAY"] = 5] = "SATURDAY";
|
|
2762
|
+
WeekDay[WeekDay["SUNDAY"] = 6] = "SUNDAY";
|
|
2763
|
+
})(WeekDay || (WeekDay = {}));
|
|
2764
|
+
|
|
2724
2765
|
const DEFAULT_COUNTRIES = [
|
|
2725
2766
|
{ "code": CountryCode.PY, "phone": "+595", "name": "Paraguay", "flag": "001-paraguay.svg" },
|
|
2726
2767
|
{ "code": CountryCode.SN, "phone": "+221", "name": "Senegal", "flag": "002-senegal.svg" },
|
|
@@ -8045,7 +8086,18 @@ class DateUtility {
|
|
|
8045
8086
|
const yyyy = d.getUTCFullYear();
|
|
8046
8087
|
const HH = this.pad2(d.getUTCHours());
|
|
8047
8088
|
const MM = this.pad2(d.getUTCMinutes());
|
|
8089
|
+
const SS = this.pad2(d.getUTCSeconds());
|
|
8048
8090
|
switch (pattern) {
|
|
8091
|
+
case 'YYYY-MM-DDTHH:mm:ssZ':
|
|
8092
|
+
const offsetMinutes = d.getTimezoneOffset();
|
|
8093
|
+
const offSign = offsetMinutes <= 0 ? '+' : '-';
|
|
8094
|
+
const abs = Math.abs(offsetMinutes);
|
|
8095
|
+
const offHH = this.pad2(Math.floor(abs / 60));
|
|
8096
|
+
const offMM = this.pad2(abs % 60);
|
|
8097
|
+
const offset = `${offSign}${offHH}:${offMM}`;
|
|
8098
|
+
return `${yyyy}-${mm}-${dd}T${HH}:${MM}:${SS}${offset}`;
|
|
8099
|
+
case 'YYYY-MM-DDTHH:mm:ss':
|
|
8100
|
+
return `${yyyy}-${mm}-${dd} ${HH}:${MM}:${SS}`;
|
|
8049
8101
|
case 'DD/MM/YYYY HH:mm':
|
|
8050
8102
|
return `${dd}/${mm}/${yyyy} ${HH}:${MM}`;
|
|
8051
8103
|
case 'YYYY-MM-DD HH:mm':
|
|
@@ -16399,12 +16451,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
|
|
|
16399
16451
|
// Este archivo es generado automáticamente por scripts/update-version.js
|
|
16400
16452
|
// No edites manualmente este archivo
|
|
16401
16453
|
const VERSION = {
|
|
16402
|
-
full: '2.
|
|
16454
|
+
full: '2.16.2',
|
|
16403
16455
|
major: 2,
|
|
16404
|
-
minor:
|
|
16405
|
-
patch:
|
|
16406
|
-
timestamp: '2025-12-
|
|
16407
|
-
buildDate: '
|
|
16456
|
+
minor: 16,
|
|
16457
|
+
patch: 2,
|
|
16458
|
+
timestamp: '2025-12-04T13:41:32.467Z',
|
|
16459
|
+
buildDate: '4/12/2025'
|
|
16408
16460
|
};
|
|
16409
16461
|
|
|
16410
16462
|
class MainNavComponent {
|
|
@@ -19987,9 +20039,13 @@ class AdAuthService {
|
|
|
19987
20039
|
},
|
|
19988
20040
|
cache: {
|
|
19989
20041
|
cacheLocation: (this.config.cacheLocation || 'sessionStorage'),
|
|
19990
|
-
storeAuthStateInCookie:
|
|
20042
|
+
storeAuthStateInCookie: this.config.interactionType === AdInteractionType.POPUP,
|
|
19991
20043
|
},
|
|
19992
20044
|
system: {
|
|
20045
|
+
allowNativeBroker: false,
|
|
20046
|
+
windowHashTimeout: 60000,
|
|
20047
|
+
iframeHashTimeout: 6000,
|
|
20048
|
+
loadFrameTimeout: 0,
|
|
19993
20049
|
loggerOptions: {
|
|
19994
20050
|
loggerCallback: this.config.enableLogging ? this.loggerCallback : undefined,
|
|
19995
20051
|
logLevel: this.config.logLevel || 0,
|
|
@@ -20085,13 +20141,21 @@ class AdAuthService {
|
|
|
20085
20141
|
this.updateAuthState({ isLoading: true, error: null });
|
|
20086
20142
|
try {
|
|
20087
20143
|
const loginRequest = {
|
|
20088
|
-
scopes: this.config.scopes || ['openid', 'profile', 'email']
|
|
20144
|
+
scopes: this.config.scopes || ['openid', 'profile', 'email'],
|
|
20145
|
+
prompt: 'select_account'
|
|
20089
20146
|
};
|
|
20090
20147
|
const result = await this.msalInstance.loginPopup(loginRequest);
|
|
20091
20148
|
this.handleAuthenticationResult(result);
|
|
20092
20149
|
return this.currentUser();
|
|
20093
20150
|
}
|
|
20094
20151
|
catch (error) {
|
|
20152
|
+
if (error?.errorCode === 'hash_empty_error') {
|
|
20153
|
+
console.warn('MSAL: Hash vacío detectado, intentando verificar sesión existente...');
|
|
20154
|
+
await this.checkActiveSession();
|
|
20155
|
+
if (this.isAuthenticated()) {
|
|
20156
|
+
return this.currentUser();
|
|
20157
|
+
}
|
|
20158
|
+
}
|
|
20095
20159
|
this.updateAuthState({
|
|
20096
20160
|
isLoading: false,
|
|
20097
20161
|
error
|
|
@@ -20251,11 +20315,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
|
|
|
20251
20315
|
}], ctorParameters: () => [] });
|
|
20252
20316
|
|
|
20253
20317
|
function adAuthGuard(redirectTo = '/login') {
|
|
20254
|
-
return () => {
|
|
20318
|
+
return async () => {
|
|
20255
20319
|
const authService = inject(AdAuthService);
|
|
20256
20320
|
const router = inject(Router);
|
|
20257
20321
|
if (!authService.isConfigured()) {
|
|
20258
|
-
return
|
|
20322
|
+
return true;
|
|
20323
|
+
}
|
|
20324
|
+
try {
|
|
20325
|
+
await authService.isReady();
|
|
20326
|
+
}
|
|
20327
|
+
catch (error) {
|
|
20328
|
+
console.warn('[adAuthGuard] MSAL initialization failed, allowing access');
|
|
20329
|
+
return true;
|
|
20259
20330
|
}
|
|
20260
20331
|
if (authService.isAuthenticated()) {
|
|
20261
20332
|
return true;
|
|
@@ -20264,12 +20335,18 @@ function adAuthGuard(redirectTo = '/login') {
|
|
|
20264
20335
|
};
|
|
20265
20336
|
}
|
|
20266
20337
|
function adGuestGuard(redirectTo = '/') {
|
|
20267
|
-
return () => {
|
|
20338
|
+
return async () => {
|
|
20268
20339
|
const authService = inject(AdAuthService);
|
|
20269
20340
|
const router = inject(Router);
|
|
20270
20341
|
if (!authService.isConfigured()) {
|
|
20271
20342
|
return true;
|
|
20272
20343
|
}
|
|
20344
|
+
try {
|
|
20345
|
+
await authService.isReady();
|
|
20346
|
+
}
|
|
20347
|
+
catch (error) {
|
|
20348
|
+
return true;
|
|
20349
|
+
}
|
|
20273
20350
|
if (!authService.isAuthenticated()) {
|
|
20274
20351
|
return true;
|
|
20275
20352
|
}
|
|
@@ -20277,11 +20354,17 @@ function adGuestGuard(redirectTo = '/') {
|
|
|
20277
20354
|
};
|
|
20278
20355
|
}
|
|
20279
20356
|
function adRoleGuard(requiredRoles, redirectTo = '/unauthorized') {
|
|
20280
|
-
return () => {
|
|
20357
|
+
return async () => {
|
|
20281
20358
|
const authService = inject(AdAuthService);
|
|
20282
20359
|
const router = inject(Router);
|
|
20283
20360
|
if (!authService.isConfigured()) {
|
|
20284
|
-
return
|
|
20361
|
+
return true;
|
|
20362
|
+
}
|
|
20363
|
+
try {
|
|
20364
|
+
await authService.isReady();
|
|
20365
|
+
}
|
|
20366
|
+
catch (error) {
|
|
20367
|
+
return true;
|
|
20285
20368
|
}
|
|
20286
20369
|
if (!authService.isAuthenticated()) {
|
|
20287
20370
|
return router.createUrlTree(['/login']);
|
|
@@ -20471,6 +20554,533 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
|
|
|
20471
20554
|
args: [{ selector: 'core-ad-login-button', standalone: true, imports: [CommonModule, GenericButtonComponent, TranslateModule], template: "<div class=\"ad-auth-container\" [ngClass]=\"config().customClass\">\n @if (!isConfigured) {\n <div class=\"ad-auth-not-configured\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n {{ \"adAuth.not Configured\" | translate }}\n </div>\n } @else if (isLoading() && config().showLoader !== false) {\n <div class=\"ad-auth-loading\">\n <span class=\"ad-auth-spinner\"></span>\n {{ \"adAuth.authenticating\" | translate }}\n </div>\n } @else if (isAuthenticated() && currentUser()) { @if (showUserInfo()) {\n <div class=\"ad-auth-user-info\">\n <div class=\"ad-auth-user-avatar\">\n {{ userInitials() }}\n </div>\n <div class=\"ad-auth-user-details\">\n <p class=\"ad-auth-user-name\">\n {{ currentUser()!.name || (\"adAuth.user\" | translate) }}\n </p>\n <p class=\"ad-auth-user-email\">{{ currentUser()!.email }}</p>\n </div>\n </div>\n }\n\n <div class=\"ad-auth-buttons\">\n <core-generic-button\n [config]=\"logoutButtonConfig()\"\n (buttonClick)=\"onLogoutClick()\"\n />\n </div>\n } @else { @if (error()) {\n <div class=\"ad-auth-error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{ \"adAuth.authError\" | translate }}\n </div>\n }\n\n <div class=\"ad-auth-buttons\">\n <core-generic-button\n [config]=\"loginButtonConfig()\"\n (buttonClick)=\"onLoginClick()\"\n />\n </div>\n }\n</div>\n", styles: [":host{display:block}.ad-auth-container{display:flex;flex-direction:column;gap:.75rem}.ad-auth-user-info{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;background-color:var(--color-background-secondary, #f5f5f5);border-radius:var(--border-radius, .375rem);font-size:.875rem}.ad-auth-user-avatar{width:2.5rem;height:2.5rem;border-radius:50%;background:linear-gradient(135deg,var(--color-primary, #0078d4) 0%,var(--color-primary-dark, #106ebe) 100%);display:flex;align-items:center;justify-content:center;color:#fff;font-weight:600;font-size:1rem;flex-shrink:0}.ad-auth-user-details{flex:1;min-width:0}.ad-auth-user-name{font-weight:600;color:var(--color-text-primary, #1a1a1a);margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ad-auth-user-email{color:var(--color-text-secondary, #666);margin:0;font-size:.8125rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ad-auth-loading{display:flex;align-items:center;justify-content:center;padding:1rem;color:var(--color-text-secondary, #666);font-size:.875rem}.ad-auth-spinner{display:inline-block;width:1rem;height:1rem;border:2px solid var(--color-border, #e0e0e0);border-top-color:var(--color-primary, #0078d4);border-radius:50%;animation:spin .6s linear infinite;margin-right:.5rem}@keyframes spin{to{transform:rotate(360deg)}}.ad-auth-error{padding:.75rem 1rem;background-color:var(--color-danger-light, #fee);color:var(--color-danger, #d32f2f);border-radius:var(--border-radius, .375rem);font-size:.875rem}.ad-auth-not-configured{padding:1rem;background-color:var(--color-warning-light, #fff8e1);color:var(--color-warning-dark, #f57c00);border-radius:var(--border-radius, .375rem);font-size:.875rem;text-align:center}.ad-auth-buttons{display:flex;gap:.5rem}\n"] }]
|
|
20472
20555
|
}], ctorParameters: () => [] });
|
|
20473
20556
|
|
|
20557
|
+
class GenericCalendarComponent {
|
|
20558
|
+
currentDate = input(new Date());
|
|
20559
|
+
selectedDate = input(null);
|
|
20560
|
+
config = input({});
|
|
20561
|
+
showNavigation = input(true);
|
|
20562
|
+
showHeader = input(true);
|
|
20563
|
+
locale = input('es-ES');
|
|
20564
|
+
dateSelected = output();
|
|
20565
|
+
monthChanged = output();
|
|
20566
|
+
displayDate = signal(new Date());
|
|
20567
|
+
calendarDays = signal([]);
|
|
20568
|
+
monthName = computed(() => {
|
|
20569
|
+
const date = this.displayDate();
|
|
20570
|
+
const localeValue = this.config().locale || this.locale();
|
|
20571
|
+
return date.toLocaleDateString(localeValue, { month: 'long', timeZone: 'UTC' });
|
|
20572
|
+
});
|
|
20573
|
+
year = computed(() => this.displayDate().getUTCFullYear());
|
|
20574
|
+
weekDayLabels = computed(() => {
|
|
20575
|
+
const startOnMonday = this.config().startWeekOnMonday ?? true;
|
|
20576
|
+
const labels = ['L', 'M', 'M', 'J', 'V', 'S', 'D'];
|
|
20577
|
+
return startOnMonday ? labels : ['D', ...labels.slice(0, 6)];
|
|
20578
|
+
});
|
|
20579
|
+
constructor() {
|
|
20580
|
+
this.displayDate.set(this.toUTCDate(this.currentDate()));
|
|
20581
|
+
this.generateCalendarDays();
|
|
20582
|
+
effect(() => {
|
|
20583
|
+
const current = this.currentDate();
|
|
20584
|
+
this.displayDate.set(this.toUTCDate(current));
|
|
20585
|
+
this.generateCalendarDays();
|
|
20586
|
+
});
|
|
20587
|
+
effect(() => {
|
|
20588
|
+
const selected = this.selectedDate();
|
|
20589
|
+
const config = this.config();
|
|
20590
|
+
this.generateCalendarDays();
|
|
20591
|
+
});
|
|
20592
|
+
}
|
|
20593
|
+
toUTCDate(date) {
|
|
20594
|
+
return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
|
20595
|
+
}
|
|
20596
|
+
createUTCDate(year, month, day) {
|
|
20597
|
+
return new Date(Date.UTC(year, month, day));
|
|
20598
|
+
}
|
|
20599
|
+
generateCalendarDays() {
|
|
20600
|
+
const date = this.displayDate();
|
|
20601
|
+
const year = date.getUTCFullYear();
|
|
20602
|
+
const month = date.getUTCMonth();
|
|
20603
|
+
const firstDayOfMonth = this.createUTCDate(year, month, 1);
|
|
20604
|
+
let startDate = new Date(firstDayOfMonth);
|
|
20605
|
+
const startWeekOnMonday = this.config().startWeekOnMonday ?? true;
|
|
20606
|
+
const firstDayWeekday = startWeekOnMonday
|
|
20607
|
+
? (firstDayOfMonth.getUTCDay() + 6) % 7
|
|
20608
|
+
: firstDayOfMonth.getUTCDay();
|
|
20609
|
+
startDate.setUTCDate(startDate.getUTCDate() - firstDayWeekday);
|
|
20610
|
+
const days = [];
|
|
20611
|
+
const today = this.toUTCDate(new Date());
|
|
20612
|
+
const holidaySets = this.getHolidaySets(this.config());
|
|
20613
|
+
for (let i = 0; i < 42; i++) {
|
|
20614
|
+
const currentDay = new Date(startDate);
|
|
20615
|
+
currentDay.setUTCDate(startDate.getUTCDate() + i);
|
|
20616
|
+
const dayType = this.getDayType(currentDay, month);
|
|
20617
|
+
const dayState = this.getDayState(currentDay, today);
|
|
20618
|
+
const isWeekend = this.isWeekend(currentDay, startWeekOnMonday);
|
|
20619
|
+
const disabled = this.isDayDisabled(currentDay, holidaySets);
|
|
20620
|
+
const holidayInfo = this.getHolidayInfo(currentDay, holidaySets);
|
|
20621
|
+
days.push({
|
|
20622
|
+
date: new Date(currentDay),
|
|
20623
|
+
dayNumber: currentDay.getUTCDate(),
|
|
20624
|
+
type: dayType,
|
|
20625
|
+
state: dayState,
|
|
20626
|
+
isToday: this.isSameDay(currentDay, today),
|
|
20627
|
+
isWeekend,
|
|
20628
|
+
disabled,
|
|
20629
|
+
isHoliday: holidayInfo.isHoliday,
|
|
20630
|
+
holidayName: holidayInfo.name
|
|
20631
|
+
});
|
|
20632
|
+
}
|
|
20633
|
+
this.calendarDays.set(days);
|
|
20634
|
+
}
|
|
20635
|
+
getDayType(date, currentMonth) {
|
|
20636
|
+
if (date.getUTCMonth() < currentMonth) {
|
|
20637
|
+
return DayType.PREVIOUS_MONTH;
|
|
20638
|
+
}
|
|
20639
|
+
else if (date.getUTCMonth() > currentMonth) {
|
|
20640
|
+
return DayType.NEXT_MONTH;
|
|
20641
|
+
}
|
|
20642
|
+
return DayType.CURRENT_MONTH;
|
|
20643
|
+
}
|
|
20644
|
+
getDayState(date, today) {
|
|
20645
|
+
const selectedDate = this.selectedDate();
|
|
20646
|
+
const config = this.config();
|
|
20647
|
+
if (selectedDate && this.isSameDay(date, selectedDate)) {
|
|
20648
|
+
return DayState.CURRENT;
|
|
20649
|
+
}
|
|
20650
|
+
if (this.isSameDay(date, today)) {
|
|
20651
|
+
return DayState.ACTIVE;
|
|
20652
|
+
}
|
|
20653
|
+
if (config.highlightedDates?.some((d) => this.isSameDay(date, d))) {
|
|
20654
|
+
return DayState.ACTIVE;
|
|
20655
|
+
}
|
|
20656
|
+
return DayState.DEFAULT;
|
|
20657
|
+
}
|
|
20658
|
+
isDayDisabled(date, holidaySets) {
|
|
20659
|
+
const config = this.config();
|
|
20660
|
+
if (!config.allowPastDates) {
|
|
20661
|
+
const today = this.toUTCDate(new Date());
|
|
20662
|
+
if (date < today)
|
|
20663
|
+
return true;
|
|
20664
|
+
}
|
|
20665
|
+
if (!config.allowFutureDates) {
|
|
20666
|
+
const today = this.toUTCDate(new Date());
|
|
20667
|
+
if (date > today)
|
|
20668
|
+
return true;
|
|
20669
|
+
}
|
|
20670
|
+
if (config.minDate) {
|
|
20671
|
+
const minDateUTC = this.toUTCDate(config.minDate);
|
|
20672
|
+
if (date < minDateUTC)
|
|
20673
|
+
return true;
|
|
20674
|
+
}
|
|
20675
|
+
if (config.maxDate) {
|
|
20676
|
+
const maxDateUTC = this.toUTCDate(config.maxDate);
|
|
20677
|
+
if (date > maxDateUTC)
|
|
20678
|
+
return true;
|
|
20679
|
+
}
|
|
20680
|
+
if (config.disabledDates?.some((d) => this.isSameDay(date, d)))
|
|
20681
|
+
return true;
|
|
20682
|
+
const formattedDate = this.formatDateUTC(date);
|
|
20683
|
+
if (holidaySets.exactDates.has(formattedDate)) {
|
|
20684
|
+
return true;
|
|
20685
|
+
}
|
|
20686
|
+
const monthDay = this.formatMonthDayUTC(date);
|
|
20687
|
+
if (holidaySets.recurringMonthDays.has(monthDay)) {
|
|
20688
|
+
return true;
|
|
20689
|
+
}
|
|
20690
|
+
return false;
|
|
20691
|
+
}
|
|
20692
|
+
isWeekend(date, startWeekOnMonday) {
|
|
20693
|
+
const dayOfWeek = date.getUTCDay();
|
|
20694
|
+
return dayOfWeek === 0 || dayOfWeek === 6;
|
|
20695
|
+
}
|
|
20696
|
+
isSameDay(date1, date2) {
|
|
20697
|
+
return date1.getUTCFullYear() === date2.getUTCFullYear() &&
|
|
20698
|
+
date1.getUTCMonth() === date2.getUTCMonth() &&
|
|
20699
|
+
date1.getUTCDate() === date2.getUTCDate();
|
|
20700
|
+
}
|
|
20701
|
+
getHolidaySets(config) {
|
|
20702
|
+
const holidays = config.holidays ?? [];
|
|
20703
|
+
const exactDates = new Set();
|
|
20704
|
+
const recurringMonthDays = new Set();
|
|
20705
|
+
const holidayNames = new Map();
|
|
20706
|
+
holidays.forEach((holiday) => {
|
|
20707
|
+
if (!holiday?.date) {
|
|
20708
|
+
return;
|
|
20709
|
+
}
|
|
20710
|
+
const holidayDate = this.parseToUTCDate(holiday.date);
|
|
20711
|
+
if (!holidayDate) {
|
|
20712
|
+
return;
|
|
20713
|
+
}
|
|
20714
|
+
const formattedDate = this.formatDateUTC(holidayDate);
|
|
20715
|
+
const monthDay = this.formatMonthDayUTC(holidayDate);
|
|
20716
|
+
const isRecurring = holiday.isRecurring || holiday.is_recurring;
|
|
20717
|
+
if (isRecurring) {
|
|
20718
|
+
recurringMonthDays.add(monthDay);
|
|
20719
|
+
holidayNames.set(`recurring:${monthDay}`, holiday.name || 'Día festivo');
|
|
20720
|
+
}
|
|
20721
|
+
else {
|
|
20722
|
+
exactDates.add(formattedDate);
|
|
20723
|
+
holidayNames.set(`exact:${formattedDate}`, holiday.name || 'Día festivo');
|
|
20724
|
+
}
|
|
20725
|
+
});
|
|
20726
|
+
return { exactDates, recurringMonthDays, holidayNames };
|
|
20727
|
+
}
|
|
20728
|
+
getHolidayInfo(date, holidaySets) {
|
|
20729
|
+
const formattedDate = this.formatDateUTC(date);
|
|
20730
|
+
const monthDay = this.formatMonthDayUTC(date);
|
|
20731
|
+
if (holidaySets.exactDates.has(formattedDate)) {
|
|
20732
|
+
return {
|
|
20733
|
+
isHoliday: true,
|
|
20734
|
+
name: holidaySets.holidayNames?.get(`exact:${formattedDate}`)
|
|
20735
|
+
};
|
|
20736
|
+
}
|
|
20737
|
+
if (holidaySets.recurringMonthDays.has(monthDay)) {
|
|
20738
|
+
return {
|
|
20739
|
+
isHoliday: true,
|
|
20740
|
+
name: holidaySets.holidayNames?.get(`recurring:${monthDay}`)
|
|
20741
|
+
};
|
|
20742
|
+
}
|
|
20743
|
+
return { isHoliday: false };
|
|
20744
|
+
}
|
|
20745
|
+
parseToUTCDate(value) {
|
|
20746
|
+
if (value instanceof Date) {
|
|
20747
|
+
return this.toUTCDate(value);
|
|
20748
|
+
}
|
|
20749
|
+
if (typeof value === 'string' && value.match(/^\d{4}-\d{2}-\d{2}$/)) {
|
|
20750
|
+
const [year, month, day] = value.split('-').map(Number);
|
|
20751
|
+
return this.createUTCDate(year, month - 1, day);
|
|
20752
|
+
}
|
|
20753
|
+
const parsed = new Date(value);
|
|
20754
|
+
return Number.isNaN(parsed.getTime()) ? null : this.toUTCDate(parsed);
|
|
20755
|
+
}
|
|
20756
|
+
formatDateUTC(date) {
|
|
20757
|
+
const year = date.getUTCFullYear();
|
|
20758
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
|
20759
|
+
const day = String(date.getUTCDate()).padStart(2, '0');
|
|
20760
|
+
return `${year}-${month}-${day}`;
|
|
20761
|
+
}
|
|
20762
|
+
formatMonthDayUTC(date) {
|
|
20763
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
|
20764
|
+
const day = String(date.getUTCDate()).padStart(2, '0');
|
|
20765
|
+
return `${month}-${day}`;
|
|
20766
|
+
}
|
|
20767
|
+
onDayClick(day) {
|
|
20768
|
+
if (day.disabled)
|
|
20769
|
+
return;
|
|
20770
|
+
if (day.type !== DayType.CURRENT_MONTH) {
|
|
20771
|
+
const clickedDate = day.date;
|
|
20772
|
+
const currentDisplayDate = this.displayDate();
|
|
20773
|
+
const newDate = this.createUTCDate(clickedDate.getUTCFullYear(), clickedDate.getUTCMonth(), 1);
|
|
20774
|
+
const isNextMonth = clickedDate > currentDisplayDate;
|
|
20775
|
+
this.displayDate.set(newDate);
|
|
20776
|
+
this.generateCalendarDays();
|
|
20777
|
+
const navigationEvent = {
|
|
20778
|
+
type: isNextMonth ? 'next' : 'previous',
|
|
20779
|
+
currentDate: new Date(currentDisplayDate),
|
|
20780
|
+
newDate: new Date(newDate)
|
|
20781
|
+
};
|
|
20782
|
+
this.monthChanged.emit(navigationEvent);
|
|
20783
|
+
}
|
|
20784
|
+
const event = {
|
|
20785
|
+
selectedDate: day.date,
|
|
20786
|
+
calendarDay: day,
|
|
20787
|
+
formattedDate: this.formatDateUTC(day.date)
|
|
20788
|
+
};
|
|
20789
|
+
this.dateSelected.emit(event);
|
|
20790
|
+
}
|
|
20791
|
+
onPreviousMonth() {
|
|
20792
|
+
const currentDate = this.displayDate();
|
|
20793
|
+
const newDate = this.createUTCDate(currentDate.getUTCFullYear(), currentDate.getUTCMonth() - 1, 1);
|
|
20794
|
+
const event = {
|
|
20795
|
+
type: 'previous',
|
|
20796
|
+
currentDate: new Date(currentDate),
|
|
20797
|
+
newDate: new Date(newDate)
|
|
20798
|
+
};
|
|
20799
|
+
this.displayDate.set(newDate);
|
|
20800
|
+
this.generateCalendarDays();
|
|
20801
|
+
this.monthChanged.emit(event);
|
|
20802
|
+
}
|
|
20803
|
+
onNextMonth() {
|
|
20804
|
+
const currentDate = this.displayDate();
|
|
20805
|
+
const newDate = this.createUTCDate(currentDate.getUTCFullYear(), currentDate.getUTCMonth() + 1, 1);
|
|
20806
|
+
const event = {
|
|
20807
|
+
type: 'next',
|
|
20808
|
+
currentDate: new Date(currentDate),
|
|
20809
|
+
newDate: new Date(newDate)
|
|
20810
|
+
};
|
|
20811
|
+
this.displayDate.set(newDate);
|
|
20812
|
+
this.generateCalendarDays();
|
|
20813
|
+
this.monthChanged.emit(event);
|
|
20814
|
+
}
|
|
20815
|
+
resetToCurrentMonth() {
|
|
20816
|
+
const today = this.toUTCDate(new Date());
|
|
20817
|
+
const currentMonth = this.createUTCDate(today.getUTCFullYear(), today.getUTCMonth(), 1);
|
|
20818
|
+
if (this.displayDate().getTime() !== currentMonth.getTime()) {
|
|
20819
|
+
const event = {
|
|
20820
|
+
type: 'reset',
|
|
20821
|
+
currentDate: new Date(this.displayDate()),
|
|
20822
|
+
newDate: new Date(currentMonth)
|
|
20823
|
+
};
|
|
20824
|
+
this.displayDate.set(currentMonth);
|
|
20825
|
+
this.generateCalendarDays();
|
|
20826
|
+
this.monthChanged.emit(event);
|
|
20827
|
+
}
|
|
20828
|
+
}
|
|
20829
|
+
getDayClasses(day) {
|
|
20830
|
+
const classes = ['c-calendar__day'];
|
|
20831
|
+
if (day.type !== DayType.CURRENT_MONTH) {
|
|
20832
|
+
classes.push('not-current');
|
|
20833
|
+
}
|
|
20834
|
+
switch (day.state) {
|
|
20835
|
+
case DayState.CURRENT:
|
|
20836
|
+
classes.push('is-current');
|
|
20837
|
+
break;
|
|
20838
|
+
case DayState.ACTIVE:
|
|
20839
|
+
classes.push('is-active');
|
|
20840
|
+
break;
|
|
20841
|
+
}
|
|
20842
|
+
if (day.disabled) {
|
|
20843
|
+
classes.push('is-disabled');
|
|
20844
|
+
}
|
|
20845
|
+
if (day.isWeekend) {
|
|
20846
|
+
classes.push('is-weekend');
|
|
20847
|
+
}
|
|
20848
|
+
if (day.isHoliday) {
|
|
20849
|
+
classes.push('is-holiday');
|
|
20850
|
+
}
|
|
20851
|
+
return classes.join(' ');
|
|
20852
|
+
}
|
|
20853
|
+
getDayTitle(day) {
|
|
20854
|
+
if (day.isHoliday && day.holidayName) {
|
|
20855
|
+
return `${day.holidayName} - Día festivo`;
|
|
20856
|
+
}
|
|
20857
|
+
if (day.disabled && day.isHoliday) {
|
|
20858
|
+
return 'Día festivo - No disponible';
|
|
20859
|
+
}
|
|
20860
|
+
if (day.disabled) {
|
|
20861
|
+
return 'Día no disponible';
|
|
20862
|
+
}
|
|
20863
|
+
return '';
|
|
20864
|
+
}
|
|
20865
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20866
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: GenericCalendarComponent, isStandalone: true, selector: "core-generic-calendar", inputs: { currentDate: { classPropertyName: "currentDate", publicName: "currentDate", isSignal: true, isRequired: false, transformFunction: null }, selectedDate: { classPropertyName: "selectedDate", publicName: "selectedDate", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, showNavigation: { classPropertyName: "showNavigation", publicName: "showNavigation", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateSelected: "dateSelected", monthChanged: "monthChanged" }, ngImport: i0, template: "<div class=\"c-bookings-calendar c-bookings-card\">\n @if (showHeader()) {\n <div class=\"c-bookings-card__top\">\n <h3 class=\"c-bookings-subtitle\">\n {{ monthName() | titlecase }} {{ year() }}\n </h3>\n @if (showNavigation()) {\n <div class=\"u-flex\">\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-left\"\n title=\"Anterior\"\n (click)=\"onPreviousMonth()\"\n ></button>\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-right\"\n title=\"Siguiente\"\n (click)=\"onNextMonth()\"\n ></button>\n </div>\n }\n </div>\n }\n\n <div class=\"c-calendar u-push-t\">\n @for (dayLabel of weekDayLabels(); track $index) {\n <span class=\"c-calendar__day-header\">{{ dayLabel }}</span>\n } @for (day of calendarDays(); track day.date.getTime()) {\n <button\n [class]=\"getDayClasses(day)\"\n [disabled]=\"day.disabled\"\n (click)=\"onDayClick(day)\"\n [title]=\"getDayTitle(day) || day.date.toLocaleDateString(locale())\"\n >\n {{ day.dayNumber }}\n </button>\n }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }] });
|
|
20867
|
+
}
|
|
20868
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericCalendarComponent, decorators: [{
|
|
20869
|
+
type: Component,
|
|
20870
|
+
args: [{ selector: 'core-generic-calendar', standalone: true, imports: [CommonModule], template: "<div class=\"c-bookings-calendar c-bookings-card\">\n @if (showHeader()) {\n <div class=\"c-bookings-card__top\">\n <h3 class=\"c-bookings-subtitle\">\n {{ monthName() | titlecase }} {{ year() }}\n </h3>\n @if (showNavigation()) {\n <div class=\"u-flex\">\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-left\"\n title=\"Anterior\"\n (click)=\"onPreviousMonth()\"\n ></button>\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-right\"\n title=\"Siguiente\"\n (click)=\"onNextMonth()\"\n ></button>\n </div>\n }\n </div>\n }\n\n <div class=\"c-calendar u-push-t\">\n @for (dayLabel of weekDayLabels(); track $index) {\n <span class=\"c-calendar__day-header\">{{ dayLabel }}</span>\n } @for (day of calendarDays(); track day.date.getTime()) {\n <button\n [class]=\"getDayClasses(day)\"\n [disabled]=\"day.disabled\"\n (click)=\"onDayClick(day)\"\n [title]=\"getDayTitle(day) || day.date.toLocaleDateString(locale())\"\n >\n {{ day.dayNumber }}\n </button>\n }\n </div>\n</div>\n" }]
|
|
20871
|
+
}], ctorParameters: () => [] });
|
|
20872
|
+
|
|
20873
|
+
const DEFAULT_SCHEDULER_CONFIG = {
|
|
20874
|
+
startHour: 6,
|
|
20875
|
+
endHour: 20,
|
|
20876
|
+
slotDuration: 30,
|
|
20877
|
+
rowHeightRem: 4,
|
|
20878
|
+
showCurrentTimeLine: true,
|
|
20879
|
+
locale: 'es-ES'
|
|
20880
|
+
};
|
|
20881
|
+
|
|
20882
|
+
class GenericSchedulerComponent {
|
|
20883
|
+
selectedDate = input(new Date());
|
|
20884
|
+
columns = input([]);
|
|
20885
|
+
events = input([]);
|
|
20886
|
+
config = input({});
|
|
20887
|
+
showTimeColumn = input(true);
|
|
20888
|
+
showHeader = input(true);
|
|
20889
|
+
timeColumnLabel = input('H');
|
|
20890
|
+
emptySlotLabel = input('Disponible');
|
|
20891
|
+
disabledSlotLabel = input('No disponible');
|
|
20892
|
+
todayLabel = input('Hoy');
|
|
20893
|
+
locale = input('es-ES');
|
|
20894
|
+
slotClick = output();
|
|
20895
|
+
eventClick = output();
|
|
20896
|
+
eventHover = output();
|
|
20897
|
+
eventLeave = output();
|
|
20898
|
+
todayClick = output();
|
|
20899
|
+
previousDay = output();
|
|
20900
|
+
nextDay = output();
|
|
20901
|
+
timeSlots = signal([]);
|
|
20902
|
+
currentTime = signal(new Date());
|
|
20903
|
+
timeUpdateInterval = null;
|
|
20904
|
+
mergedConfig = computed(() => ({ ...DEFAULT_SCHEDULER_CONFIG, ...this.config() }));
|
|
20905
|
+
isToday = computed(() => {
|
|
20906
|
+
const selected = this.selectedDate();
|
|
20907
|
+
const today = new Date();
|
|
20908
|
+
return selected.getUTCFullYear() === today.getUTCFullYear() &&
|
|
20909
|
+
selected.getUTCMonth() === today.getUTCMonth() &&
|
|
20910
|
+
selected.getUTCDate() === today.getUTCDate();
|
|
20911
|
+
});
|
|
20912
|
+
formattedDate = computed(() => {
|
|
20913
|
+
const date = this.selectedDate();
|
|
20914
|
+
const localeValue = this.locale();
|
|
20915
|
+
return date.toLocaleDateString(localeValue, {
|
|
20916
|
+
weekday: 'long',
|
|
20917
|
+
year: 'numeric',
|
|
20918
|
+
month: 'long',
|
|
20919
|
+
day: 'numeric',
|
|
20920
|
+
timeZone: 'UTC'
|
|
20921
|
+
});
|
|
20922
|
+
});
|
|
20923
|
+
currentTimePosition = computed(() => {
|
|
20924
|
+
if (!this.isToday() || !this.mergedConfig().showCurrentTimeLine)
|
|
20925
|
+
return null;
|
|
20926
|
+
const now = this.currentTime();
|
|
20927
|
+
const hours = now.getUTCHours();
|
|
20928
|
+
const minutes = now.getUTCMinutes();
|
|
20929
|
+
const cfg = this.mergedConfig();
|
|
20930
|
+
if (hours < cfg.startHour || hours >= cfg.endHour) {
|
|
20931
|
+
return null;
|
|
20932
|
+
}
|
|
20933
|
+
const minutesFromStart = (hours - cfg.startHour) * 60 + minutes;
|
|
20934
|
+
const slotsFromStart = minutesFromStart / cfg.slotDuration;
|
|
20935
|
+
const positionInRem = slotsFromStart * cfg.rowHeightRem;
|
|
20936
|
+
return positionInRem;
|
|
20937
|
+
});
|
|
20938
|
+
eventMap = computed(() => {
|
|
20939
|
+
const map = new Map();
|
|
20940
|
+
const evts = this.events();
|
|
20941
|
+
evts.forEach(event => {
|
|
20942
|
+
const key = event.columnId;
|
|
20943
|
+
if (!map.has(key)) {
|
|
20944
|
+
map.set(key, []);
|
|
20945
|
+
}
|
|
20946
|
+
map.get(key).push(event);
|
|
20947
|
+
});
|
|
20948
|
+
return map;
|
|
20949
|
+
});
|
|
20950
|
+
ngOnInit() {
|
|
20951
|
+
this.initializeTimeSlots();
|
|
20952
|
+
this.startTimeUpdater();
|
|
20953
|
+
}
|
|
20954
|
+
ngOnDestroy() {
|
|
20955
|
+
this.stopTimeUpdater();
|
|
20956
|
+
}
|
|
20957
|
+
initializeTimeSlots() {
|
|
20958
|
+
const cfg = this.mergedConfig();
|
|
20959
|
+
const slots = [];
|
|
20960
|
+
for (let hour = cfg.startHour; hour < cfg.endHour; hour++) {
|
|
20961
|
+
for (let minutes = 0; minutes < 60; minutes += cfg.slotDuration) {
|
|
20962
|
+
const timeString = `${hour.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
|
|
20963
|
+
const isHalfHour = minutes !== 0;
|
|
20964
|
+
slots.push({
|
|
20965
|
+
time: timeString,
|
|
20966
|
+
hour,
|
|
20967
|
+
minutes,
|
|
20968
|
+
isHalfHour,
|
|
20969
|
+
displayTime: !isHalfHour
|
|
20970
|
+
});
|
|
20971
|
+
}
|
|
20972
|
+
}
|
|
20973
|
+
this.timeSlots.set(slots);
|
|
20974
|
+
}
|
|
20975
|
+
startTimeUpdater() {
|
|
20976
|
+
this.currentTime.set(new Date());
|
|
20977
|
+
this.timeUpdateInterval = setInterval(() => {
|
|
20978
|
+
this.currentTime.set(new Date());
|
|
20979
|
+
}, 60000);
|
|
20980
|
+
}
|
|
20981
|
+
stopTimeUpdater() {
|
|
20982
|
+
if (this.timeUpdateInterval) {
|
|
20983
|
+
clearInterval(this.timeUpdateInterval);
|
|
20984
|
+
this.timeUpdateInterval = null;
|
|
20985
|
+
}
|
|
20986
|
+
}
|
|
20987
|
+
isSlotOccupied(columnId, slot) {
|
|
20988
|
+
const evts = this.eventMap().get(columnId) || [];
|
|
20989
|
+
return evts.some(event => this.isTimeInEvent(slot.time, event));
|
|
20990
|
+
}
|
|
20991
|
+
shouldShowEvent(columnId, slot) {
|
|
20992
|
+
const evts = this.eventMap().get(columnId) || [];
|
|
20993
|
+
return evts.some(event => event.startTime === slot.time);
|
|
20994
|
+
}
|
|
20995
|
+
getEventForSlot(columnId, slot) {
|
|
20996
|
+
const evts = this.eventMap().get(columnId) || [];
|
|
20997
|
+
return evts.find(event => event.startTime === slot.time);
|
|
20998
|
+
}
|
|
20999
|
+
getEventRowSpan(event) {
|
|
21000
|
+
if (event.rowSpan)
|
|
21001
|
+
return event.rowSpan;
|
|
21002
|
+
const cfg = this.mergedConfig();
|
|
21003
|
+
const slotsPerHour = 60 / cfg.slotDuration;
|
|
21004
|
+
return Math.ceil(event.duration / cfg.slotDuration) || 1;
|
|
21005
|
+
}
|
|
21006
|
+
isTimeInEvent(time, event) {
|
|
21007
|
+
const [slotHour, slotMin] = time.split(':').map(Number);
|
|
21008
|
+
const [startHour, startMin] = event.startTime.split(':').map(Number);
|
|
21009
|
+
const [endHour, endMin] = event.endTime.split(':').map(Number);
|
|
21010
|
+
const slotMinutes = slotHour * 60 + slotMin;
|
|
21011
|
+
const startMinutes = startHour * 60 + startMin;
|
|
21012
|
+
const endMinutes = endHour * 60 + endMin;
|
|
21013
|
+
return slotMinutes >= startMinutes && slotMinutes < endMinutes;
|
|
21014
|
+
}
|
|
21015
|
+
isSlotDisabled(columnId, slot) {
|
|
21016
|
+
const now = new Date();
|
|
21017
|
+
const selected = this.selectedDate();
|
|
21018
|
+
const todayUTC = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
|
|
21019
|
+
const selectedUTC = Date.UTC(selected.getUTCFullYear(), selected.getUTCMonth(), selected.getUTCDate());
|
|
21020
|
+
if (selectedUTC < todayUTC) {
|
|
21021
|
+
return true;
|
|
21022
|
+
}
|
|
21023
|
+
if (selectedUTC === todayUTC) {
|
|
21024
|
+
const [slotHour, slotMin] = slot.time.split(':').map(Number);
|
|
21025
|
+
const slotMinutes = slotHour * 60 + slotMin;
|
|
21026
|
+
const currentMinutes = now.getUTCHours() * 60 + now.getUTCMinutes();
|
|
21027
|
+
return slotMinutes < currentMinutes;
|
|
21028
|
+
}
|
|
21029
|
+
return false;
|
|
21030
|
+
}
|
|
21031
|
+
onSlotClick(columnId, slot) {
|
|
21032
|
+
if (this.isSlotOccupied(columnId, slot) || this.isSlotDisabled(columnId, slot)) {
|
|
21033
|
+
return;
|
|
21034
|
+
}
|
|
21035
|
+
this.slotClick.emit({
|
|
21036
|
+
columnId,
|
|
21037
|
+
slot,
|
|
21038
|
+
date: this.selectedDate()
|
|
21039
|
+
});
|
|
21040
|
+
}
|
|
21041
|
+
onEventClick(event, column) {
|
|
21042
|
+
this.eventClick.emit({ event, column });
|
|
21043
|
+
}
|
|
21044
|
+
onEventHover(mouseEvent, event) {
|
|
21045
|
+
this.eventHover.emit({
|
|
21046
|
+
event,
|
|
21047
|
+
position: { x: mouseEvent.clientX, y: mouseEvent.clientY }
|
|
21048
|
+
});
|
|
21049
|
+
}
|
|
21050
|
+
onEventLeave() {
|
|
21051
|
+
this.eventLeave.emit();
|
|
21052
|
+
}
|
|
21053
|
+
getEventClasses(event) {
|
|
21054
|
+
const classes = ['c-bookings-grid__booking'];
|
|
21055
|
+
if (event.type) {
|
|
21056
|
+
classes.push(`c-bookings-grid__booking--${event.type}`);
|
|
21057
|
+
}
|
|
21058
|
+
return classes.join(' ');
|
|
21059
|
+
}
|
|
21060
|
+
onTodayClick() {
|
|
21061
|
+
this.todayClick.emit();
|
|
21062
|
+
}
|
|
21063
|
+
onPreviousDay() {
|
|
21064
|
+
const current = this.selectedDate();
|
|
21065
|
+
const prevDay = new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), current.getUTCDate() - 1));
|
|
21066
|
+
this.previousDay.emit(prevDay);
|
|
21067
|
+
}
|
|
21068
|
+
onNextDay() {
|
|
21069
|
+
const current = this.selectedDate();
|
|
21070
|
+
const nextDayDate = new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), current.getUTCDate() + 1));
|
|
21071
|
+
this.nextDay.emit(nextDayDate);
|
|
21072
|
+
}
|
|
21073
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericSchedulerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
21074
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: GenericSchedulerComponent, isStandalone: true, selector: "core-generic-scheduler", inputs: { selectedDate: { classPropertyName: "selectedDate", publicName: "selectedDate", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, showTimeColumn: { classPropertyName: "showTimeColumn", publicName: "showTimeColumn", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, timeColumnLabel: { classPropertyName: "timeColumnLabel", publicName: "timeColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, emptySlotLabel: { classPropertyName: "emptySlotLabel", publicName: "emptySlotLabel", isSignal: true, isRequired: false, transformFunction: null }, disabledSlotLabel: { classPropertyName: "disabledSlotLabel", publicName: "disabledSlotLabel", isSignal: true, isRequired: false, transformFunction: null }, todayLabel: { classPropertyName: "todayLabel", publicName: "todayLabel", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { slotClick: "slotClick", eventClick: "eventClick", eventHover: "eventHover", eventLeave: "eventLeave", todayClick: "todayClick", previousDay: "previousDay", nextDay: "nextDay" }, host: { properties: { "style.--cols": "columns().length" }, classAttribute: "c-bookings-grid c-bookings-card" }, ngImport: i0, template: "@if (showHeader()) {\n<div class=\"c-bookings-header\">\n <button class=\"c-bookings-header__today\" (click)=\"onTodayClick()\">\n {{ todayLabel() }}\n </button>\n\n <div class=\"c-bookings-header__date\">\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-left\"\n title=\"D\u00EDa anterior\"\n (click)=\"onPreviousDay()\"\n ></button>\n <span>{{ formattedDate() }}</span>\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-right\"\n title=\"D\u00EDa siguiente\"\n (click)=\"onNextDay()\"\n ></button>\n </div>\n</div>\n}\n\n<div\n class=\"c-bookings-grid__wrapper\"\n [style.--cols]=\"columns().length\"\n style=\"position: relative\"\n>\n @if (isToday() && currentTimePosition() !== null) {\n <div\n class=\"c-bookings-grid__current-time-line\"\n [style.--time-position-rem]=\"currentTimePosition()\"\n ></div>\n } @if (showTimeColumn()) {\n <div class=\"c-bookings-grid__times\">\n <div class=\"c-bookings-grid__top\">\n <div class=\"c-bookings-grid__title\">{{ timeColumnLabel() }}</div>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (slot.displayTime) {\n <span class=\"c-bookings-grid__time\">{{ slot.time }}</span>\n }\n </div>\n }\n </div>\n } @for (column of columns(); track column.id) {\n <div class=\"c-bookings-grid__col\">\n <div class=\"c-bookings-grid__top\">\n <p class=\"c-bookings-grid__title\">{{ column.name }}</p>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (!isSlotOccupied(column.id, slot)) { @if (isSlotDisabled(column.id,\n slot)) {\n <button\n class=\"c-bookings-grid__slot c-bookings-grid__slot--disabled\"\n disabled\n [title]=\"disabledSlotLabel()\"\n >\n {{ disabledSlotLabel() }}\n </button>\n } @else {\n <button\n class=\"c-bookings-grid__slot\"\n [title]=\"emptySlotLabel()\"\n (click)=\"onSlotClick(column.id, slot)\"\n >\n {{ emptySlotLabel() }}\n </button>\n } } @if (shouldShowEvent(column.id, slot)) { @let event =\n getEventForSlot(column.id, slot); @if (event) {\n <div\n [class]=\"getEventClasses(event)\"\n [attr.data-type]=\"event.type\"\n [attr.data-status]=\"event.status\"\n [style.--rows]=\"getEventRowSpan(event)\"\n (mouseenter)=\"onEventHover($event, event)\"\n (mouseleave)=\"onEventLeave()\"\n (click)=\"onEventClick(event, column)\"\n >\n <p class=\"c-bookings-grid__title\">\n {{ event.subtitle || event.title }}\n </p>\n <p class=\"c-bookings-grid__text\">\n {{ event.startTime }} - {{ event.endTime }}\n </p>\n\n @if (event.canCancel) {\n <button\n class=\"c-bookings-grid__link c-link--underlined\"\n (click)=\"$event.stopPropagation()\"\n >\n <span class=\"icon-cross-thin\"></span>\n Cancelar\n </button>\n } @if ((event.canApprove || event.canReject) && event.duration >= 91) {\n <div class=\"c-bookings-grid__quick-actions\">\n @if (event.canApprove) {\n <button\n class=\"c-icon-btn--fill context:success icon-check\"\n title=\"Aprobar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n } @if (event.canReject) {\n <button\n class=\"c-icon-btn--fill context:error icon-cross\"\n title=\"Rechazar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n }\n </div>\n }\n </div>\n } }\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;overflow:visible}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
21075
|
+
}
|
|
21076
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericSchedulerComponent, decorators: [{
|
|
21077
|
+
type: Component,
|
|
21078
|
+
args: [{ selector: 'core-generic-scheduler', standalone: true, imports: [CommonModule], host: {
|
|
21079
|
+
'class': 'c-bookings-grid c-bookings-card',
|
|
21080
|
+
'[style.--cols]': 'columns().length'
|
|
21081
|
+
}, template: "@if (showHeader()) {\n<div class=\"c-bookings-header\">\n <button class=\"c-bookings-header__today\" (click)=\"onTodayClick()\">\n {{ todayLabel() }}\n </button>\n\n <div class=\"c-bookings-header__date\">\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-left\"\n title=\"D\u00EDa anterior\"\n (click)=\"onPreviousDay()\"\n ></button>\n <span>{{ formattedDate() }}</span>\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-right\"\n title=\"D\u00EDa siguiente\"\n (click)=\"onNextDay()\"\n ></button>\n </div>\n</div>\n}\n\n<div\n class=\"c-bookings-grid__wrapper\"\n [style.--cols]=\"columns().length\"\n style=\"position: relative\"\n>\n @if (isToday() && currentTimePosition() !== null) {\n <div\n class=\"c-bookings-grid__current-time-line\"\n [style.--time-position-rem]=\"currentTimePosition()\"\n ></div>\n } @if (showTimeColumn()) {\n <div class=\"c-bookings-grid__times\">\n <div class=\"c-bookings-grid__top\">\n <div class=\"c-bookings-grid__title\">{{ timeColumnLabel() }}</div>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (slot.displayTime) {\n <span class=\"c-bookings-grid__time\">{{ slot.time }}</span>\n }\n </div>\n }\n </div>\n } @for (column of columns(); track column.id) {\n <div class=\"c-bookings-grid__col\">\n <div class=\"c-bookings-grid__top\">\n <p class=\"c-bookings-grid__title\">{{ column.name }}</p>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (!isSlotOccupied(column.id, slot)) { @if (isSlotDisabled(column.id,\n slot)) {\n <button\n class=\"c-bookings-grid__slot c-bookings-grid__slot--disabled\"\n disabled\n [title]=\"disabledSlotLabel()\"\n >\n {{ disabledSlotLabel() }}\n </button>\n } @else {\n <button\n class=\"c-bookings-grid__slot\"\n [title]=\"emptySlotLabel()\"\n (click)=\"onSlotClick(column.id, slot)\"\n >\n {{ emptySlotLabel() }}\n </button>\n } } @if (shouldShowEvent(column.id, slot)) { @let event =\n getEventForSlot(column.id, slot); @if (event) {\n <div\n [class]=\"getEventClasses(event)\"\n [attr.data-type]=\"event.type\"\n [attr.data-status]=\"event.status\"\n [style.--rows]=\"getEventRowSpan(event)\"\n (mouseenter)=\"onEventHover($event, event)\"\n (mouseleave)=\"onEventLeave()\"\n (click)=\"onEventClick(event, column)\"\n >\n <p class=\"c-bookings-grid__title\">\n {{ event.subtitle || event.title }}\n </p>\n <p class=\"c-bookings-grid__text\">\n {{ event.startTime }} - {{ event.endTime }}\n </p>\n\n @if (event.canCancel) {\n <button\n class=\"c-bookings-grid__link c-link--underlined\"\n (click)=\"$event.stopPropagation()\"\n >\n <span class=\"icon-cross-thin\"></span>\n Cancelar\n </button>\n } @if ((event.canApprove || event.canReject) && event.duration >= 91) {\n <div class=\"c-bookings-grid__quick-actions\">\n @if (event.canApprove) {\n <button\n class=\"c-icon-btn--fill context:success icon-check\"\n title=\"Aprobar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n } @if (event.canReject) {\n <button\n class=\"c-icon-btn--fill context:error icon-cross\"\n title=\"Rechazar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n }\n </div>\n }\n </div>\n } }\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;overflow:visible}\n"] }]
|
|
21082
|
+
}] });
|
|
21083
|
+
|
|
20474
21084
|
class CacheBustingInterceptor {
|
|
20475
21085
|
intercept(req, next) {
|
|
20476
21086
|
if (req.url.includes('/assets/i18n/') && req.url.endsWith('.json')) {
|
|
@@ -20752,5 +21362,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
|
|
|
20752
21362
|
* Generated bundle index. Do not edit.
|
|
20753
21363
|
*/
|
|
20754
21364
|
|
|
20755
|
-
export { AD_AUTH_CONFIG, AD_AUTH_INTERCEPTOR_CONFIG, ALL_COUNTRY_CODES, ActiveFiltersComponent, AdAuthService, AdInteractionType, AdLoginButtonComponent, AgeValidationHelper, AlertComponent, AlertContainerComponent, AlertService, AlertType, ApiConfigurationProvider, BaseFieldComponent, ButtonContext, ButtonSize, ButtonType, COMMON_COUNTRIES, CacheBustingInterceptor, CardComponent, CarouselComponent, ChatMessagePosition, ChatMessageType, CheckboxFieldComponent, ConfigurationModel, ConfirmationDialogComponent, ConfirmationDialogService, CoreHostDirective, CoreManualRefreshComponent, CoreUiHttpLoaderFactory, CoreUiTranslateLoader, CoreUiTranslateService, CountryCode, CustomClassService, DEFAULT_AD_AUTH_INTERCEPTOR_CONFIG, DEFAULT_COUNTRIES, DataListComponent, DataListItemComponent, DataStoreService, DateFieldComponent, DateUtility, DatetimeFieldComponent, DialogActions, DocumentAction, DocumentDisplayMode, DocumentFieldComponent, DocumentFieldValidators, DocumentPayloadMode, DropdownComponent, DropdownDirection, DropdownService, DynamicFieldDirective, DynamicFieldsHelper, FieldErrorsComponent, FieldType, FileFieldComponent, FileModel, FilePreviewActionType, FileTemplateModel, FileTemplateType, FileType, FileTypeModel, FileUploadService, FilterModalComponent, FilterService, FilterType, FixedActionPosition, FixedActionsMobileModalComponent, FixedActionsMobileModalService, GalleryAnimationType, GalleryLayoutType, GalleryModalComponent, GalleryModalGlobalService, GenericButtonComponent, GenericChatComponent, GenericChatService, GenericDocumentationComponent, GenericFixedActionsComponent, GenericGalleryComponent, GenericModalComponent, GenericPaginationComponent, GenericRatingComponent, GenericSidebarComponent, GenericSkeletonComponent, GenericStepsComponent, GenericSwitchComponent, GenericTableComponent, GenericTabsComponent, GenericTimelineComponent, GlobalApiConfigService, HeaderComponent, HeaderConfigurationService, HeaderElementType, HeaderService, HttpLoaderFactory, ImageModalComponent, ImageModalService, ImagePreviewComponent, LATIN_AMERICA_COUNTRIES, LayoutAuth, LayoutBreakpoint, LayoutComponent, LayoutService, LayoutStateService, LayoutType, LoaderComponent, LoaderService, MODEL_REFERENCE_SORT_KEY, MainNavComponent, MainNavService, ManualRefreshService, MobileHeaderComponent, MobileResolutionService, ModalMode, ModelApiService, MultiEntryFieldComponent, MultiEntryOutputFormat, NumberFieldComponent, NumberFieldConfigType, NumberFieldType, NumberRange, PERMISSION_ACTIONS_PROVIDER, PERMISSION_PROVIDER, PERMISSION_RESOURCES_PROVIDER, PaginationService, PasswordFieldComponent, PermissionEnumsService, PermissionModel, PermissionService, PermissionWrapperService, PermissionsActions, PermissionsCustomActions, PermissionsInterceptor, PermissionsResources, PhoneFieldComponent, ProgressBarComponent, ProgressBarSize, RatingService, RatingSize, RatingType, RedirectUrlService, ResetPasswordModel, RoleModel, SOUTH_AMERICA_COUNTRIES, SelectFieldComponent, ServerSelectFieldComponent, ServerSelectService, SidebarCustomModalComponent, SidebarCustomModalService, SidebarHeight, SidebarMobileModalService, SidebarMobileType, SidebarPosition, SidebarService, SidebarState, SidebarTemplateRegistryService, SidebarVisibility, SidebarWidth, SkeletonAnimation, SkeletonService, SkeletonSize, SkeletonType, SmartFieldComponent, SortDirection, SortMode, StepSize, StepStatus, StepType, StepsService, SwitchFieldComponent, TableAction, TableActionService, TableDataService, TableFixedActionsService, TableSortService, TextAreaFieldComponent, TextFieldComponent, TimeFieldComponent, TimeInterval, TimelineService, TimelineStatus, TimelineType, TranslationMergeService, UruguayanDocumentValidationHelper, UsersModel, VERSION, adAuthGuard, adAuthInterceptor, adGuestGuard, adRoleGuard, ageValidator, calculateAge, equalToValidator, generateRandomUruguayanDocument, getCountryCodeStrings, getLatestBirthDateForAge, getRandomCi, getUruguayanDocumentValidationDigit, getValidationDigit, isSameDate, isValidCountryCode, provideAdAuth, provideAdAuthInterceptor, provideAdAuthWithInterceptor, provideCoreUiTranslateLoader, providePermissionActions, providePermissionEnums, providePermissionResources, providePermissionService, providePermissionServiceFactory, provideTranslateLoader, random, transform, transformUruguayanDocument, uruguayanDocumentValidator, validate, validateAge, validateCi, validateUruguayanDocument, validationDigit };
|
|
21365
|
+
export { AD_AUTH_CONFIG, AD_AUTH_INTERCEPTOR_CONFIG, ALL_COUNTRY_CODES, ActiveFiltersComponent, AdAuthService, AdInteractionType, AdLoginButtonComponent, AgeValidationHelper, AlertComponent, AlertContainerComponent, AlertService, AlertType, ApiConfigurationProvider, BaseFieldComponent, ButtonContext, ButtonSize, ButtonType, COMMON_COUNTRIES, CacheBustingInterceptor, CalendarEventType, CardComponent, CarouselComponent, ChatMessagePosition, ChatMessageType, CheckboxFieldComponent, ConfigurationModel, ConfirmationDialogComponent, ConfirmationDialogService, CoreHostDirective, CoreManualRefreshComponent, CoreUiHttpLoaderFactory, CoreUiTranslateLoader, CoreUiTranslateService, CountryCode, CustomClassService, DEFAULT_AD_AUTH_INTERCEPTOR_CONFIG, DEFAULT_COUNTRIES, DEFAULT_SCHEDULER_CONFIG, DataListComponent, DataListItemComponent, DataStoreService, DateFieldComponent, DateUtility, DatetimeFieldComponent, DayState, DayType, DialogActions, DocumentAction, DocumentDisplayMode, DocumentFieldComponent, DocumentFieldValidators, DocumentPayloadMode, DropdownComponent, DropdownDirection, DropdownService, DynamicFieldDirective, DynamicFieldsHelper, FieldErrorsComponent, FieldType, FileFieldComponent, FileModel, FilePreviewActionType, FileTemplateModel, FileTemplateType, FileType, FileTypeModel, FileUploadService, FilterModalComponent, FilterService, FilterType, FixedActionPosition, FixedActionsMobileModalComponent, FixedActionsMobileModalService, GalleryAnimationType, GalleryLayoutType, GalleryModalComponent, GalleryModalGlobalService, GenericButtonComponent, GenericCalendarComponent, GenericChatComponent, GenericChatService, GenericDocumentationComponent, GenericFixedActionsComponent, GenericGalleryComponent, GenericModalComponent, GenericPaginationComponent, GenericRatingComponent, GenericSchedulerComponent, GenericSidebarComponent, GenericSkeletonComponent, GenericStepsComponent, GenericSwitchComponent, GenericTableComponent, GenericTabsComponent, GenericTimelineComponent, GlobalApiConfigService, HeaderComponent, HeaderConfigurationService, HeaderElementType, HeaderService, HttpLoaderFactory, ImageModalComponent, ImageModalService, ImagePreviewComponent, LATIN_AMERICA_COUNTRIES, LayoutAuth, LayoutBreakpoint, LayoutComponent, LayoutService, LayoutStateService, LayoutType, LoaderComponent, LoaderService, MODEL_REFERENCE_SORT_KEY, MainNavComponent, MainNavService, ManualRefreshService, MobileHeaderComponent, MobileResolutionService, ModalMode, ModelApiService, MultiEntryFieldComponent, MultiEntryOutputFormat, NumberFieldComponent, NumberFieldConfigType, NumberFieldType, NumberRange, PERMISSION_ACTIONS_PROVIDER, PERMISSION_PROVIDER, PERMISSION_RESOURCES_PROVIDER, PaginationService, PasswordFieldComponent, PermissionEnumsService, PermissionModel, PermissionService, PermissionWrapperService, PermissionsActions, PermissionsCustomActions, PermissionsInterceptor, PermissionsResources, PhoneFieldComponent, ProgressBarComponent, ProgressBarSize, RatingService, RatingSize, RatingType, RedirectUrlService, ResetPasswordModel, RoleModel, SOUTH_AMERICA_COUNTRIES, SelectFieldComponent, ServerSelectFieldComponent, ServerSelectService, SidebarCustomModalComponent, SidebarCustomModalService, SidebarHeight, SidebarMobileModalService, SidebarMobileType, SidebarPosition, SidebarService, SidebarState, SidebarTemplateRegistryService, SidebarVisibility, SidebarWidth, SkeletonAnimation, SkeletonService, SkeletonSize, SkeletonType, SmartFieldComponent, SortDirection, SortMode, StepSize, StepStatus, StepType, StepsService, SwitchFieldComponent, TableAction, TableActionService, TableDataService, TableFixedActionsService, TableSortService, TextAreaFieldComponent, TextFieldComponent, TimeFieldComponent, TimeInterval, TimelineService, TimelineStatus, TimelineType, TranslationMergeService, UruguayanDocumentValidationHelper, UsersModel, VERSION, WeekDay, adAuthGuard, adAuthInterceptor, adGuestGuard, adRoleGuard, ageValidator, calculateAge, equalToValidator, generateRandomUruguayanDocument, getCountryCodeStrings, getLatestBirthDateForAge, getRandomCi, getUruguayanDocumentValidationDigit, getValidationDigit, isSameDate, isValidCountryCode, provideAdAuth, provideAdAuthInterceptor, provideAdAuthWithInterceptor, provideCoreUiTranslateLoader, providePermissionActions, providePermissionEnums, providePermissionResources, providePermissionService, providePermissionServiceFactory, provideTranslateLoader, random, transform, transformUruguayanDocument, uruguayanDocumentValidator, validate, validateAge, validateCi, validateUruguayanDocument, validationDigit };
|
|
20756
21366
|
//# sourceMappingURL=solcre-org-core-ui.mjs.map
|