@acorex/modules 19.3.5 → 19.3.6
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/dashboard-management/lib/features/home-dashboard/dashboard-home/home-dashboard.d.ts +5 -7
- package/dashboard-management/lib/features/home-dashboard/dashboard-popups/dashboard-popup.service.d.ts +1 -0
- package/dashboard-management/lib/features/home-dashboard/widget-wrapper/dashboard-widget-wrapper.d.ts +2 -1
- package/dashboard-management/lib/features/shared/widgets/weather/weather-widget.component.d.ts +5 -0
- package/fesm2022/{acorex-modules-auth-acorex-modules-auth-VeeGJcyl.mjs → acorex-modules-auth-acorex-modules-auth-bj5xztse.mjs} +9 -9
- package/fesm2022/{acorex-modules-auth-acorex-modules-auth-VeeGJcyl.mjs.map → acorex-modules-auth-acorex-modules-auth-bj5xztse.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-app-chooser.component-IhAQfHJU.mjs → acorex-modules-auth-app-chooser.component-BOL3VzC1.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-app-chooser.component-IhAQfHJU.mjs.map → acorex-modules-auth-app-chooser.component-BOL3VzC1.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-login.module-B8qqaCq8.mjs → acorex-modules-auth-login.module-C1AoXhCI.mjs} +4 -4
- package/fesm2022/{acorex-modules-auth-login.module-B8qqaCq8.mjs.map → acorex-modules-auth-login.module-C1AoXhCI.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-master.layout-egA9357P.mjs → acorex-modules-auth-master.layout-vuHfrDxu.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-master.layout-egA9357P.mjs.map → acorex-modules-auth-master.layout-vuHfrDxu.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-BimdcHXP.mjs → acorex-modules-auth-password.component-C71v2x71.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-BimdcHXP.mjs.map → acorex-modules-auth-password.component-C71v2x71.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-BMWDHmu6.mjs → acorex-modules-auth-password.component-Dtcz95NV.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-BMWDHmu6.mjs.map → acorex-modules-auth-password.component-Dtcz95NV.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-routes-BYT58dkA.mjs → acorex-modules-auth-routes-lJgHFaQR.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-routes-BYT58dkA.mjs.map → acorex-modules-auth-routes-lJgHFaQR.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-two-factor.module-B_g4P4is.mjs → acorex-modules-auth-two-factor.module-C9SfEHF7.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-two-factor.module-B_g4P4is.mjs.map → acorex-modules-auth-two-factor.module-C9SfEHF7.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-user-sessions.component-DvYAh9cg.mjs → acorex-modules-auth-user-sessions.component-CCsoLecU.mjs} +4 -4
- package/fesm2022/acorex-modules-auth-user-sessions.component-CCsoLecU.mjs.map +1 -0
- package/fesm2022/acorex-modules-auth.mjs +1 -1
- package/fesm2022/acorex-modules-dashboard-management.mjs +335 -232
- package/fesm2022/acorex-modules-dashboard-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-notification-management.mjs +11 -11
- package/fesm2022/acorex-modules-notification-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-security-management.mjs +1 -1
- package/fesm2022/acorex-modules-security-management.mjs.map +1 -1
- package/package.json +1 -1
- package/fesm2022/acorex-modules-auth-user-sessions.component-DvYAh9cg.mjs.map +0 -1
@@ -38,14 +38,14 @@ import { AXCheckBoxModule } from '@acorex/components/check-box';
|
|
38
38
|
import { AXImageModule } from '@acorex/components/image';
|
39
39
|
import { AXLabelModule } from '@acorex/components/label';
|
40
40
|
import { AXTabsModule } from '@acorex/components/tabs';
|
41
|
-
import * as
|
41
|
+
import * as i2$3 from '@acorex/core/translation';
|
42
42
|
import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
|
43
43
|
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
44
44
|
import { AXPopupService } from '@acorex/components/popup';
|
45
45
|
import { AXP_GLOBAL_SEARCH_CONFIG_TOKEN } from '@acorex/modules/common';
|
46
46
|
import { AXPDataGenerator, AXPPlatformScope } from '@acorex/platform/core';
|
47
47
|
import { AXPWorkflowService } from '@acorex/platform/workflow';
|
48
|
-
import {
|
48
|
+
import { ActivatedRoute, Router } from '@angular/router';
|
49
49
|
import { AXBreadcrumbsModule } from '@acorex/components/breadcrumbs';
|
50
50
|
import { AXButtonGroupModule } from '@acorex/components/button-group';
|
51
51
|
import { AXDialogService } from '@acorex/components/dialog';
|
@@ -55,12 +55,14 @@ import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
|
|
55
55
|
import { AXPWidgetPropertyViewerComponent, AXPWidgetPickerService, AXPDesignerService } from '@acorex/platform/layout/designer';
|
56
56
|
import { AXPBasePageComponent, AXPPageLayoutComponent, AXPBasePage } from '@acorex/platform/themes/default';
|
57
57
|
import { AXPLayoutThemeService, AXPThemeLayoutBlockComponent } from '@acorex/platform/themes/shared';
|
58
|
-
import * as i2$
|
58
|
+
import * as i2$4 from '@acorex/components/loading';
|
59
59
|
import { AXLoadingModule } from '@acorex/components/loading';
|
60
60
|
import { signalStore, withState, withComputed, withMethods, patchState } from '@ngrx/signals';
|
61
61
|
import { AXBasePageComponent } from '@acorex/components/page';
|
62
62
|
import * as i7 from '@acorex/components/select-box';
|
63
63
|
import { AXSelectBoxModule } from '@acorex/components/select-box';
|
64
|
+
import * as i8 from '@acorex/components/switch';
|
65
|
+
import { AXSwitchModule } from '@acorex/components/switch';
|
64
66
|
import * as i3$3 from '@acorex/components/text-box';
|
65
67
|
import { AXTextBoxModule } from '@acorex/components/text-box';
|
66
68
|
import { AXMOrganizationManagementRoleEntityService } from '@acorex/modules/organization-management';
|
@@ -496,7 +498,7 @@ const AXPBarChartWidget = {
|
|
496
498
|
// ====== Chart Title ======
|
497
499
|
{
|
498
500
|
name: 'title',
|
499
|
-
title: '
|
501
|
+
title: '@dashboard:widgets.bar-chart.chart-title',
|
500
502
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
501
503
|
schema: {
|
502
504
|
defaultValue: '',
|
@@ -515,7 +517,7 @@ const AXPBarChartWidget = {
|
|
515
517
|
// ====== Layout & Dimensions ======
|
516
518
|
{
|
517
519
|
name: 'width',
|
518
|
-
title: '
|
520
|
+
title: '@dashboard:widgets.bar-chart.width',
|
519
521
|
group: AXP_STYLING_PROPERTY_GROUP,
|
520
522
|
schema: {
|
521
523
|
defaultValue: null,
|
@@ -534,7 +536,7 @@ const AXPBarChartWidget = {
|
|
534
536
|
},
|
535
537
|
{
|
536
538
|
name: 'height',
|
537
|
-
title: '
|
539
|
+
title: '@dashboard:widgets.bar-chart.height',
|
538
540
|
group: AXP_STYLING_PROPERTY_GROUP,
|
539
541
|
schema: {
|
540
542
|
defaultValue: 300,
|
@@ -554,7 +556,7 @@ const AXPBarChartWidget = {
|
|
554
556
|
// ====== X Axis Settings ======
|
555
557
|
{
|
556
558
|
name: 'showXAxis',
|
557
|
-
title: '
|
559
|
+
title: '@dashboard:widgets.bar-chart.show-x-axis',
|
558
560
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
559
561
|
schema: {
|
560
562
|
defaultValue: true,
|
@@ -569,7 +571,7 @@ const AXPBarChartWidget = {
|
|
569
571
|
},
|
570
572
|
{
|
571
573
|
name: 'xAxisLabel',
|
572
|
-
title: '
|
574
|
+
title: '@dashboard:widgets.bar-chart.x-axis-label',
|
573
575
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
574
576
|
schema: {
|
575
577
|
defaultValue: '',
|
@@ -585,7 +587,7 @@ const AXPBarChartWidget = {
|
|
585
587
|
// ====== Y Axis Settings ======
|
586
588
|
{
|
587
589
|
name: 'showYAxis',
|
588
|
-
title: '
|
590
|
+
title: '@dashboard:widgets.bar-chart.show-y-axis',
|
589
591
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
590
592
|
schema: {
|
591
593
|
defaultValue: true,
|
@@ -600,7 +602,7 @@ const AXPBarChartWidget = {
|
|
600
602
|
},
|
601
603
|
{
|
602
604
|
name: 'yAxisLabel',
|
603
|
-
title: '
|
605
|
+
title: '@dashboard:widgets.bar-chart.y-axis-label',
|
604
606
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
605
607
|
schema: {
|
606
608
|
defaultValue: '',
|
@@ -616,7 +618,7 @@ const AXPBarChartWidget = {
|
|
616
618
|
// ====== Bar Appearance ======
|
617
619
|
{
|
618
620
|
name: 'barWidth',
|
619
|
-
title: '
|
621
|
+
title: '@dashboard:widgets.bar-chart.bar-width',
|
620
622
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
621
623
|
schema: {
|
622
624
|
defaultValue: 80,
|
@@ -636,7 +638,7 @@ const AXPBarChartWidget = {
|
|
636
638
|
},
|
637
639
|
{
|
638
640
|
name: 'cornerRadius',
|
639
|
-
title: '
|
641
|
+
title: '@dashboard:widgets.bar-chart.corner-radius',
|
640
642
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
641
643
|
schema: {
|
642
644
|
defaultValue: 4,
|
@@ -657,7 +659,7 @@ const AXPBarChartWidget = {
|
|
657
659
|
// ====== Grid Settings ======
|
658
660
|
{
|
659
661
|
name: 'showGrid',
|
660
|
-
title: '
|
662
|
+
title: '@dashboard:widgets.bar-chart.show-grid',
|
661
663
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
662
664
|
schema: {
|
663
665
|
defaultValue: true,
|
@@ -672,7 +674,7 @@ const AXPBarChartWidget = {
|
|
672
674
|
},
|
673
675
|
{
|
674
676
|
name: 'showDataLabels',
|
675
|
-
title: '
|
677
|
+
title: '@dashboard:widgets.bar-chart.show-data-labels',
|
676
678
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
677
679
|
schema: {
|
678
680
|
defaultValue: true,
|
@@ -688,7 +690,7 @@ const AXPBarChartWidget = {
|
|
688
690
|
// ====== Tooltip Settings ======
|
689
691
|
{
|
690
692
|
name: 'showTooltip',
|
691
|
-
title: '
|
693
|
+
title: '@dashboard:widgets.bar-chart.show-tooltip',
|
692
694
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
693
695
|
schema: {
|
694
696
|
defaultValue: true,
|
@@ -704,7 +706,7 @@ const AXPBarChartWidget = {
|
|
704
706
|
// ====== Animation Settings ======
|
705
707
|
{
|
706
708
|
name: 'animationEasing',
|
707
|
-
title: '
|
709
|
+
title: '@dashboard:widgets.bar-chart.animation-easing',
|
708
710
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
709
711
|
schema: {
|
710
712
|
defaultValue: 'cubic-out',
|
@@ -734,7 +736,7 @@ const AXPBarChartWidget = {
|
|
734
736
|
},
|
735
737
|
{
|
736
738
|
name: 'animationDuration',
|
737
|
-
title: '
|
739
|
+
title: '@dashboard:widgets.bar-chart.animation-duration',
|
738
740
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
739
741
|
schema: {
|
740
742
|
defaultValue: 800,
|
@@ -803,7 +805,7 @@ class AXPClockCalendarWidgetViewComponent extends AXPValueWidgetComponent {
|
|
803
805
|
this.showDayOfWeek = computed(() => this.options()?.showDayOfWeek !== false);
|
804
806
|
this.use24Hour = computed(() => this.options()?.use24Hour === true);
|
805
807
|
this.showSeconds = computed(() => this.options()?.showSeconds !== false);
|
806
|
-
this.dateFormat = computed(() => this.options()?.dateFormat?.id ?? '
|
808
|
+
this.dateFormat = computed(() => this.options()?.dateFormat?.id ?? 'DD MMM YYYY');
|
807
809
|
this.timezone = computed(() => this.options()?.timezone?.id ?? 'local');
|
808
810
|
// protected readonly showTimezoneIndicator: Signal<boolean> = computed(() => this.timezone() !== 'local');
|
809
811
|
this.displayTimezone = computed(() => {
|
@@ -893,11 +895,11 @@ class AXPClockCalendarWidgetViewComponent extends AXPValueWidgetComponent {
|
|
893
895
|
return days[this.currentDate.getDay()];
|
894
896
|
}
|
895
897
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPClockCalendarWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
896
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPClockCalendarWidgetViewComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"axp-clock-calendar-container\">\n <!-- Timezone indicator (only shown when not local) -->\n <!-- @if (showTimezoneIndicator()) {\n <div class=\"axp-clock-calendar-timezone-badge\"><i class=\"fa-solid fa-globe\"></i> {{ displayTimezone() }}</div>\n } -->\n\n <!-- Day of week display -->\n @if (showDayOfWeek()) {\n
|
898
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPClockCalendarWidgetViewComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"axp-clock-calendar-container\">\n <!-- Timezone indicator (only shown when not local) -->\n <!-- @if (showTimezoneIndicator()) {\n <div class=\"axp-clock-calendar-timezone-badge\"><i class=\"fa-solid fa-globe\"></i> {{ displayTimezone() }}</div>\n } -->\n\n <!-- Day of week display -->\n @if (showDayOfWeek()) {\n <div class=\"axp-clock-calendar-day-label\">{{ getDayOfWeek() }}</div>\n }\n\n <div class=\"axp-clock-calendar-content\">\n <!-- Digital Clock Display -->\n @if (showDigitalClock()) {\n <div class=\"axp-clock-calendar-digital-clock\">\n {{ currentTime | format: 'datetime' : timeFormat() | async }}\n </div>\n }\n\n <!-- Analog Clock Display -->\n @if (showAnalogClock()) {\n <div class=\"axp-clock-calendar-analog-clock\">\n <!-- Hour markers -->\n @for (hour of clockHours; track hour) {\n <div\n class=\"axp-clock-calendar-hour-marker\"\n [style.transform]=\"'rotate(' + hour * 30 + 'deg) translateY(-80px)'\"\n ></div>\n }\n\n <!-- Clock Numbers -->\n <div class=\"axp-clock-calendar-numbers-container\">\n @for (hour of clockHourNumbers; track hour) {\n <div\n class=\"axp-clock-calendar-hour-number\"\n [style.transform]=\"'rotate(' + hour.angle + 'deg) translateY(-82px)'\"\n >\n <span [style.transform]=\"'rotate(' + -hour.angle + 'deg)'\">{{ hour.number }}</span>\n </div>\n }\n </div>\n\n <!-- Clock Hands -->\n <div class=\"axp-clock-calendar-hands-container\">\n <div class=\"axp-clock-calendar-hour-hand\" [style.transform]=\"'rotate(' + hourRotation + 'deg)'\"></div>\n <div class=\"axp-clock-calendar-minute-hand\" [style.transform]=\"'rotate(' + minuteRotation + 'deg)'\"></div>\n @if (showSeconds()) {\n <div class=\"axp-clock-calendar-second-hand\" [style.transform]=\"'rotate(' + secondRotation + 'deg)'\"></div>\n }\n <div class=\"axp-clock-calendar-center-dot\"></div>\n </div>\n </div>\n }\n\n <!-- Date Display -->\n @if (showDate()) {\n <div class=\"axp-clock-calendar-date-display\">\n <i class=\"fa-regular fa-calendar\"></i>\n {{ currentDate | format: 'datetime' : dateFormat() | async }}\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%;height:100%}.axp-clock-calendar-container{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;padding:1rem;position:relative;overflow:hidden;box-shadow:var(--ax-shadow-sm);background-color:var(--ax-surface-color);color:var(--ax-text-color)}.axp-clock-calendar-content{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;width:100%;height:100%;position:relative}.axp-clock-calendar-timezone-badge{position:absolute;top:.5rem;right:.5rem;font-size:.75rem;padding:.25rem;border-radius:1rem;border-width:1px;border-color:rgba(23,23,23,.5)}.axp-clock-calendar-timezone-badge:is(.ax-dark *){border-color:rgba(245,245,245,.5)}.axp-clock-calendar-timezone-badge{display:flex;align-items:center;gap:.25rem}.axp-clock-calendar-timezone-badge i{font-size:.75rem}.axp-clock-calendar-day-label{font-size:.9rem;font-weight:600;text-transform:uppercase;letter-spacing:.05rem;margin-bottom:.25rem}.axp-clock-calendar-digital-clock{font-size:1.5rem;font-weight:500;letter-spacing:.05rem;font-family:monospace;padding:.5rem .75rem;border-radius:.25rem}.axp-clock-calendar-analog-clock{position:relative;border-radius:50%;border-width:1px;border-color:rgba(23,23,23,.5)}.axp-clock-calendar-analog-clock:is(.ax-dark *){border-color:rgba(245,245,245,.5)}.axp-clock-calendar-analog-clock{display:flex;align-items:center;justify-content:center;background:var(--ax-surface-color);width:min(180px,100%);height:0;padding-bottom:min(180px,100%);margin:.5rem auto;min-width:120px;min-height:120px;box-shadow:var(--ax-shadow-sm)}.axp-clock-calendar-hands-container,.axp-clock-calendar-numbers-container{position:absolute;top:0;left:0;width:100%;height:100%;border-radius:50%}.axp-clock-calendar-hour-marker{position:absolute;left:50%;top:50%;width:2px;height:4%;margin-left:-1px;border-radius:1px;background-color:var(--ax-text-muted);transform-origin:50% 0}.axp-clock-calendar-hour-number{position:absolute;left:50%;top:50%;transform-origin:50% 0;font-size:clamp(.7rem,2.5vw,.9rem);font-weight:600;color:var(--ax-text-color)}.axp-clock-calendar-hour-number span{display:block}.axp-clock-calendar-hour-hand{position:absolute;top:50%;left:50%;width:4px;height:25%;margin-left:-2px;background-color:rgba(23,23,23,.75)}.axp-clock-calendar-hour-hand:is(.ax-dark *){background-color:rgba(245,245,245,.75)}.axp-clock-calendar-hour-hand{transform-origin:50% 0;border-radius:3px;box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-minute-hand{position:absolute;top:50%;left:50%;width:3px;height:38%;margin-left:-1.5px;background-color:rgba(23,23,23,.5)}.axp-clock-calendar-minute-hand:is(.ax-dark *){background-color:rgba(245,245,245,.5)}.axp-clock-calendar-minute-hand{transform-origin:50% 0;border-radius:2px;box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-second-hand{position:absolute;top:50%;left:50%;width:2px;height:42%;margin-left:-1px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-500),var(--tw-bg-opacity, 1))}.axp-clock-calendar-second-hand:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-400),var(--tw-bg-opacity, 1))}.axp-clock-calendar-second-hand{transform-origin:50% 0;border-radius:1px;box-shadow:0 0 3px rgba(0,0,0,.2)}.axp-clock-calendar-center-dot{position:absolute;top:50%;left:50%;width:10px;height:10px;border-radius:50%;margin-top:-5px;margin-left:-5px;background-color:#d81159;border:2px solid var(--ax-surface-color);box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-date-display{display:flex;align-items:center;gap:.5rem;font-size:.85rem;padding:.25rem .6rem;border-radius:.25rem;background-color:var(--ax-surface-hover);color:var(--ax-text-color)}.axp-clock-calendar-date-display i{font-size:.85rem;opacity:.7}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXDateTimeModule }, { kind: "ngmodule", type: AXFormatModule }, { kind: "pipe", type: i2.AXFormatPipe, name: "format" }, { kind: "ngmodule", type: AXTagModule }, { kind: "ngmodule", type: AXDecoratorModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
897
899
|
}
|
898
900
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPClockCalendarWidgetViewComponent, decorators: [{
|
899
901
|
type: Component,
|
900
|
-
args: [{ standalone: true, imports: [CommonModule, AXDateTimeModule, AXFormatModule, AXTagModule, AXDecoratorModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axp-clock-calendar-container\">\n <!-- Timezone indicator (only shown when not local) -->\n <!-- @if (showTimezoneIndicator()) {\n <div class=\"axp-clock-calendar-timezone-badge\"><i class=\"fa-solid fa-globe\"></i> {{ displayTimezone() }}</div>\n } -->\n\n <!-- Day of week display -->\n @if (showDayOfWeek()) {\n
|
902
|
+
args: [{ standalone: true, imports: [CommonModule, AXDateTimeModule, AXFormatModule, AXTagModule, AXDecoratorModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axp-clock-calendar-container\">\n <!-- Timezone indicator (only shown when not local) -->\n <!-- @if (showTimezoneIndicator()) {\n <div class=\"axp-clock-calendar-timezone-badge\"><i class=\"fa-solid fa-globe\"></i> {{ displayTimezone() }}</div>\n } -->\n\n <!-- Day of week display -->\n @if (showDayOfWeek()) {\n <div class=\"axp-clock-calendar-day-label\">{{ getDayOfWeek() }}</div>\n }\n\n <div class=\"axp-clock-calendar-content\">\n <!-- Digital Clock Display -->\n @if (showDigitalClock()) {\n <div class=\"axp-clock-calendar-digital-clock\">\n {{ currentTime | format: 'datetime' : timeFormat() | async }}\n </div>\n }\n\n <!-- Analog Clock Display -->\n @if (showAnalogClock()) {\n <div class=\"axp-clock-calendar-analog-clock\">\n <!-- Hour markers -->\n @for (hour of clockHours; track hour) {\n <div\n class=\"axp-clock-calendar-hour-marker\"\n [style.transform]=\"'rotate(' + hour * 30 + 'deg) translateY(-80px)'\"\n ></div>\n }\n\n <!-- Clock Numbers -->\n <div class=\"axp-clock-calendar-numbers-container\">\n @for (hour of clockHourNumbers; track hour) {\n <div\n class=\"axp-clock-calendar-hour-number\"\n [style.transform]=\"'rotate(' + hour.angle + 'deg) translateY(-82px)'\"\n >\n <span [style.transform]=\"'rotate(' + -hour.angle + 'deg)'\">{{ hour.number }}</span>\n </div>\n }\n </div>\n\n <!-- Clock Hands -->\n <div class=\"axp-clock-calendar-hands-container\">\n <div class=\"axp-clock-calendar-hour-hand\" [style.transform]=\"'rotate(' + hourRotation + 'deg)'\"></div>\n <div class=\"axp-clock-calendar-minute-hand\" [style.transform]=\"'rotate(' + minuteRotation + 'deg)'\"></div>\n @if (showSeconds()) {\n <div class=\"axp-clock-calendar-second-hand\" [style.transform]=\"'rotate(' + secondRotation + 'deg)'\"></div>\n }\n <div class=\"axp-clock-calendar-center-dot\"></div>\n </div>\n </div>\n }\n\n <!-- Date Display -->\n @if (showDate()) {\n <div class=\"axp-clock-calendar-date-display\">\n <i class=\"fa-regular fa-calendar\"></i>\n {{ currentDate | format: 'datetime' : dateFormat() | async }}\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%;height:100%}.axp-clock-calendar-container{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;padding:1rem;position:relative;overflow:hidden;box-shadow:var(--ax-shadow-sm);background-color:var(--ax-surface-color);color:var(--ax-text-color)}.axp-clock-calendar-content{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;width:100%;height:100%;position:relative}.axp-clock-calendar-timezone-badge{position:absolute;top:.5rem;right:.5rem;font-size:.75rem;padding:.25rem;border-radius:1rem;border-width:1px;border-color:rgba(23,23,23,.5)}.axp-clock-calendar-timezone-badge:is(.ax-dark *){border-color:rgba(245,245,245,.5)}.axp-clock-calendar-timezone-badge{display:flex;align-items:center;gap:.25rem}.axp-clock-calendar-timezone-badge i{font-size:.75rem}.axp-clock-calendar-day-label{font-size:.9rem;font-weight:600;text-transform:uppercase;letter-spacing:.05rem;margin-bottom:.25rem}.axp-clock-calendar-digital-clock{font-size:1.5rem;font-weight:500;letter-spacing:.05rem;font-family:monospace;padding:.5rem .75rem;border-radius:.25rem}.axp-clock-calendar-analog-clock{position:relative;border-radius:50%;border-width:1px;border-color:rgba(23,23,23,.5)}.axp-clock-calendar-analog-clock:is(.ax-dark *){border-color:rgba(245,245,245,.5)}.axp-clock-calendar-analog-clock{display:flex;align-items:center;justify-content:center;background:var(--ax-surface-color);width:min(180px,100%);height:0;padding-bottom:min(180px,100%);margin:.5rem auto;min-width:120px;min-height:120px;box-shadow:var(--ax-shadow-sm)}.axp-clock-calendar-hands-container,.axp-clock-calendar-numbers-container{position:absolute;top:0;left:0;width:100%;height:100%;border-radius:50%}.axp-clock-calendar-hour-marker{position:absolute;left:50%;top:50%;width:2px;height:4%;margin-left:-1px;border-radius:1px;background-color:var(--ax-text-muted);transform-origin:50% 0}.axp-clock-calendar-hour-number{position:absolute;left:50%;top:50%;transform-origin:50% 0;font-size:clamp(.7rem,2.5vw,.9rem);font-weight:600;color:var(--ax-text-color)}.axp-clock-calendar-hour-number span{display:block}.axp-clock-calendar-hour-hand{position:absolute;top:50%;left:50%;width:4px;height:25%;margin-left:-2px;background-color:rgba(23,23,23,.75)}.axp-clock-calendar-hour-hand:is(.ax-dark *){background-color:rgba(245,245,245,.75)}.axp-clock-calendar-hour-hand{transform-origin:50% 0;border-radius:3px;box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-minute-hand{position:absolute;top:50%;left:50%;width:3px;height:38%;margin-left:-1.5px;background-color:rgba(23,23,23,.5)}.axp-clock-calendar-minute-hand:is(.ax-dark *){background-color:rgba(245,245,245,.5)}.axp-clock-calendar-minute-hand{transform-origin:50% 0;border-radius:2px;box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-second-hand{position:absolute;top:50%;left:50%;width:2px;height:42%;margin-left:-1px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-500),var(--tw-bg-opacity, 1))}.axp-clock-calendar-second-hand:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-400),var(--tw-bg-opacity, 1))}.axp-clock-calendar-second-hand{transform-origin:50% 0;border-radius:1px;box-shadow:0 0 3px rgba(0,0,0,.2)}.axp-clock-calendar-center-dot{position:absolute;top:50%;left:50%;width:10px;height:10px;border-radius:50%;margin-top:-5px;margin-left:-5px;background-color:#d81159;border:2px solid var(--ax-surface-color);box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-date-display{display:flex;align-items:center;gap:.5rem;font-size:.85rem;padding:.25rem .6rem;border-radius:.25rem;background-color:var(--ax-surface-hover);color:var(--ax-text-color)}.axp-clock-calendar-date-display i{font-size:.85rem;opacity:.7}\n"] }]
|
901
903
|
}] });
|
902
904
|
|
903
905
|
var clockCalendarWidget_component = /*#__PURE__*/Object.freeze({
|
@@ -932,10 +934,10 @@ const AXP_TIMEZONE_OPTIONS = [
|
|
932
934
|
* Common date format options for the widget configuration
|
933
935
|
*/
|
934
936
|
const AXP_DATE_FORMAT_OPTIONS = [
|
935
|
-
{ id: '
|
936
|
-
{ id: 'MMM
|
937
|
-
{ id: '
|
938
|
-
{ id: 'MM/
|
937
|
+
{ id: 'DD MMM YYYY', title: '31 Dec 2023' },
|
938
|
+
{ id: 'MMM DD, YYYY', title: 'Dec 31, 2023' },
|
939
|
+
{ id: 'DD/MM/YYYY', title: '31/12/2023' },
|
940
|
+
{ id: 'MM/DD/YYYY', title: '12/31/2023' },
|
939
941
|
];
|
940
942
|
|
941
943
|
const AXPClockCalendarWidget = {
|
@@ -949,7 +951,7 @@ const AXPClockCalendarWidget = {
|
|
949
951
|
// ====== Title ======
|
950
952
|
{
|
951
953
|
name: 'title',
|
952
|
-
title: '
|
954
|
+
title: '@dashboard:widgets.clock-calendar.chart-title',
|
953
955
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
954
956
|
schema: {
|
955
957
|
defaultValue: '',
|
@@ -968,7 +970,7 @@ const AXPClockCalendarWidget = {
|
|
968
970
|
// ====== Display Settings ======
|
969
971
|
{
|
970
972
|
name: 'displayLayout',
|
971
|
-
title: '
|
973
|
+
title: '@dashboard:widgets.clock-calendar.display-layout',
|
972
974
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
973
975
|
schema: {
|
974
976
|
dataType: 'string',
|
@@ -990,7 +992,7 @@ const AXPClockCalendarWidget = {
|
|
990
992
|
},
|
991
993
|
{
|
992
994
|
name: 'showDate',
|
993
|
-
title: '
|
995
|
+
title: '@dashboard:widgets.clock-calendar.show-date',
|
994
996
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
995
997
|
schema: {
|
996
998
|
defaultValue: true,
|
@@ -1005,7 +1007,7 @@ const AXPClockCalendarWidget = {
|
|
1005
1007
|
},
|
1006
1008
|
{
|
1007
1009
|
name: 'showDayOfWeek',
|
1008
|
-
title: '
|
1010
|
+
title: '@dashboard:widgets.clock-calendar.show-day-of-week',
|
1009
1011
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1010
1012
|
schema: {
|
1011
1013
|
defaultValue: true,
|
@@ -1021,7 +1023,7 @@ const AXPClockCalendarWidget = {
|
|
1021
1023
|
// ====== Time Format Settings ======
|
1022
1024
|
{
|
1023
1025
|
name: 'use24Hour',
|
1024
|
-
title: '
|
1026
|
+
title: '@dashboard:widgets.clock-calendar.use-24-hour',
|
1025
1027
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
1026
1028
|
schema: {
|
1027
1029
|
defaultValue: false,
|
@@ -1036,7 +1038,7 @@ const AXPClockCalendarWidget = {
|
|
1036
1038
|
},
|
1037
1039
|
{
|
1038
1040
|
name: 'showSeconds',
|
1039
|
-
title: '
|
1041
|
+
title: '@dashboard:widgets.clock-calendar.show-seconds',
|
1040
1042
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
1041
1043
|
schema: {
|
1042
1044
|
defaultValue: true,
|
@@ -1066,10 +1068,10 @@ const AXPClockCalendarWidget = {
|
|
1066
1068
|
// },
|
1067
1069
|
{
|
1068
1070
|
name: 'dateFormat',
|
1069
|
-
title: '
|
1071
|
+
title: '@dashboard:widgets.clock-calendar.date-format',
|
1070
1072
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
1071
1073
|
schema: {
|
1072
|
-
defaultValue: '
|
1074
|
+
defaultValue: 'DD MMM YYYY',
|
1073
1075
|
dataType: 'string',
|
1074
1076
|
interface: {
|
1075
1077
|
name: 'dateFormat',
|
@@ -1084,7 +1086,7 @@ const AXPClockCalendarWidget = {
|
|
1084
1086
|
},
|
1085
1087
|
{
|
1086
1088
|
name: 'timezone',
|
1087
|
-
title: '
|
1089
|
+
title: '@dashboard:widgets.clock-calendar.timezone',
|
1088
1090
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
1089
1091
|
schema: {
|
1090
1092
|
defaultValue: 'local',
|
@@ -1157,7 +1159,7 @@ const AXPDonutChartWidget = {
|
|
1157
1159
|
// ====== Chart Title ======
|
1158
1160
|
{
|
1159
1161
|
name: 'title',
|
1160
|
-
title: '
|
1162
|
+
title: '@dashboard:widgets.donut-chart.chart-title',
|
1161
1163
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1162
1164
|
schema: {
|
1163
1165
|
defaultValue: '',
|
@@ -1176,7 +1178,7 @@ const AXPDonutChartWidget = {
|
|
1176
1178
|
// ====== Size & Layout ======
|
1177
1179
|
{
|
1178
1180
|
name: 'width',
|
1179
|
-
title: '
|
1181
|
+
title: '@dashboard:widgets.donut-chart.width',
|
1180
1182
|
group: AXP_STYLING_PROPERTY_GROUP,
|
1181
1183
|
schema: {
|
1182
1184
|
defaultValue: 300,
|
@@ -1195,7 +1197,7 @@ const AXPDonutChartWidget = {
|
|
1195
1197
|
},
|
1196
1198
|
{
|
1197
1199
|
name: 'height',
|
1198
|
-
title: '
|
1200
|
+
title: '@dashboard:widgets.donut-chart.height',
|
1199
1201
|
group: AXP_STYLING_PROPERTY_GROUP,
|
1200
1202
|
schema: {
|
1201
1203
|
defaultValue: 300,
|
@@ -1215,7 +1217,7 @@ const AXPDonutChartWidget = {
|
|
1215
1217
|
// ====== Donut Appearance ======
|
1216
1218
|
{
|
1217
1219
|
name: 'showDataLabels',
|
1218
|
-
title: '
|
1220
|
+
title: '@dashboard:widgets.donut-chart.show-data-labels',
|
1219
1221
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1220
1222
|
schema: {
|
1221
1223
|
defaultValue: true,
|
@@ -1230,7 +1232,7 @@ const AXPDonutChartWidget = {
|
|
1230
1232
|
},
|
1231
1233
|
{
|
1232
1234
|
name: 'donutWidth',
|
1233
|
-
title: '
|
1235
|
+
title: '@dashboard:widgets.donut-chart.donut-width',
|
1234
1236
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1235
1237
|
schema: {
|
1236
1238
|
defaultValue: 35,
|
@@ -1250,7 +1252,7 @@ const AXPDonutChartWidget = {
|
|
1250
1252
|
},
|
1251
1253
|
{
|
1252
1254
|
name: 'cornerRadius',
|
1253
|
-
title: '
|
1255
|
+
title: '@dashboard:widgets.donut-chart.corner-radius',
|
1254
1256
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1255
1257
|
schema: {
|
1256
1258
|
defaultValue: 4,
|
@@ -1305,7 +1307,7 @@ const AXPDonutChartWidget = {
|
|
1305
1307
|
// ====== Tooltip ======
|
1306
1308
|
{
|
1307
1309
|
name: 'showTooltip',
|
1308
|
-
title: '
|
1310
|
+
title: '@dashboard:widgets.donut-chart.show-tooltip',
|
1309
1311
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1310
1312
|
schema: {
|
1311
1313
|
defaultValue: true,
|
@@ -1321,7 +1323,7 @@ const AXPDonutChartWidget = {
|
|
1321
1323
|
// ====== Animation Settings ======
|
1322
1324
|
{
|
1323
1325
|
name: 'animationEasing',
|
1324
|
-
title: '
|
1326
|
+
title: '@dashboard:widgets.donut-chart.animation-easing',
|
1325
1327
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1326
1328
|
schema: {
|
1327
1329
|
defaultValue: 'cubic-out',
|
@@ -1351,7 +1353,7 @@ const AXPDonutChartWidget = {
|
|
1351
1353
|
},
|
1352
1354
|
{
|
1353
1355
|
name: 'animationDuration',
|
1354
|
-
title: '
|
1356
|
+
title: '@dashboard:widgets.donut-chart.animation-duration',
|
1355
1357
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1356
1358
|
schema: {
|
1357
1359
|
defaultValue: 800,
|
@@ -1422,7 +1424,7 @@ const AXPGaugeChartWidget = {
|
|
1422
1424
|
// ====== Chart Title ======
|
1423
1425
|
{
|
1424
1426
|
name: 'title',
|
1425
|
-
title: '
|
1427
|
+
title: '@dashboard:widgets.gauge-chart.chart-title',
|
1426
1428
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1427
1429
|
schema: {
|
1428
1430
|
defaultValue: '',
|
@@ -1441,7 +1443,7 @@ const AXPGaugeChartWidget = {
|
|
1441
1443
|
// ====== Layout & Dimensions ======
|
1442
1444
|
{
|
1443
1445
|
name: 'width',
|
1444
|
-
title: '
|
1446
|
+
title: '@dashboard:widgets.gauge-chart.width',
|
1445
1447
|
group: AXP_STYLING_PROPERTY_GROUP,
|
1446
1448
|
schema: {
|
1447
1449
|
defaultValue: null,
|
@@ -1461,7 +1463,7 @@ const AXPGaugeChartWidget = {
|
|
1461
1463
|
},
|
1462
1464
|
{
|
1463
1465
|
name: 'height',
|
1464
|
-
title: '
|
1466
|
+
title: '@dashboard:widgets.gauge-chart.height',
|
1465
1467
|
group: AXP_STYLING_PROPERTY_GROUP,
|
1466
1468
|
schema: {
|
1467
1469
|
defaultValue: 300,
|
@@ -1482,7 +1484,7 @@ const AXPGaugeChartWidget = {
|
|
1482
1484
|
// ====== Gauge Configuration ======
|
1483
1485
|
{
|
1484
1486
|
name: 'minValue',
|
1485
|
-
title: '
|
1487
|
+
title: '@dashboard:widgets.gauge-chart.min-value',
|
1486
1488
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1487
1489
|
schema: {
|
1488
1490
|
defaultValue: 0,
|
@@ -1497,7 +1499,7 @@ const AXPGaugeChartWidget = {
|
|
1497
1499
|
},
|
1498
1500
|
{
|
1499
1501
|
name: 'maxValue',
|
1500
|
-
title: '
|
1502
|
+
title: '@dashboard:widgets.gauge-chart.max-value',
|
1501
1503
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1502
1504
|
schema: {
|
1503
1505
|
defaultValue: 100,
|
@@ -1513,7 +1515,7 @@ const AXPGaugeChartWidget = {
|
|
1513
1515
|
// ====== Gauge Appearance ======
|
1514
1516
|
{
|
1515
1517
|
name: 'showTooltip',
|
1516
|
-
title: '
|
1518
|
+
title: '@dashboard:widgets.gauge-chart.show-tooltip',
|
1517
1519
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1518
1520
|
schema: {
|
1519
1521
|
defaultValue: true,
|
@@ -1528,7 +1530,7 @@ const AXPGaugeChartWidget = {
|
|
1528
1530
|
},
|
1529
1531
|
{
|
1530
1532
|
name: 'gaugeWidth',
|
1531
|
-
title: '
|
1533
|
+
title: '@dashboard:widgets.gauge-chart.gauge-width',
|
1532
1534
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1533
1535
|
schema: {
|
1534
1536
|
defaultValue: 30,
|
@@ -1548,7 +1550,7 @@ const AXPGaugeChartWidget = {
|
|
1548
1550
|
},
|
1549
1551
|
{
|
1550
1552
|
name: 'cornerRadius',
|
1551
|
-
title: '
|
1553
|
+
title: '@dashboard:widgets.gauge-chart.corner-radius',
|
1552
1554
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1553
1555
|
schema: {
|
1554
1556
|
defaultValue: 4,
|
@@ -1569,7 +1571,7 @@ const AXPGaugeChartWidget = {
|
|
1569
1571
|
// ====== Label Display ======
|
1570
1572
|
{
|
1571
1573
|
name: 'label',
|
1572
|
-
title: '
|
1574
|
+
title: '@dashboard:widgets.gauge-chart.label',
|
1573
1575
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1574
1576
|
schema: {
|
1575
1577
|
defaultValue: '',
|
@@ -1585,7 +1587,7 @@ const AXPGaugeChartWidget = {
|
|
1585
1587
|
// ====== Animation Settings ======
|
1586
1588
|
{
|
1587
1589
|
name: 'animationEasing',
|
1588
|
-
title: '
|
1590
|
+
title: '@dashboard:widgets.gauge-chart.animation-easing',
|
1589
1591
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1590
1592
|
schema: {
|
1591
1593
|
defaultValue: 'cubic-out',
|
@@ -1615,7 +1617,7 @@ const AXPGaugeChartWidget = {
|
|
1615
1617
|
},
|
1616
1618
|
{
|
1617
1619
|
name: 'animationDuration',
|
1618
|
-
title: '
|
1620
|
+
title: '@dashboard:widgets.gauge-chart.animation-duration',
|
1619
1621
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1620
1622
|
schema: {
|
1621
1623
|
defaultValue: 800,
|
@@ -1690,7 +1692,7 @@ const AXPLineChartWidget = {
|
|
1690
1692
|
// ====== Chart Title ======
|
1691
1693
|
{
|
1692
1694
|
name: 'title',
|
1693
|
-
title: '
|
1695
|
+
title: '@dashboard:widgets.line-chart.chart-title',
|
1694
1696
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1695
1697
|
schema: {
|
1696
1698
|
defaultValue: '',
|
@@ -1709,7 +1711,7 @@ const AXPLineChartWidget = {
|
|
1709
1711
|
// ====== Layout & Dimensions ======
|
1710
1712
|
{
|
1711
1713
|
name: 'width',
|
1712
|
-
title: '
|
1714
|
+
title: '@dashboard:widgets.line-chart.width',
|
1713
1715
|
group: AXP_STYLING_PROPERTY_GROUP,
|
1714
1716
|
schema: {
|
1715
1717
|
defaultValue: null,
|
@@ -1728,7 +1730,7 @@ const AXPLineChartWidget = {
|
|
1728
1730
|
},
|
1729
1731
|
{
|
1730
1732
|
name: 'height',
|
1731
|
-
title: '
|
1733
|
+
title: '@dashboard:widgets.line-chart.height',
|
1732
1734
|
group: AXP_STYLING_PROPERTY_GROUP,
|
1733
1735
|
schema: {
|
1734
1736
|
defaultValue: 300,
|
@@ -1748,7 +1750,7 @@ const AXPLineChartWidget = {
|
|
1748
1750
|
// ====== Axis Settings ======
|
1749
1751
|
{
|
1750
1752
|
name: 'showXAxis',
|
1751
|
-
title: '
|
1753
|
+
title: '@dashboard:widgets.line-chart.show-x-axis',
|
1752
1754
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1753
1755
|
schema: {
|
1754
1756
|
defaultValue: true,
|
@@ -1763,7 +1765,7 @@ const AXPLineChartWidget = {
|
|
1763
1765
|
},
|
1764
1766
|
{
|
1765
1767
|
name: 'xAxisLabel',
|
1766
|
-
title: '
|
1768
|
+
title: '@dashboard:widgets.line-chart.x-axis-label',
|
1767
1769
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1768
1770
|
schema: {
|
1769
1771
|
defaultValue: '',
|
@@ -1778,7 +1780,7 @@ const AXPLineChartWidget = {
|
|
1778
1780
|
},
|
1779
1781
|
{
|
1780
1782
|
name: 'showYAxis',
|
1781
|
-
title: '
|
1783
|
+
title: '@dashboard:widgets.line-chart.show-y-axis',
|
1782
1784
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1783
1785
|
schema: {
|
1784
1786
|
defaultValue: true,
|
@@ -1793,7 +1795,7 @@ const AXPLineChartWidget = {
|
|
1793
1795
|
},
|
1794
1796
|
{
|
1795
1797
|
name: 'yAxisLabel',
|
1796
|
-
title: '
|
1798
|
+
title: '@dashboard:widgets.line-chart.y-axis-label',
|
1797
1799
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1798
1800
|
schema: {
|
1799
1801
|
defaultValue: '',
|
@@ -1808,7 +1810,7 @@ const AXPLineChartWidget = {
|
|
1808
1810
|
},
|
1809
1811
|
{
|
1810
1812
|
name: 'yAxisStartsAtZero',
|
1811
|
-
title: '
|
1813
|
+
title: '@dashboard:widgets.line-chart.y-axis-starts-at-zero',
|
1812
1814
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1813
1815
|
schema: {
|
1814
1816
|
defaultValue: true,
|
@@ -1823,7 +1825,7 @@ const AXPLineChartWidget = {
|
|
1823
1825
|
},
|
1824
1826
|
{
|
1825
1827
|
name: 'showGrid',
|
1826
|
-
title: '
|
1828
|
+
title: '@dashboard:widgets.line-chart.show-grid',
|
1827
1829
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1828
1830
|
schema: {
|
1829
1831
|
defaultValue: true,
|
@@ -1838,7 +1840,7 @@ const AXPLineChartWidget = {
|
|
1838
1840
|
},
|
1839
1841
|
{
|
1840
1842
|
name: 'showVerticalGrid',
|
1841
|
-
title: '
|
1843
|
+
title: '@dashboard:widgets.line-chart.show-vertical-grid',
|
1842
1844
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1843
1845
|
schema: {
|
1844
1846
|
defaultValue: true,
|
@@ -1854,7 +1856,7 @@ const AXPLineChartWidget = {
|
|
1854
1856
|
// ====== Line Appearance ======
|
1855
1857
|
{
|
1856
1858
|
name: 'lineWidth',
|
1857
|
-
title: '
|
1859
|
+
title: '@dashboard:widgets.line-chart.line-width',
|
1858
1860
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1859
1861
|
schema: {
|
1860
1862
|
defaultValue: 2,
|
@@ -1874,7 +1876,7 @@ const AXPLineChartWidget = {
|
|
1874
1876
|
},
|
1875
1877
|
{
|
1876
1878
|
name: 'smoothLine',
|
1877
|
-
title: '
|
1879
|
+
title: '@dashboard:widgets.line-chart.smooth-line',
|
1878
1880
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1879
1881
|
schema: {
|
1880
1882
|
defaultValue: true,
|
@@ -1889,7 +1891,7 @@ const AXPLineChartWidget = {
|
|
1889
1891
|
},
|
1890
1892
|
{
|
1891
1893
|
name: 'showPoints',
|
1892
|
-
title: '
|
1894
|
+
title: '@dashboard:widgets.line-chart.show-points',
|
1893
1895
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1894
1896
|
schema: {
|
1895
1897
|
defaultValue: true,
|
@@ -1904,7 +1906,7 @@ const AXPLineChartWidget = {
|
|
1904
1906
|
},
|
1905
1907
|
{
|
1906
1908
|
name: 'pointRadius',
|
1907
|
-
title: '
|
1909
|
+
title: '@dashboard:widgets.line-chart.point-radius',
|
1908
1910
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1909
1911
|
schema: {
|
1910
1912
|
defaultValue: 4,
|
@@ -1924,7 +1926,7 @@ const AXPLineChartWidget = {
|
|
1924
1926
|
},
|
1925
1927
|
{
|
1926
1928
|
name: 'fillArea',
|
1927
|
-
title: '
|
1929
|
+
title: '@dashboard:widgets.line-chart.fill-area',
|
1928
1930
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1929
1931
|
schema: {
|
1930
1932
|
defaultValue: false,
|
@@ -1939,19 +1941,20 @@ const AXPLineChartWidget = {
|
|
1939
1941
|
},
|
1940
1942
|
{
|
1941
1943
|
name: 'fillOpacity',
|
1942
|
-
title: '
|
1944
|
+
title: '@dashboard:widgets.line-chart.fill-opacity',
|
1943
1945
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1944
1946
|
schema: {
|
1945
|
-
defaultValue:
|
1947
|
+
defaultValue: 0.1,
|
1946
1948
|
dataType: 'number',
|
1947
1949
|
interface: {
|
1948
1950
|
name: 'fillOpacity',
|
1949
1951
|
path: 'options.fillOpacity',
|
1950
1952
|
type: AXPWidgetsCatalog.number,
|
1951
1953
|
options: {
|
1952
|
-
placeholder: '0-
|
1954
|
+
placeholder: '0-1',
|
1953
1955
|
minValue: 0,
|
1954
|
-
maxValue:
|
1956
|
+
maxValue: 1,
|
1957
|
+
step: 0.1,
|
1955
1958
|
},
|
1956
1959
|
},
|
1957
1960
|
},
|
@@ -1960,7 +1963,7 @@ const AXPLineChartWidget = {
|
|
1960
1963
|
// ====== Tooltip Settings ======
|
1961
1964
|
{
|
1962
1965
|
name: 'showTooltip',
|
1963
|
-
title: '
|
1966
|
+
title: '@dashboard:widgets.line-chart.show-tooltip',
|
1964
1967
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1965
1968
|
schema: {
|
1966
1969
|
defaultValue: true,
|
@@ -1975,10 +1978,10 @@ const AXPLineChartWidget = {
|
|
1975
1978
|
},
|
1976
1979
|
{
|
1977
1980
|
name: 'showCrosshair',
|
1978
|
-
title: '
|
1981
|
+
title: '@dashboard:widgets.line-chart.show-crosshair',
|
1979
1982
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1980
1983
|
schema: {
|
1981
|
-
defaultValue:
|
1984
|
+
defaultValue: true,
|
1982
1985
|
dataType: 'boolean',
|
1983
1986
|
interface: {
|
1984
1987
|
name: 'showCrosshair',
|
@@ -1991,7 +1994,7 @@ const AXPLineChartWidget = {
|
|
1991
1994
|
// ====== Animation Settings ======
|
1992
1995
|
{
|
1993
1996
|
name: 'animationEasing',
|
1994
|
-
title: '
|
1997
|
+
title: '@dashboard:widgets.line-chart.animation-easing',
|
1995
1998
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1996
1999
|
schema: {
|
1997
2000
|
defaultValue: 'cubic-out',
|
@@ -2021,7 +2024,7 @@ const AXPLineChartWidget = {
|
|
2021
2024
|
},
|
2022
2025
|
{
|
2023
2026
|
name: 'animationDuration',
|
2024
|
-
title: '
|
2027
|
+
title: '@dashboard:widgets.line-chart.animation-duration',
|
2025
2028
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2026
2029
|
schema: {
|
2027
2030
|
defaultValue: 800,
|
@@ -2047,12 +2050,12 @@ const AXPLineChartWidget = {
|
|
2047
2050
|
},
|
2048
2051
|
meta: {
|
2049
2052
|
dimensions: {
|
2050
|
-
width:
|
2051
|
-
height:
|
2053
|
+
width: 3,
|
2054
|
+
height: 4,
|
2052
2055
|
minWidth: 2,
|
2053
2056
|
minHeight: 2,
|
2054
|
-
maxWidth:
|
2055
|
-
maxHeight:
|
2057
|
+
maxWidth: 4,
|
2058
|
+
maxHeight: 5,
|
2056
2059
|
},
|
2057
2060
|
},
|
2058
2061
|
};
|
@@ -2150,7 +2153,17 @@ const AXPStickyNoteWidget = {
|
|
2150
2153
|
groups: [AXPWidgetGroupEnum.DashboardWidget],
|
2151
2154
|
type: 'dashboard',
|
2152
2155
|
icon: 'fa-light fa-sticky-note',
|
2153
|
-
properties: [
|
2156
|
+
properties: [
|
2157
|
+
AXP_DATA_PATH_PROPERTY,
|
2158
|
+
{
|
2159
|
+
...AXP_BG_COLOR_PROPERTY,
|
2160
|
+
title: '@dashboard:widgets.sticky-note.background-color',
|
2161
|
+
},
|
2162
|
+
{
|
2163
|
+
...plainTextDefaultProperty(),
|
2164
|
+
title: '@dashboard:widgets.sticky-note.note-text',
|
2165
|
+
},
|
2166
|
+
],
|
2154
2167
|
components: {
|
2155
2168
|
view: {
|
2156
2169
|
component: () => Promise.resolve().then(function () { return stickyNoteWidget_component; }).then((c) => c.AXPStickyNoteWidgetViewComponent),
|
@@ -2263,7 +2276,7 @@ class AXPTaskListWidgetViewComponent extends AXPValueWidgetComponent {
|
|
2263
2276
|
return 'Tomorrow';
|
2264
2277
|
if (diffDays < 7)
|
2265
2278
|
return this.datePipe.transform(dateObj, 'EEE') || '';
|
2266
|
-
return this.datePipe.transform(dateObj, 'MM/
|
2279
|
+
return this.datePipe.transform(dateObj, 'MM/DD/YYYY') || '';
|
2267
2280
|
}
|
2268
2281
|
getPriorityColor(priority) {
|
2269
2282
|
if (!priority)
|
@@ -2291,7 +2304,7 @@ class AXPTaskListWidgetViewComponent extends AXPValueWidgetComponent {
|
|
2291
2304
|
return Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
2292
2305
|
}
|
2293
2306
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPTaskListWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
2294
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPTaskListWidgetViewComponent, isStandalone: true, selector: "ng-component", outputs: { taskClick: "taskClick", taskCompleted: "taskCompleted" }, providers: [DatePipe], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-size-full ax-p-4\">\n <!-- Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center
|
2307
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPTaskListWidgetViewComponent, isStandalone: true, selector: "ng-component", outputs: { taskClick: "taskClick", taskCompleted: "taskCompleted" }, providers: [DatePipe], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-size-full ax-p-4 ax-flex ax-flex-col\">\n <!-- Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <h3 class=\"ax-text-lg ax-font-semibold ax-flex ax-items-center ax-gap-2\">\n <ax-icon class=\"ax-text-primary-500\">\n <i class=\"fa-light fa-clipboard-list-check\"></i>\n </ax-icon>\n {{ 'tasklist.title' | translate: { scope: 'dashboard' } | async }}\n </h3>\n <div class=\"ax-flex ax-gap-2\">\n @if (getPendingTaskCount() > 0) {\n <ax-badge\n [text]=\"getPendingTaskCount() + ' ' + ('tasklist.pending' | translate: { scope: 'dashboard' } | async)\"\n [color]=\"'warning'\"\n size=\"sm\"\n class=\"ax-ml-1\"\n >\n </ax-badge>\n }\n @if (getCompletedTaskCount() > 0) {\n <ax-badge\n [text]=\"getCompletedTaskCount() + ' ' + ('tasklist.completed' | translate: { scope: 'dashboard' } | async)\"\n [color]=\"'success'\"\n size=\"sm\"\n class=\"ax-ml-1\"\n >\n </ax-badge>\n }\n </div>\n </div>\n\n <!-- Task List -->\n <div class=\"ax-space-y-4 ax-my-4 ax-px-1 ax-overflow-auto ax-grow\">\n @if (showCategories() && hasCategories()) {\n <!-- Categorized Tasks -->\n @for (category of getCategories(); track category) {\n <div class=\"ax-mb-5\">\n <!-- Category Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center ax-mb-3 ax-h-5\">\n <h4 class=\"ax-font-medium category-header\">{{ category }}</h4>\n @if (getCategoryTaskCount(category)) {\n <ax-badge\n [text]=\"getCategoryTaskCount(category).toString()\"\n [color]=\"'primary'\"\n size=\"sm\"\n class=\"ax-rounded-full\"\n ></ax-badge>\n }\n </div>\n <!-- Tasks in Category -->\n <div class=\"ax-space-y-2\">\n @for (task of getTasksByCategory(category); track task.id) {\n <ng-container\n [ngTemplateOutlet]=\"taskItemTemplateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: task }\"\n ></ng-container>\n }\n </div>\n </div>\n }\n } @else {\n <!-- Uncategorized Tasks -->\n <div class=\"ax-space-y-2\">\n @for (task of taskItems(); track task.id) {\n <ng-container\n [ngTemplateOutlet]=\"taskItemTemplateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: task }\"\n ></ng-container>\n } @empty {\n <!-- Empty State -->\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-py-14 ax-px-4 ax-text-gray-400 empty-state\"\n >\n <ax-icon class=\"ax-text-5xl ax-mb-3 ax-text-gray-300\">\n <i class=\"fa-light fa-clipboard-list-check\"></i>\n </ax-icon>\n <p class=\"ax-text-center ax-font-medium\">\n {{ 'tasklist.noTasks' | translate: { scope: 'dashboard' } | async }}\n </p>\n <p class=\"ax-text-center ax-text-sm ax-mt-2\">\n {{ 'tasklist.addTask' | translate: { scope: 'dashboard' } | async }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n</div>\n\n<!-- Task Item Template -->\n<ng-template #taskItemTemplateRef let-task>\n <div\n class=\"ax-flex ax-gap-3 ax-items-start ax-p-3 ax-rounded-lg task-item\"\n [class.priority-high]=\"task.priority === 'high'\"\n [class.priority-medium]=\"task.priority === 'medium'\"\n [class.priority-low]=\"task.priority === 'low'\"\n [class.ax-bg-surface]=\"task.completed\"\n >\n <!-- Checkbox -->\n <ax-check-box\n class=\"ax-flex-shrink-0 ax-mt-1 task-checkbox\"\n [value]=\"task.completed\"\n [disabled]=\"!allowMarkComplete()\"\n (valueChange)=\"onTaskCompletionChange(task, $event)\"\n >\n </ax-check-box>\n\n <!-- Task Details -->\n <div class=\"ax-overflow-hidden ax-grow ax-text-start\" (click)=\"onTaskClick(task)\">\n <!-- Title and Priority -->\n <div class=\"ax-flex ax-items-center ax-gap-2\">\n <h6 class=\"ax-font-medium ax-truncate ax-pb-1\" [title]=\"task.title\" [class.task-completed]=\"task.completed\">\n {{ task.title }}\n </h6>\n @if (showPriority() && task.priority) {\n <ax-badge\n [color]=\"getPriorityColor(task.priority)\"\n [text]=\"task.priority\"\n size=\"sm\"\n class=\"ax-ml-1 ax-rounded-full\"\n ></ax-badge>\n }\n </div>\n\n <!-- Metadata -->\n <div class=\"ax-flex ax-flex-wrap ax-gap-x-3 ax-gap-y-1 ax-mt-2 ax-text-xs ax-text-gray-500\">\n @if (showDate() && task.dueDate) {\n <span\n class=\"ax-flex ax-items-center ax-gap-1 due-date\"\n [class.ax-text-danger-500]=\"getDaysDifference(task.dueDate) < 0\"\n [class.overdue]=\"getDaysDifference(task.dueDate) < 0\"\n >\n <ax-icon><i class=\"fa-light fa-calendar\"></i></ax-icon>\n {{ formatDueDate(task.dueDate) }}\n </span>\n }\n @if (showAssignee() && task.assignedTo) {\n <span class=\"ax-flex ax-items-center ax-gap-1\">\n @if (task.assignedTo.image) {\n <ax-icon class=\"ax-bg-primary-100 ax-text-primary-500 ax-rounded-full ax-p-1\">\n <i class=\"fa-light fa-user\"></i>\n </ax-icon>\n } @else {\n <ax-icon><i class=\"fa-light fa-user\"></i></ax-icon>\n }\n {{ task.assignedTo.name }}\n </span>\n }\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [":host{display:block;height:100%;width:100%}.task-item{border-radius:8px;transition:all .2s ease-in-out;border-left:3px solid transparent}.task-item:hover{background-color:rgba(var(--ax-sys-color-on-surface),.1);transform:translateY(-2px);box-shadow:0 2px 8px rgba(0,0,0,.05)}.task-item.priority-high{border-left-color:rgb(var(--ax-sys-color-danger-500))}.task-item.priority-medium{border-left-color:rgb(var(--ax-sys-color-warning-500))}.task-item.priority-low{border-left-color:rgb(var(--ax-sys-color-success-500))}.task-item:active{transform:translateY(0);box-shadow:0 1px 3px rgba(0,0,0,.05)}.task-completed{text-decoration:line-through;color:var(--ax-text-secondary);opacity:.7;transition:all .3s ease}.category-header{position:relative}.category-header:after{content:\"\";position:absolute;bottom:-8px;left:0;width:40px;height:3px;background-color:var(--ax-primary-500);border-radius:3px;transition:width .3s ease}.category-header:hover:after{width:60px}.empty-state{animation:fadeIn .5s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.task-checkbox ::ng-deep .ax-checkbox{transition:all .2s ease}.task-checkbox ::ng-deep .ax-checkbox:hover{transform:scale(1.1)}.due-date.overdue{animation:pulse 2s infinite}@keyframes pulse{0%{opacity:.7}50%{opacity:1}to{opacity:.7}}.ax-space-y-2>*{animation:slideInRight .3s ease forwards;opacity:0}.ax-space-y-2>*:nth-child(1){animation-delay:.05s}.ax-space-y-2>*:nth-child(2){animation-delay:.1s}.ax-space-y-2>*:nth-child(3){animation-delay:.15s}.ax-space-y-2>*:nth-child(4){animation-delay:.2s}.ax-space-y-2>*:nth-child(5){animation-delay:.25s}.ax-space-y-2>*:nth-child(6){animation-delay:.3s}.ax-space-y-2>*:nth-child(7){animation-delay:.35s}.ax-space-y-2>*:nth-child(8){animation-delay:.4s}.ax-space-y-2>*:nth-child(9){animation-delay:.45s}.ax-space-y-2>*:nth-child(10){animation-delay:.5s}@keyframes slideInRight{0%{opacity:0;transform:translate(10px)}to{opacity:1;transform:translate(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i3.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXAvatarModule }, { kind: "ngmodule", type: AXImageModule }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i4.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "checked", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i2$3.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
2295
2308
|
}
|
2296
2309
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPTaskListWidgetViewComponent, decorators: [{
|
2297
2310
|
type: Component,
|
@@ -2306,7 +2319,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
2306
2319
|
AXCheckBoxModule,
|
2307
2320
|
AXLabelModule,
|
2308
2321
|
AXTranslationModule,
|
2309
|
-
], providers: [DatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ax-size-full ax-p-4\">\n <!-- Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center
|
2322
|
+
], providers: [DatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ax-size-full ax-p-4 ax-flex ax-flex-col\">\n <!-- Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <h3 class=\"ax-text-lg ax-font-semibold ax-flex ax-items-center ax-gap-2\">\n <ax-icon class=\"ax-text-primary-500\">\n <i class=\"fa-light fa-clipboard-list-check\"></i>\n </ax-icon>\n {{ 'tasklist.title' | translate: { scope: 'dashboard' } | async }}\n </h3>\n <div class=\"ax-flex ax-gap-2\">\n @if (getPendingTaskCount() > 0) {\n <ax-badge\n [text]=\"getPendingTaskCount() + ' ' + ('tasklist.pending' | translate: { scope: 'dashboard' } | async)\"\n [color]=\"'warning'\"\n size=\"sm\"\n class=\"ax-ml-1\"\n >\n </ax-badge>\n }\n @if (getCompletedTaskCount() > 0) {\n <ax-badge\n [text]=\"getCompletedTaskCount() + ' ' + ('tasklist.completed' | translate: { scope: 'dashboard' } | async)\"\n [color]=\"'success'\"\n size=\"sm\"\n class=\"ax-ml-1\"\n >\n </ax-badge>\n }\n </div>\n </div>\n\n <!-- Task List -->\n <div class=\"ax-space-y-4 ax-my-4 ax-px-1 ax-overflow-auto ax-grow\">\n @if (showCategories() && hasCategories()) {\n <!-- Categorized Tasks -->\n @for (category of getCategories(); track category) {\n <div class=\"ax-mb-5\">\n <!-- Category Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center ax-mb-3 ax-h-5\">\n <h4 class=\"ax-font-medium category-header\">{{ category }}</h4>\n @if (getCategoryTaskCount(category)) {\n <ax-badge\n [text]=\"getCategoryTaskCount(category).toString()\"\n [color]=\"'primary'\"\n size=\"sm\"\n class=\"ax-rounded-full\"\n ></ax-badge>\n }\n </div>\n <!-- Tasks in Category -->\n <div class=\"ax-space-y-2\">\n @for (task of getTasksByCategory(category); track task.id) {\n <ng-container\n [ngTemplateOutlet]=\"taskItemTemplateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: task }\"\n ></ng-container>\n }\n </div>\n </div>\n }\n } @else {\n <!-- Uncategorized Tasks -->\n <div class=\"ax-space-y-2\">\n @for (task of taskItems(); track task.id) {\n <ng-container\n [ngTemplateOutlet]=\"taskItemTemplateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: task }\"\n ></ng-container>\n } @empty {\n <!-- Empty State -->\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-py-14 ax-px-4 ax-text-gray-400 empty-state\"\n >\n <ax-icon class=\"ax-text-5xl ax-mb-3 ax-text-gray-300\">\n <i class=\"fa-light fa-clipboard-list-check\"></i>\n </ax-icon>\n <p class=\"ax-text-center ax-font-medium\">\n {{ 'tasklist.noTasks' | translate: { scope: 'dashboard' } | async }}\n </p>\n <p class=\"ax-text-center ax-text-sm ax-mt-2\">\n {{ 'tasklist.addTask' | translate: { scope: 'dashboard' } | async }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n</div>\n\n<!-- Task Item Template -->\n<ng-template #taskItemTemplateRef let-task>\n <div\n class=\"ax-flex ax-gap-3 ax-items-start ax-p-3 ax-rounded-lg task-item\"\n [class.priority-high]=\"task.priority === 'high'\"\n [class.priority-medium]=\"task.priority === 'medium'\"\n [class.priority-low]=\"task.priority === 'low'\"\n [class.ax-bg-surface]=\"task.completed\"\n >\n <!-- Checkbox -->\n <ax-check-box\n class=\"ax-flex-shrink-0 ax-mt-1 task-checkbox\"\n [value]=\"task.completed\"\n [disabled]=\"!allowMarkComplete()\"\n (valueChange)=\"onTaskCompletionChange(task, $event)\"\n >\n </ax-check-box>\n\n <!-- Task Details -->\n <div class=\"ax-overflow-hidden ax-grow ax-text-start\" (click)=\"onTaskClick(task)\">\n <!-- Title and Priority -->\n <div class=\"ax-flex ax-items-center ax-gap-2\">\n <h6 class=\"ax-font-medium ax-truncate ax-pb-1\" [title]=\"task.title\" [class.task-completed]=\"task.completed\">\n {{ task.title }}\n </h6>\n @if (showPriority() && task.priority) {\n <ax-badge\n [color]=\"getPriorityColor(task.priority)\"\n [text]=\"task.priority\"\n size=\"sm\"\n class=\"ax-ml-1 ax-rounded-full\"\n ></ax-badge>\n }\n </div>\n\n <!-- Metadata -->\n <div class=\"ax-flex ax-flex-wrap ax-gap-x-3 ax-gap-y-1 ax-mt-2 ax-text-xs ax-text-gray-500\">\n @if (showDate() && task.dueDate) {\n <span\n class=\"ax-flex ax-items-center ax-gap-1 due-date\"\n [class.ax-text-danger-500]=\"getDaysDifference(task.dueDate) < 0\"\n [class.overdue]=\"getDaysDifference(task.dueDate) < 0\"\n >\n <ax-icon><i class=\"fa-light fa-calendar\"></i></ax-icon>\n {{ formatDueDate(task.dueDate) }}\n </span>\n }\n @if (showAssignee() && task.assignedTo) {\n <span class=\"ax-flex ax-items-center ax-gap-1\">\n @if (task.assignedTo.image) {\n <ax-icon class=\"ax-bg-primary-100 ax-text-primary-500 ax-rounded-full ax-p-1\">\n <i class=\"fa-light fa-user\"></i>\n </ax-icon>\n } @else {\n <ax-icon><i class=\"fa-light fa-user\"></i></ax-icon>\n }\n {{ task.assignedTo.name }}\n </span>\n }\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [":host{display:block;height:100%;width:100%}.task-item{border-radius:8px;transition:all .2s ease-in-out;border-left:3px solid transparent}.task-item:hover{background-color:rgba(var(--ax-sys-color-on-surface),.1);transform:translateY(-2px);box-shadow:0 2px 8px rgba(0,0,0,.05)}.task-item.priority-high{border-left-color:rgb(var(--ax-sys-color-danger-500))}.task-item.priority-medium{border-left-color:rgb(var(--ax-sys-color-warning-500))}.task-item.priority-low{border-left-color:rgb(var(--ax-sys-color-success-500))}.task-item:active{transform:translateY(0);box-shadow:0 1px 3px rgba(0,0,0,.05)}.task-completed{text-decoration:line-through;color:var(--ax-text-secondary);opacity:.7;transition:all .3s ease}.category-header{position:relative}.category-header:after{content:\"\";position:absolute;bottom:-8px;left:0;width:40px;height:3px;background-color:var(--ax-primary-500);border-radius:3px;transition:width .3s ease}.category-header:hover:after{width:60px}.empty-state{animation:fadeIn .5s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.task-checkbox ::ng-deep .ax-checkbox{transition:all .2s ease}.task-checkbox ::ng-deep .ax-checkbox:hover{transform:scale(1.1)}.due-date.overdue{animation:pulse 2s infinite}@keyframes pulse{0%{opacity:.7}50%{opacity:1}to{opacity:.7}}.ax-space-y-2>*{animation:slideInRight .3s ease forwards;opacity:0}.ax-space-y-2>*:nth-child(1){animation-delay:.05s}.ax-space-y-2>*:nth-child(2){animation-delay:.1s}.ax-space-y-2>*:nth-child(3){animation-delay:.15s}.ax-space-y-2>*:nth-child(4){animation-delay:.2s}.ax-space-y-2>*:nth-child(5){animation-delay:.25s}.ax-space-y-2>*:nth-child(6){animation-delay:.3s}.ax-space-y-2>*:nth-child(7){animation-delay:.35s}.ax-space-y-2>*:nth-child(8){animation-delay:.4s}.ax-space-y-2>*:nth-child(9){animation-delay:.45s}.ax-space-y-2>*:nth-child(10){animation-delay:.5s}@keyframes slideInRight{0%{opacity:0;transform:translate(10px)}to{opacity:1;transform:translate(0)}}\n"] }]
|
2310
2323
|
}] });
|
2311
2324
|
|
2312
2325
|
var tasklistWidget_component = /*#__PURE__*/Object.freeze({
|
@@ -2326,7 +2339,7 @@ const AXPTaskListWidget = {
|
|
2326
2339
|
// ====== Title ======
|
2327
2340
|
{
|
2328
2341
|
name: 'title',
|
2329
|
-
title: '
|
2342
|
+
title: '@dashboard:widgets.task-list.chart-title',
|
2330
2343
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2331
2344
|
schema: {
|
2332
2345
|
defaultValue: '',
|
@@ -2345,7 +2358,7 @@ const AXPTaskListWidget = {
|
|
2345
2358
|
// Display options
|
2346
2359
|
{
|
2347
2360
|
name: 'maxItems',
|
2348
|
-
title: '
|
2361
|
+
title: '@dashboard:widgets.task-list.max-items',
|
2349
2362
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2350
2363
|
schema: {
|
2351
2364
|
defaultValue: 10,
|
@@ -2364,7 +2377,7 @@ const AXPTaskListWidget = {
|
|
2364
2377
|
},
|
2365
2378
|
{
|
2366
2379
|
name: 'showDate',
|
2367
|
-
title: '
|
2380
|
+
title: '@dashboard:widgets.task-list.show-date',
|
2368
2381
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2369
2382
|
schema: {
|
2370
2383
|
defaultValue: true,
|
@@ -2379,7 +2392,7 @@ const AXPTaskListWidget = {
|
|
2379
2392
|
},
|
2380
2393
|
{
|
2381
2394
|
name: 'showAssignee',
|
2382
|
-
title: '
|
2395
|
+
title: '@dashboard:widgets.task-list.show-assignee',
|
2383
2396
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2384
2397
|
schema: {
|
2385
2398
|
defaultValue: true,
|
@@ -2394,7 +2407,7 @@ const AXPTaskListWidget = {
|
|
2394
2407
|
},
|
2395
2408
|
{
|
2396
2409
|
name: 'groupByCategory',
|
2397
|
-
title: '
|
2410
|
+
title: '@dashboard:widgets.task-list.group-by-category',
|
2398
2411
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2399
2412
|
schema: {
|
2400
2413
|
defaultValue: true,
|
@@ -2409,7 +2422,7 @@ const AXPTaskListWidget = {
|
|
2409
2422
|
},
|
2410
2423
|
{
|
2411
2424
|
name: 'showPriority',
|
2412
|
-
title: '
|
2425
|
+
title: '@dashboard:widgets.task-list.show-priority',
|
2413
2426
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2414
2427
|
schema: {
|
2415
2428
|
defaultValue: true,
|
@@ -2424,7 +2437,7 @@ const AXPTaskListWidget = {
|
|
2424
2437
|
},
|
2425
2438
|
{
|
2426
2439
|
name: 'allowMarkComplete',
|
2427
|
-
title: '
|
2440
|
+
title: '@dashboard:widgets.task-list.allow-complete',
|
2428
2441
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2429
2442
|
schema: {
|
2430
2443
|
defaultValue: true,
|
@@ -2445,7 +2458,7 @@ const AXPTaskListWidget = {
|
|
2445
2458
|
},
|
2446
2459
|
meta: {
|
2447
2460
|
dimensions: {
|
2448
|
-
width:
|
2461
|
+
width: 3,
|
2449
2462
|
height: 7,
|
2450
2463
|
minWidth: 3,
|
2451
2464
|
minHeight: 4,
|
@@ -3080,8 +3093,7 @@ class AXPWeatherWidgetViewComponent extends AXPValueWidgetComponent {
|
|
3080
3093
|
setTimeout(() => this.cdr.detectChanges());
|
3081
3094
|
},
|
3082
3095
|
error: (error) => {
|
3083
|
-
this.
|
3084
|
-
this.errorMessage.set(error.message || 'Failed to load weather data. Please try again.');
|
3096
|
+
this.handleError(error);
|
3085
3097
|
this.isLoading.set(false);
|
3086
3098
|
this.isForecastLoading.set(false);
|
3087
3099
|
this.cdr.detectChanges();
|
@@ -3102,8 +3114,7 @@ class AXPWeatherWidgetViewComponent extends AXPValueWidgetComponent {
|
|
3102
3114
|
setTimeout(() => this.cdr.detectChanges());
|
3103
3115
|
},
|
3104
3116
|
error: (error) => {
|
3105
|
-
this.
|
3106
|
-
this.errorMessage.set(error.message || 'Failed to load weather data. Please try again.');
|
3117
|
+
this.handleError(error);
|
3107
3118
|
this.isLoading.set(false);
|
3108
3119
|
this.cdr.detectChanges();
|
3109
3120
|
},
|
@@ -3208,7 +3219,11 @@ class AXPWeatherWidgetViewComponent extends AXPValueWidgetComponent {
|
|
3208
3219
|
*/
|
3209
3220
|
getConditionName(conditionId) {
|
3210
3221
|
const condition = this.weatherService.getCondition(conditionId);
|
3211
|
-
|
3222
|
+
if (!condition?.name)
|
3223
|
+
return 'weather.conditions.sunny';
|
3224
|
+
// Convert condition name to lowercase and replace spaces with hyphens
|
3225
|
+
const formattedName = condition.name.toLowerCase().replace(/\s+/g, '-');
|
3226
|
+
return `weather.conditions.${formattedName}`;
|
3212
3227
|
}
|
3213
3228
|
/**
|
3214
3229
|
* Gets the color for a weather condition
|
@@ -3226,22 +3241,60 @@ class AXPWeatherWidgetViewComponent extends AXPValueWidgetComponent {
|
|
3226
3241
|
cleanupChart() {
|
3227
3242
|
this.clearRefreshTimer();
|
3228
3243
|
}
|
3244
|
+
handleError(error) {
|
3245
|
+
console.error('Weather widget error:', error);
|
3246
|
+
this.hasError.set(true);
|
3247
|
+
// Check if it's a network error
|
3248
|
+
if (error.status === 0) {
|
3249
|
+
this.errorMessage.set('weather.error.network');
|
3250
|
+
return;
|
3251
|
+
}
|
3252
|
+
// Check if it's an API error
|
3253
|
+
if (error.status >= 400 && error.status < 500) {
|
3254
|
+
this.errorMessage.set('weather.error.api');
|
3255
|
+
return;
|
3256
|
+
}
|
3257
|
+
// Default error message
|
3258
|
+
this.errorMessage.set('weather.error.general');
|
3259
|
+
}
|
3260
|
+
getTemperatureUnit() {
|
3261
|
+
return this.temperatureUnit() === '°C' ? 'weather.units.celsius' : 'weather.units.fahrenheit';
|
3262
|
+
}
|
3263
|
+
getWindSpeedUnit() {
|
3264
|
+
return this.windSpeedUnit() === 'km/h' ? 'weather.units.kmh' : 'weather.units.mph';
|
3265
|
+
}
|
3266
|
+
getDayName(date) {
|
3267
|
+
const today = new Date();
|
3268
|
+
const tomorrow = new Date(today);
|
3269
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
3270
|
+
if (date.toDateString() === today.toDateString()) {
|
3271
|
+
return 'weather.days.today';
|
3272
|
+
}
|
3273
|
+
if (date.toDateString() === tomorrow.toDateString()) {
|
3274
|
+
return 'weather.days.tomorrow';
|
3275
|
+
}
|
3276
|
+
const days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
|
3277
|
+
return `weather.days.${days[date.getDay()]}`;
|
3278
|
+
}
|
3279
|
+
parseDate(dateStr) {
|
3280
|
+
return new Date(dateStr);
|
3281
|
+
}
|
3229
3282
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPWeatherWidgetViewComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
3230
3283
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPWeatherWidgetViewComponent, isStandalone: true, selector: "ng-component", providers: [
|
3231
3284
|
{
|
3232
3285
|
provide: AXPWeatherApiAbstract,
|
3233
3286
|
useClass: AXPWeatherApiService,
|
3234
3287
|
},
|
3235
|
-
], viewQueries: [{ propertyName: "containerEl", first: true, predicate: ["containerElement"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- Weather Widget Component Template -->\n<div class=\"axp-weather-container\" #containerElement>\n <!-- Loading indicator -->\n @if (isLoading()) {\n <div class=\"axp-weather-loading-overlay\">\n <div class=\"axp-weather-loading-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading weather data...</span>\n </div>\n </div>\n }\n\n <!-- Error message -->\n @if (hasError()) {\n <div class=\"axp-weather-error-overlay\">\n <div class=\"axp-weather-error-message\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ errorMessage() }}</span>\n <button class=\"axp-weather-retry-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Retry</span>\n </button>\n </div>\n </div>\n }\n\n <!-- Weather content - only show when we have data -->\n @if (weatherData()) {\n <!-- Background decorations based on weather condition -->\n <div class=\"axp-weather-background-decorations\">\n <div class=\"axp-weather-decoration\" [ngClass]=\"weatherData()?.current?.condition?.toLowerCase()\"></div>\n <div class=\"axp-weather-gradient-overlay\"></div>\n </div>\n\n <div class=\"axp-weather-inner\">\n <!-- Location information section -->\n <div class=\"axp-weather-location-info\">\n <div class=\"axp-weather-location-icon\">\n <i class=\"fa-solid fa-location-dot\"></i>\n </div>\n <div class=\"axp-weather-location-text\">\n <h2 class=\"axp-weather-location-name\">{{ city() }}</h2>\n </div>\n </div>\n\n <!-- Current weather conditions section -->\n <div class=\"axp-weather-current-weather\">\n <!-- Weather icon and condition name -->\n @if (showCurrentCondition()) {\n <div class=\"axp-weather-condition\">\n <div class=\"axp-weather-icon-wrapper\">\n <div class=\"axp-weather-icon\">\n <i\n [class]=\"getConditionIcon(weatherData()?.current?.condition || '')\"\n [style.color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></i>\n </div>\n <div\n class=\"axp-weather-icon-glow\"\n [style.background-color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></div>\n </div>\n <div class=\"axp-weather-condition-name\">{{ getCurrentCondition() }}</div>\n </div>\n }\n\n <!-- Temperature display -->\n @if (showTemperature()) {\n <div class=\"axp-weather-temperature\">\n <span class=\"axp-weather-temperature-value\">{{ getCurrentTemperature() }}</span>\n <span class=\"axp-weather-temperature-unit\">{{ temperatureUnit() }}</span>\n </div>\n }\n </div>\n\n <!-- Weather details section (humidity and wind) -->\n @if (showHumidity() || showWind()) {\n <div class=\"axp-weather-details\">\n <!-- Humidity information -->\n @if (showHumidity()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-droplet\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">Humidity</div>\n <div class=\"axp-weather-detail-value\">{{ getHumidity() }}%</div>\n </div>\n </div>\n }\n\n <!-- Wind speed information -->\n @if (showWind()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-wind\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">Wind</div>\n <div class=\"axp-weather-detail-value\">{{ getWindSpeed() }} {{ windSpeedUnit() }}</div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Weather forecast section -->\n @if (showForecast() && weatherData()?.forecast) {\n <div class=\"axp-weather-forecast\">\n <div class=\"axp-weather-forecast-header\">\n <h3 class=\"axp-weather-forecast-title\">\n <i class=\"fa-solid fa-calendar-days\"></i>\n <span>Forecast</span>\n </h3>\n <!-- <div class=\"axp-weather-scroll-indicator\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </div> -->\n </div>\n <!-- Loading indicator for forecast -->\n @if (isForecastLoading()) {\n <div class=\"axp-weather-forecast-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading forecast...</span>\n </div>\n }\n <!-- Scrollable forecast days display -->\n <div class=\"axp-weather-forecast-items\">\n @for (day of displayedForecast(); track day.day) {\n <div class=\"axp-weather-forecast-day\">\n <div class=\"axp-weather-forecast-day-name\">{{ day.day }}</div>\n <div class=\"axp-weather-forecast-icon\" title=\"{{ getConditionName(day.condition) }}\">\n <i [class]=\"getConditionIcon(day.condition)\" [style.color]=\"getConditionColor(day.condition)\"></i>\n </div>\n <div class=\"axp-weather-forecast-temps\">\n <span class=\"axp-weather-forecast-low\">\n {{ temperatureUnit() === '\u00B0C' ? day.minTempC : day.minTempF }}\u00B0\n </span>\n <span class=\"axp-weather-forecast-high\">\n {{ temperatureUnit() === '\u00B0C' ? day.maxTempC : day.maxTempF }}\u00B0\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Last updated timestamp -->\n <div class=\"axp-weather-last-updated\">\n <span>Last updated: {{ getLastUpdated() }}</span>\n </div>\n\n <!-- Manual refresh button -->\n <div class=\"axp-weather-refresh-action\">\n <button\n class=\"axp-weather-refresh-button\"\n (click)=\"refreshWeather()\"\n [attr.aria-label]=\"'Refresh weather data'\"\n title=\"Refresh weather data\"\n >\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Refresh</span>\n </button>\n </div>\n </div>\n } @else if (!isLoading() && !hasError()) {\n <!-- No data state (not loading, no error) -->\n <div class=\"axp-weather-no-data-state\">\n <i class=\"fa-solid fa-cloud-sun\"></i>\n <p>No weather data available</p>\n <button class=\"axp-weather-refresh-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Load Data</span>\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;height:100%;--primary-gradient-start: #2196f3;--primary-gradient-end: #1976d2;--shadow-color: rgba(0, 0, 0, .2);--glass-bg: rgba(255, 255, 255, .15);--glass-border: rgba(255, 255, 255, .2);--text-primary: rgba(255, 255, 255, .95);--text-secondary: rgba(255, 255, 255, .75);--transition-speed: .3s}.axp-weather-container{width:100%;height:100%;border-radius:8px;overflow:hidden;position:relative;box-shadow:0 4px 8px rgba(0,0,0,.1);color:#fff;min-height:300px;background-color:#2c3e50}.axp-weather-loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(44,62,80,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-loading-spinner{text-align:center}.axp-weather-loading-spinner i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-loading-spinner span{display:block;color:#fff;font-size:1rem}.axp-weather-error-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(189,54,47,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-error-message{text-align:center;padding:1rem}.axp-weather-error-message i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-error-message span{display:block;color:#fff;font-size:1.1rem;margin-bottom:1rem}.axp-weather-error-message .axp-weather-retry-button{color:#bd362f;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-error-message .axp-weather-retry-button:hover{transform:translateY(-1px)}.axp-weather-no-data-state{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;padding:2rem;text-align:center}.axp-weather-no-data-state i{font-size:3rem;margin-bottom:1rem;color:rgba(255,255,255,.8)}.axp-weather-no-data-state p{margin-bottom:1.5rem;font-size:1.1rem}.axp-weather-no-data-state .axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-no-data-state .axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-background-decorations{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.axp-weather-decoration{position:absolute;top:0;left:0;width:100%;height:100%;background-size:cover;background-position:center}.axp-weather-decoration.sunny{background:linear-gradient(135deg,#ff7e00,#f7d358)}.axp-weather-decoration.partlyCloudy{background:linear-gradient(135deg,#7ba2e7,#b4d2f7)}.axp-weather-decoration.cloudy{background:linear-gradient(135deg,#717e8c,#919eab)}.axp-weather-decoration.rain{background:linear-gradient(135deg,#6a8caf,#567a9e)}.axp-weather-decoration.snow{background:linear-gradient(135deg,#99b3cc,#c6d4e1)}.axp-weather-decoration.thunder{background:linear-gradient(135deg,#425777,#2c3e50)}.axp-weather-decoration.mist{background:linear-gradient(135deg,#94a3b8,#cbd5e1)}.axp-weather-gradient-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.5))}.axp-weather-inner{position:relative;z-index:2;height:100%;padding:1.5rem;display:flex;flex-direction:column}.axp-weather-location-info{display:flex;align-items:center;margin-bottom:1.5rem}.axp-weather-location-icon{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background-color:rgba(255,255,255,.2);border-radius:50%;margin-right:.75rem}.axp-weather-location-icon i{color:#fff}.axp-weather-location-name{margin:0;font-size:1.5rem;font-weight:500;text-shadow:1px 1px 3px rgba(0,0,0,.2);text-transform:capitalize}.axp-weather-current-weather{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;flex-wrap:wrap}.axp-weather-condition{display:flex;flex-direction:column;align-items:center}.axp-weather-icon-wrapper{position:relative;margin-bottom:.5rem}.axp-weather-icon{position:relative;z-index:2}.axp-weather-icon i{font-size:2.75rem;filter:drop-shadow(0 0 8px rgba(0,0,0,.3))}.axp-weather-icon-glow{position:absolute;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);width:45px;height:45px;border-radius:50%;filter:blur(15px);opacity:.75}.axp-weather-condition-name{font-size:1.1rem;text-align:center;text-shadow:1px 1px 2px rgba(0,0,0,.2)}.axp-weather-temperature{display:flex;align-items:flex-start;text-shadow:1px 1px 3px rgba(0,0,0,.3)}.axp-weather-temperature-value{font-size:3.5rem;font-weight:500;line-height:1}.axp-weather-temperature-unit{font-size:1.5rem;margin-top:.25rem}.axp-weather-details{display:flex;flex-wrap:wrap;gap:1.5rem;margin-bottom:1.5rem;padding:1rem;background-color:rgba(0,0,0,.15);border-radius:8px}.axp-weather-detail-item{display:flex;align-items:center;flex:1;min-width:120px}.axp-weather-detail-icon{width:40px;height:40px;border-radius:50%;background-color:rgba(255,255,255,.2);display:flex;align-items:center;justify-content:center;margin-right:.75rem}.axp-weather-detail-icon i{font-size:1.25rem}.axp-weather-detail-info{display:flex;flex-direction:column}.axp-weather-detail-label{font-size:.875rem;color:rgba(255,255,255,.8);margin-bottom:.25rem}.axp-weather-detail-value{font-size:1.125rem;font-weight:500}.axp-weather-forecast{margin-top:auto;margin-bottom:1rem;background-color:rgba(0,0,0,.15);border-radius:8px;padding:1rem}.axp-weather-forecast-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.axp-weather-forecast-title{margin:0;font-size:1.125rem;font-weight:500;display:flex;align-items:center}.axp-weather-forecast-title i{margin-right:.5rem;opacity:.8}.axp-weather-scroll-indicator{color:rgba(255,255,255,.6)}.axp-weather-forecast-items{display:flex;overflow-x:auto;gap:.75rem;padding-bottom:.5rem}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.3);border-radius:4px}.axp-weather-forecast-items::-webkit-scrollbar-track{background-color:rgba(0,0,0,.1);border-radius:4px}.axp-weather-forecast-day{min-width:80px;display:flex;flex-direction:column;align-items:center;padding:.75rem .5rem;background-color:rgba(255,255,255,.1);border-radius:6px;transition:all .3s ease}.axp-weather-forecast-day:hover{background-color:rgba(255,255,255,.15);transform:translateY(-2px)}.axp-weather-forecast-day-name{font-size:.875rem;margin-bottom:.5rem;font-weight:500}.axp-weather-forecast-icon{font-size:1.5rem;margin-bottom:.5rem}.axp-weather-forecast-icon i{filter:drop-shadow(0 0 5px rgba(0,0,0,.2))}.axp-weather-forecast-temps{display:flex;flex-direction:row;gap:.75rem;align-items:center;font-size:.875rem}.axp-weather-last-updated{text-align:center;font-size:.75rem;opacity:.7;margin-bottom:.5rem}.axp-weather-refresh-action{text-align:center}.axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:.875rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-refresh-button i{font-size:.875rem}@media (max-width: 576px){.axp-weather-inner{padding:.8rem;gap:.4rem}.axp-weather-location-name{font-size:1.1rem}.axp-weather-temperature{font-size:2.5rem}.axp-weather-temperature-unit{font-size:1.1rem}.axp-weather-weather-details{flex-direction:column;gap:.5rem}.axp-weather-forecast-items{flex-wrap:nowrap;overflow-x:auto;padding-bottom:.5rem;margin:0 -.4rem;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;scrollbar-width:thin;mask-image:linear-gradient(to right,#000 95%,rgba(0,0,0,0));-webkit-mask-image:linear-gradient(to right,rgb(0,0,0) 95%,rgba(0,0,0,0))}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.2);border-radius:4px}.axp-weather-forecast-day{min-width:60px;flex:0 0 auto;padding:.4rem .6rem}.axp-weather-forecast-day-name{font-size:.7rem}.axp-weather-forecast-icon{padding:.3rem;height:1.6rem}.axp-weather-forecast-temps{font-size:.7rem}.axp-weather-scroll-indicator{display:block}}:host-context(.theme-dark){--glass-bg: rgba(0, 0, 0, .3);--glass-border: rgba(255, 255, 255, .1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: AXDateTimeModule }, { kind: "ngmodule", type: AXFormatModule }, { kind: "ngmodule", type: HttpClientModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
3288
|
+
], viewQueries: [{ propertyName: "containerEl", first: true, predicate: ["containerElement"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- Weather Widget Component Template -->\n<div class=\"axp-weather-container\" #containerElement>\n <!-- Loading indicator -->\n @if (isLoading()) {\n <div class=\"axp-weather-loading-overlay\">\n <div class=\"axp-weather-loading-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>{{ 'weather.loading' | translate: { scope: 'dashboard' } | async }}</span>\n </div>\n </div>\n }\n\n <!-- Error message -->\n @if (hasError()) {\n <div class=\"axp-weather-error-overlay\">\n <div class=\"axp-weather-error-message\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ errorMessage() | translate: { scope: 'dashboard' } | async }}</span>\n <button class=\"axp-weather-retry-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>{{ 'weather.retry' | translate: { scope: 'dashboard' } | async }}</span>\n </button>\n </div>\n </div>\n }\n\n <!-- Weather content - only show when we have data -->\n @if (weatherData()) {\n <!-- Background decorations based on weather condition -->\n <div class=\"axp-weather-background-decorations\">\n <div class=\"axp-weather-decoration\" [ngClass]=\"weatherData()?.current?.condition?.toLowerCase()\"></div>\n <div class=\"axp-weather-gradient-overlay\"></div>\n </div>\n\n <div class=\"axp-weather-inner\">\n <!-- Location information section -->\n <div class=\"axp-weather-location-info\">\n <div class=\"axp-weather-location-icon\">\n <i class=\"fa-solid fa-location-dot\"></i>\n </div>\n <div class=\"axp-weather-location-text\">\n <h2 class=\"axp-weather-location-name\">{{ city() }}</h2>\n </div>\n </div>\n\n <!-- Current weather conditions section -->\n <div class=\"axp-weather-current-weather\">\n <!-- Weather icon and condition name -->\n @if (showCurrentCondition()) {\n <div class=\"axp-weather-condition\">\n <div class=\"axp-weather-icon-wrapper\">\n <div class=\"axp-weather-icon\">\n <i\n [class]=\"getConditionIcon(weatherData()?.current?.condition || '')\"\n [style.color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></i>\n </div>\n <div\n class=\"axp-weather-icon-glow\"\n [style.background-color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></div>\n </div>\n <div class=\"axp-weather-condition-name\">\n {{ getCurrentCondition() | translate: { scope: 'dashboard' } | async }}\n </div>\n </div>\n }\n\n <!-- Temperature display -->\n @if (showTemperature()) {\n <div class=\"axp-weather-temperature\">\n <span class=\"axp-weather-temperature-value\">{{ getCurrentTemperature() }}</span>\n <span class=\"axp-weather-temperature-unit\">{{\n getTemperatureUnit() | translate: { scope: 'dashboard' } | async\n }}</span>\n </div>\n }\n </div>\n\n <!-- Weather details section (humidity and wind) -->\n @if (showHumidity() || showWind()) {\n <div class=\"axp-weather-details\">\n <!-- Humidity information -->\n @if (showHumidity()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-droplet\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">\n {{ 'weather.humidity' | translate: { scope: 'dashboard' } | async }}\n </div>\n <div class=\"axp-weather-detail-value\">{{ getHumidity() }}%</div>\n </div>\n </div>\n }\n\n <!-- Wind speed information -->\n @if (showWind()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-wind\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">\n {{ 'weather.wind' | translate: { scope: 'dashboard' } | async }}\n </div>\n <div class=\"axp-weather-detail-value\">\n {{ getWindSpeed() }} {{ getWindSpeedUnit() | translate: { scope: 'dashboard' } | async }}\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Weather forecast section -->\n @if (showForecast() && weatherData()?.forecast) {\n <div class=\"axp-weather-forecast\">\n <div class=\"axp-weather-forecast-header\">\n <h3 class=\"axp-weather-forecast-title\">\n <i class=\"fa-solid fa-calendar-days\"></i>\n <span class=\"ax-px-1\">{{ 'weather.forecast' | translate: { scope: 'dashboard' } | async }}</span>\n </h3>\n </div>\n <!-- Loading indicator for forecast -->\n <!-- @if (isForecastLoading()) {\n <div class=\"axp-weather-forecast-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>{{ 'weather.loading-forecast' | translate: { scope: 'dashboard' } | async }}</span>\n </div>\n } -->\n <!-- Scrollable forecast days display -->\n <div class=\"axp-weather-forecast-items\">\n @for (day of displayedForecast(); track day.day) {\n <div class=\"axp-weather-forecast-day\">\n <div class=\"axp-weather-forecast-day-name\">\n {{ getDayName(parseDate(day.date)) | translate: { scope: 'dashboard' } | async }}\n </div>\n <div\n class=\"axp-weather-forecast-icon\"\n [title]=\"getConditionName(day.condition) | translate: { scope: 'dashboard' } | async\"\n >\n <i [class]=\"getConditionIcon(day.condition)\" [style.color]=\"getConditionColor(day.condition)\"></i>\n </div>\n <div class=\"axp-weather-forecast-temps\">\n <span class=\"axp-weather-forecast-low\">\n {{ temperatureUnit() === '\u00B0C' ? day.minTempC : day.minTempF\n }}{{ getTemperatureUnit() | translate: { scope: 'dashboard' } | async }}\n </span>\n <span class=\"axp-weather-forecast-high\">\n {{ temperatureUnit() === '\u00B0C' ? day.maxTempC : day.maxTempF\n }}{{ getTemperatureUnit() | translate: { scope: 'dashboard' } | async }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Last updated timestamp -->\n <div class=\"axp-weather-last-updated\">\n <span>{{ 'weather.last-updated' | translate: { scope: 'dashboard' } | async }}: {{ getLastUpdated() }}</span>\n </div>\n\n <!-- Manual refresh button -->\n <div class=\"axp-weather-refresh-action\">\n <button\n class=\"axp-weather-refresh-button\"\n (click)=\"refreshWeather()\"\n [attr.aria-label]=\"'weather.refresh' | translate: { scope: 'dashboard' } | async\"\n [title]=\"'weather.refresh' | translate: { scope: 'dashboard' } | async\"\n >\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>{{ 'weather.refresh' | translate: { scope: 'dashboard' } | async }}</span>\n </button>\n </div>\n </div>\n } @else if (!isLoading() && !hasError()) {\n <!-- No data state (not loading, no error) -->\n <div class=\"axp-weather-no-data-state\">\n <i class=\"fa-solid fa-cloud-sun\"></i>\n <p>{{ 'weather.no-data' | translate: { scope: 'dashboard' } | async }}</p>\n <button class=\"axp-weather-refresh-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>{{ 'weather.load-data' | translate: { scope: 'dashboard' } | async }}</span>\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;height:100%;--primary-gradient-start: #2196f3;--primary-gradient-end: #1976d2;--shadow-color: rgba(0, 0, 0, .2);--glass-bg: rgba(255, 255, 255, .15);--glass-border: rgba(255, 255, 255, .2);--text-primary: rgba(255, 255, 255, .95);--text-secondary: rgba(255, 255, 255, .75);--transition-speed: .3s}.axp-weather-container{width:100%;height:100%;overflow:hidden;position:relative;box-shadow:0 4px 8px rgba(0,0,0,.1);color:#fff;min-height:300px;background-color:#2c3e50}.axp-weather-loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(44,62,80,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-loading-spinner{text-align:center}.axp-weather-loading-spinner i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-loading-spinner span{display:block;color:#fff;font-size:1rem}.axp-weather-error-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(189,54,47,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-error-message{text-align:center;padding:1rem}.axp-weather-error-message i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-error-message span{display:block;color:#fff;font-size:1.1rem;margin-bottom:1rem}.axp-weather-error-message .axp-weather-retry-button{color:#bd362f;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-error-message .axp-weather-retry-button:hover{transform:translateY(-1px)}.axp-weather-no-data-state{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;padding:2rem;text-align:center}.axp-weather-no-data-state i{font-size:3rem;margin-bottom:1rem;color:rgba(255,255,255,.8)}.axp-weather-no-data-state p{margin-bottom:1.5rem;font-size:1.1rem}.axp-weather-no-data-state .axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-no-data-state .axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-background-decorations{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.axp-weather-decoration{position:absolute;top:0;left:0;width:100%;height:100%;background-size:cover;background-position:center}.axp-weather-decoration.sunny{background:linear-gradient(135deg,#ff7e00,#f7d358)}.axp-weather-decoration.partlyCloudy{background:linear-gradient(135deg,#7ba2e7,#b4d2f7)}.axp-weather-decoration.cloudy{background:linear-gradient(135deg,#717e8c,#919eab)}.axp-weather-decoration.rain{background:linear-gradient(135deg,#6a8caf,#567a9e)}.axp-weather-decoration.snow{background:linear-gradient(135deg,#99b3cc,#c6d4e1)}.axp-weather-decoration.thunder{background:linear-gradient(135deg,#425777,#2c3e50)}.axp-weather-decoration.mist{background:linear-gradient(135deg,#94a3b8,#cbd5e1)}.axp-weather-gradient-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.5))}.axp-weather-inner{position:relative;z-index:2;height:100%;padding:1.5rem;display:flex;flex-direction:column;justify-content:space-between}.axp-weather-location-info{display:flex;align-items:center;margin-bottom:1.5rem}.axp-weather-location-icon{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background-color:rgba(255,255,255,.2);border-radius:50%;margin-right:.75rem}.axp-weather-location-icon i{color:#fff}.axp-weather-location-name{margin:0;font-size:1.5rem;font-weight:500;text-shadow:1px 1px 3px rgba(0,0,0,.2);text-transform:capitalize}.axp-weather-current-weather{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;flex-wrap:wrap}.axp-weather-condition{display:flex;flex-direction:column;align-items:center}.axp-weather-icon-wrapper{position:relative;margin-bottom:.5rem}.axp-weather-icon{position:relative;z-index:2}.axp-weather-icon i{font-size:2.75rem;filter:drop-shadow(0 0 8px rgba(0,0,0,.3))}.axp-weather-icon-glow{position:absolute;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);width:45px;height:45px;border-radius:50%;filter:blur(15px);opacity:.75}.axp-weather-condition-name{font-size:1.1rem;text-align:center;text-shadow:1px 1px 2px rgba(0,0,0,.2)}.axp-weather-temperature{display:flex;align-items:flex-start;text-shadow:1px 1px 3px rgba(0,0,0,.3)}.axp-weather-temperature-value{font-size:3.5rem;font-weight:500;line-height:1}.axp-weather-temperature-unit{font-size:1.5rem;margin-top:.25rem}.axp-weather-details{display:flex;flex-wrap:wrap;gap:1.5rem;margin-bottom:1rem;padding:1rem;background-color:rgba(0,0,0,.15);border-radius:8px}.axp-weather-detail-item{display:flex;align-items:center;flex:1;min-width:120px}.axp-weather-detail-icon{width:40px;height:40px;border-radius:50%;background-color:rgba(255,255,255,.2);display:flex;align-items:center;justify-content:center;margin-right:.75rem}.axp-weather-detail-icon i{font-size:1.25rem}.axp-weather-detail-info{display:flex;padding-inline:.25rem;flex-direction:column}.axp-weather-detail-label{font-size:.875rem;color:rgba(255,255,255,.8);margin-bottom:.25rem}.axp-weather-detail-value{font-size:1.125rem;font-weight:500}.axp-weather-forecast{margin-bottom:.5rem;background-color:rgba(0,0,0,.15);border-radius:8px;padding:1rem}.axp-weather-forecast-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.axp-weather-forecast-title{margin:0;font-size:1.125rem;font-weight:500;display:flex;align-items:center}.axp-weather-forecast-title i{margin-right:.5rem;opacity:.8}.axp-weather-scroll-indicator{color:rgba(255,255,255,.6)}.axp-weather-forecast-items{display:flex;overflow-x:auto;gap:.75rem;padding-bottom:.5rem}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.3);border-radius:4px}.axp-weather-forecast-items::-webkit-scrollbar-track{background-color:rgba(0,0,0,.1);border-radius:4px}.axp-weather-forecast-day{min-width:90px;display:flex;flex-direction:column;align-items:center;padding:.75rem .5rem;background-color:rgba(255,255,255,.1);border-radius:6px;transition:all .3s ease}.axp-weather-forecast-day:hover{background-color:rgba(255,255,255,.15);transform:translateY(-2px)}.axp-weather-forecast-day-name{font-size:.875rem;margin-bottom:.5rem;font-weight:500}.axp-weather-forecast-icon{font-size:1.5rem;margin-bottom:.5rem}.axp-weather-forecast-icon i{filter:drop-shadow(0 0 5px rgba(0,0,0,.2))}.axp-weather-forecast-temps{display:flex;flex-direction:row;gap:.75rem;align-items:center;font-size:.775rem}.axp-weather-last-updated{text-align:center;font-size:.75rem;opacity:.7;margin-bottom:.5rem}.axp-weather-refresh-action{text-align:center}.axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:.875rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-refresh-button i{font-size:.875rem}@media (max-width: 576px){.axp-weather-inner{padding:.8rem;gap:.4rem}.axp-weather-location-name{font-size:1.1rem;padding-inline:.25rem}.axp-weather-temperature{font-size:2.5rem}.axp-weather-temperature-unit{font-size:1.1rem}.axp-weather-weather-details{flex-direction:column;gap:.5rem}.axp-weather-forecast-items{flex-wrap:nowrap;overflow-x:auto;padding-bottom:.5rem;margin:0 -.4rem;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;scrollbar-width:thin;mask-image:linear-gradient(to right,#000 95%,rgba(0,0,0,0));-webkit-mask-image:linear-gradient(to right,rgb(0,0,0) 95%,rgba(0,0,0,0))}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.2);border-radius:4px}.axp-weather-forecast-day{min-width:60px;flex:0 0 auto;padding:.4rem .6rem}.axp-weather-forecast-day-name{font-size:.7rem}.axp-weather-forecast-icon{padding:.3rem;height:1.6rem}.axp-weather-forecast-temps{font-size:.7rem}.axp-weather-scroll-indicator{display:block}}:host-context(.theme-dark){--glass-bg: rgba(0, 0, 0, .3);--glass-border: rgba(255, 255, 255, .1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXDateTimeModule }, { kind: "ngmodule", type: AXFormatModule }, { kind: "ngmodule", type: HttpClientModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i2$3.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
3236
3289
|
}
|
3237
3290
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPWeatherWidgetViewComponent, decorators: [{
|
3238
3291
|
type: Component,
|
3239
|
-
args: [{ standalone: true, imports: [CommonModule, AXDateTimeModule, AXFormatModule, HttpClientModule], providers: [
|
3292
|
+
args: [{ standalone: true, imports: [CommonModule, AXDateTimeModule, AXFormatModule, HttpClientModule, AXTranslationModule], providers: [
|
3240
3293
|
{
|
3241
3294
|
provide: AXPWeatherApiAbstract,
|
3242
3295
|
useClass: AXPWeatherApiService,
|
3243
3296
|
},
|
3244
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Weather Widget Component Template -->\n<div class=\"axp-weather-container\" #containerElement>\n <!-- Loading indicator -->\n @if (isLoading()) {\n <div class=\"axp-weather-loading-overlay\">\n <div class=\"axp-weather-loading-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading weather data...</span>\n </div>\n </div>\n }\n\n <!-- Error message -->\n @if (hasError()) {\n <div class=\"axp-weather-error-overlay\">\n <div class=\"axp-weather-error-message\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ errorMessage() }}</span>\n <button class=\"axp-weather-retry-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Retry</span>\n </button>\n </div>\n </div>\n }\n\n <!-- Weather content - only show when we have data -->\n @if (weatherData()) {\n <!-- Background decorations based on weather condition -->\n <div class=\"axp-weather-background-decorations\">\n <div class=\"axp-weather-decoration\" [ngClass]=\"weatherData()?.current?.condition?.toLowerCase()\"></div>\n <div class=\"axp-weather-gradient-overlay\"></div>\n </div>\n\n <div class=\"axp-weather-inner\">\n <!-- Location information section -->\n <div class=\"axp-weather-location-info\">\n <div class=\"axp-weather-location-icon\">\n <i class=\"fa-solid fa-location-dot\"></i>\n </div>\n <div class=\"axp-weather-location-text\">\n <h2 class=\"axp-weather-location-name\">{{ city() }}</h2>\n </div>\n </div>\n\n <!-- Current weather conditions section -->\n <div class=\"axp-weather-current-weather\">\n <!-- Weather icon and condition name -->\n @if (showCurrentCondition()) {\n <div class=\"axp-weather-condition\">\n <div class=\"axp-weather-icon-wrapper\">\n <div class=\"axp-weather-icon\">\n <i\n [class]=\"getConditionIcon(weatherData()?.current?.condition || '')\"\n [style.color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></i>\n </div>\n <div\n class=\"axp-weather-icon-glow\"\n [style.background-color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></div>\n </div>\n <div class=\"axp-weather-condition-name\">{{ getCurrentCondition() }}</div>\n </div>\n }\n\n <!-- Temperature display -->\n @if (showTemperature()) {\n <div class=\"axp-weather-temperature\">\n <span class=\"axp-weather-temperature-value\">{{ getCurrentTemperature() }}</span>\n <span class=\"axp-weather-temperature-unit\">{{ temperatureUnit() }}</span>\n </div>\n }\n </div>\n\n <!-- Weather details section (humidity and wind) -->\n @if (showHumidity() || showWind()) {\n <div class=\"axp-weather-details\">\n <!-- Humidity information -->\n @if (showHumidity()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-droplet\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">Humidity</div>\n <div class=\"axp-weather-detail-value\">{{ getHumidity() }}%</div>\n </div>\n </div>\n }\n\n <!-- Wind speed information -->\n @if (showWind()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-wind\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">Wind</div>\n <div class=\"axp-weather-detail-value\">{{ getWindSpeed() }} {{ windSpeedUnit() }}</div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Weather forecast section -->\n @if (showForecast() && weatherData()?.forecast) {\n <div class=\"axp-weather-forecast\">\n <div class=\"axp-weather-forecast-header\">\n <h3 class=\"axp-weather-forecast-title\">\n <i class=\"fa-solid fa-calendar-days\"></i>\n <span>Forecast</span>\n </h3>\n <!-- <div class=\"axp-weather-scroll-indicator\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </div> -->\n </div>\n <!-- Loading indicator for forecast -->\n @if (isForecastLoading()) {\n <div class=\"axp-weather-forecast-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading forecast...</span>\n </div>\n }\n <!-- Scrollable forecast days display -->\n <div class=\"axp-weather-forecast-items\">\n @for (day of displayedForecast(); track day.day) {\n <div class=\"axp-weather-forecast-day\">\n <div class=\"axp-weather-forecast-day-name\">{{ day.day }}</div>\n <div class=\"axp-weather-forecast-icon\" title=\"{{ getConditionName(day.condition) }}\">\n <i [class]=\"getConditionIcon(day.condition)\" [style.color]=\"getConditionColor(day.condition)\"></i>\n </div>\n <div class=\"axp-weather-forecast-temps\">\n <span class=\"axp-weather-forecast-low\">\n {{ temperatureUnit() === '\u00B0C' ? day.minTempC : day.minTempF }}\u00B0\n </span>\n <span class=\"axp-weather-forecast-high\">\n {{ temperatureUnit() === '\u00B0C' ? day.maxTempC : day.maxTempF }}\u00B0\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Last updated timestamp -->\n <div class=\"axp-weather-last-updated\">\n <span>Last updated: {{ getLastUpdated() }}</span>\n </div>\n\n <!-- Manual refresh button -->\n <div class=\"axp-weather-refresh-action\">\n <button\n class=\"axp-weather-refresh-button\"\n (click)=\"refreshWeather()\"\n [attr.aria-label]=\"'Refresh weather data'\"\n title=\"Refresh weather data\"\n >\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Refresh</span>\n </button>\n </div>\n </div>\n } @else if (!isLoading() && !hasError()) {\n <!-- No data state (not loading, no error) -->\n <div class=\"axp-weather-no-data-state\">\n <i class=\"fa-solid fa-cloud-sun\"></i>\n <p>No weather data available</p>\n <button class=\"axp-weather-refresh-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Load Data</span>\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;height:100%;--primary-gradient-start: #2196f3;--primary-gradient-end: #1976d2;--shadow-color: rgba(0, 0, 0, .2);--glass-bg: rgba(255, 255, 255, .15);--glass-border: rgba(255, 255, 255, .2);--text-primary: rgba(255, 255, 255, .95);--text-secondary: rgba(255, 255, 255, .75);--transition-speed: .3s}.axp-weather-container{width:100%;height:100%;border-radius:8px;overflow:hidden;position:relative;box-shadow:0 4px 8px rgba(0,0,0,.1);color:#fff;min-height:300px;background-color:#2c3e50}.axp-weather-loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(44,62,80,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-loading-spinner{text-align:center}.axp-weather-loading-spinner i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-loading-spinner span{display:block;color:#fff;font-size:1rem}.axp-weather-error-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(189,54,47,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-error-message{text-align:center;padding:1rem}.axp-weather-error-message i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-error-message span{display:block;color:#fff;font-size:1.1rem;margin-bottom:1rem}.axp-weather-error-message .axp-weather-retry-button{color:#bd362f;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-error-message .axp-weather-retry-button:hover{transform:translateY(-1px)}.axp-weather-no-data-state{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;padding:2rem;text-align:center}.axp-weather-no-data-state i{font-size:3rem;margin-bottom:1rem;color:rgba(255,255,255,.8)}.axp-weather-no-data-state p{margin-bottom:1.5rem;font-size:1.1rem}.axp-weather-no-data-state .axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-no-data-state .axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-background-decorations{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.axp-weather-decoration{position:absolute;top:0;left:0;width:100%;height:100%;background-size:cover;background-position:center}.axp-weather-decoration.sunny{background:linear-gradient(135deg,#ff7e00,#f7d358)}.axp-weather-decoration.partlyCloudy{background:linear-gradient(135deg,#7ba2e7,#b4d2f7)}.axp-weather-decoration.cloudy{background:linear-gradient(135deg,#717e8c,#919eab)}.axp-weather-decoration.rain{background:linear-gradient(135deg,#6a8caf,#567a9e)}.axp-weather-decoration.snow{background:linear-gradient(135deg,#99b3cc,#c6d4e1)}.axp-weather-decoration.thunder{background:linear-gradient(135deg,#425777,#2c3e50)}.axp-weather-decoration.mist{background:linear-gradient(135deg,#94a3b8,#cbd5e1)}.axp-weather-gradient-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.5))}.axp-weather-inner{position:relative;z-index:2;height:100%;padding:1.5rem;display:flex;flex-direction:column}.axp-weather-location-info{display:flex;align-items:center;margin-bottom:1.5rem}.axp-weather-location-icon{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background-color:rgba(255,255,255,.2);border-radius:50%;margin-right:.75rem}.axp-weather-location-icon i{color:#fff}.axp-weather-location-name{margin:0;font-size:1.5rem;font-weight:500;text-shadow:1px 1px 3px rgba(0,0,0,.2);text-transform:capitalize}.axp-weather-current-weather{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;flex-wrap:wrap}.axp-weather-condition{display:flex;flex-direction:column;align-items:center}.axp-weather-icon-wrapper{position:relative;margin-bottom:.5rem}.axp-weather-icon{position:relative;z-index:2}.axp-weather-icon i{font-size:2.75rem;filter:drop-shadow(0 0 8px rgba(0,0,0,.3))}.axp-weather-icon-glow{position:absolute;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);width:45px;height:45px;border-radius:50%;filter:blur(15px);opacity:.75}.axp-weather-condition-name{font-size:1.1rem;text-align:center;text-shadow:1px 1px 2px rgba(0,0,0,.2)}.axp-weather-temperature{display:flex;align-items:flex-start;text-shadow:1px 1px 3px rgba(0,0,0,.3)}.axp-weather-temperature-value{font-size:3.5rem;font-weight:500;line-height:1}.axp-weather-temperature-unit{font-size:1.5rem;margin-top:.25rem}.axp-weather-details{display:flex;flex-wrap:wrap;gap:1.5rem;margin-bottom:1.5rem;padding:1rem;background-color:rgba(0,0,0,.15);border-radius:8px}.axp-weather-detail-item{display:flex;align-items:center;flex:1;min-width:120px}.axp-weather-detail-icon{width:40px;height:40px;border-radius:50%;background-color:rgba(255,255,255,.2);display:flex;align-items:center;justify-content:center;margin-right:.75rem}.axp-weather-detail-icon i{font-size:1.25rem}.axp-weather-detail-info{display:flex;flex-direction:column}.axp-weather-detail-label{font-size:.875rem;color:rgba(255,255,255,.8);margin-bottom:.25rem}.axp-weather-detail-value{font-size:1.125rem;font-weight:500}.axp-weather-forecast{margin-top:auto;margin-bottom:1rem;background-color:rgba(0,0,0,.15);border-radius:8px;padding:1rem}.axp-weather-forecast-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.axp-weather-forecast-title{margin:0;font-size:1.125rem;font-weight:500;display:flex;align-items:center}.axp-weather-forecast-title i{margin-right:.5rem;opacity:.8}.axp-weather-scroll-indicator{color:rgba(255,255,255,.6)}.axp-weather-forecast-items{display:flex;overflow-x:auto;gap:.75rem;padding-bottom:.5rem}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.3);border-radius:4px}.axp-weather-forecast-items::-webkit-scrollbar-track{background-color:rgba(0,0,0,.1);border-radius:4px}.axp-weather-forecast-day{min-width:80px;display:flex;flex-direction:column;align-items:center;padding:.75rem .5rem;background-color:rgba(255,255,255,.1);border-radius:6px;transition:all .3s ease}.axp-weather-forecast-day:hover{background-color:rgba(255,255,255,.15);transform:translateY(-2px)}.axp-weather-forecast-day-name{font-size:.875rem;margin-bottom:.5rem;font-weight:500}.axp-weather-forecast-icon{font-size:1.5rem;margin-bottom:.5rem}.axp-weather-forecast-icon i{filter:drop-shadow(0 0 5px rgba(0,0,0,.2))}.axp-weather-forecast-temps{display:flex;flex-direction:row;gap:.75rem;align-items:center;font-size:.875rem}.axp-weather-last-updated{text-align:center;font-size:.75rem;opacity:.7;margin-bottom:.5rem}.axp-weather-refresh-action{text-align:center}.axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:.875rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-refresh-button i{font-size:.875rem}@media (max-width: 576px){.axp-weather-inner{padding:.8rem;gap:.4rem}.axp-weather-location-name{font-size:1.1rem}.axp-weather-temperature{font-size:2.5rem}.axp-weather-temperature-unit{font-size:1.1rem}.axp-weather-weather-details{flex-direction:column;gap:.5rem}.axp-weather-forecast-items{flex-wrap:nowrap;overflow-x:auto;padding-bottom:.5rem;margin:0 -.4rem;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;scrollbar-width:thin;mask-image:linear-gradient(to right,#000 95%,rgba(0,0,0,0));-webkit-mask-image:linear-gradient(to right,rgb(0,0,0) 95%,rgba(0,0,0,0))}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.2);border-radius:4px}.axp-weather-forecast-day{min-width:60px;flex:0 0 auto;padding:.4rem .6rem}.axp-weather-forecast-day-name{font-size:.7rem}.axp-weather-forecast-icon{padding:.3rem;height:1.6rem}.axp-weather-forecast-temps{font-size:.7rem}.axp-weather-scroll-indicator{display:block}}:host-context(.theme-dark){--glass-bg: rgba(0, 0, 0, .3);--glass-border: rgba(255, 255, 255, .1)}\n"] }]
|
3297
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Weather Widget Component Template -->\n<div class=\"axp-weather-container\" #containerElement>\n <!-- Loading indicator -->\n @if (isLoading()) {\n <div class=\"axp-weather-loading-overlay\">\n <div class=\"axp-weather-loading-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>{{ 'weather.loading' | translate: { scope: 'dashboard' } | async }}</span>\n </div>\n </div>\n }\n\n <!-- Error message -->\n @if (hasError()) {\n <div class=\"axp-weather-error-overlay\">\n <div class=\"axp-weather-error-message\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ errorMessage() | translate: { scope: 'dashboard' } | async }}</span>\n <button class=\"axp-weather-retry-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>{{ 'weather.retry' | translate: { scope: 'dashboard' } | async }}</span>\n </button>\n </div>\n </div>\n }\n\n <!-- Weather content - only show when we have data -->\n @if (weatherData()) {\n <!-- Background decorations based on weather condition -->\n <div class=\"axp-weather-background-decorations\">\n <div class=\"axp-weather-decoration\" [ngClass]=\"weatherData()?.current?.condition?.toLowerCase()\"></div>\n <div class=\"axp-weather-gradient-overlay\"></div>\n </div>\n\n <div class=\"axp-weather-inner\">\n <!-- Location information section -->\n <div class=\"axp-weather-location-info\">\n <div class=\"axp-weather-location-icon\">\n <i class=\"fa-solid fa-location-dot\"></i>\n </div>\n <div class=\"axp-weather-location-text\">\n <h2 class=\"axp-weather-location-name\">{{ city() }}</h2>\n </div>\n </div>\n\n <!-- Current weather conditions section -->\n <div class=\"axp-weather-current-weather\">\n <!-- Weather icon and condition name -->\n @if (showCurrentCondition()) {\n <div class=\"axp-weather-condition\">\n <div class=\"axp-weather-icon-wrapper\">\n <div class=\"axp-weather-icon\">\n <i\n [class]=\"getConditionIcon(weatherData()?.current?.condition || '')\"\n [style.color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></i>\n </div>\n <div\n class=\"axp-weather-icon-glow\"\n [style.background-color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></div>\n </div>\n <div class=\"axp-weather-condition-name\">\n {{ getCurrentCondition() | translate: { scope: 'dashboard' } | async }}\n </div>\n </div>\n }\n\n <!-- Temperature display -->\n @if (showTemperature()) {\n <div class=\"axp-weather-temperature\">\n <span class=\"axp-weather-temperature-value\">{{ getCurrentTemperature() }}</span>\n <span class=\"axp-weather-temperature-unit\">{{\n getTemperatureUnit() | translate: { scope: 'dashboard' } | async\n }}</span>\n </div>\n }\n </div>\n\n <!-- Weather details section (humidity and wind) -->\n @if (showHumidity() || showWind()) {\n <div class=\"axp-weather-details\">\n <!-- Humidity information -->\n @if (showHumidity()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-droplet\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">\n {{ 'weather.humidity' | translate: { scope: 'dashboard' } | async }}\n </div>\n <div class=\"axp-weather-detail-value\">{{ getHumidity() }}%</div>\n </div>\n </div>\n }\n\n <!-- Wind speed information -->\n @if (showWind()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-wind\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">\n {{ 'weather.wind' | translate: { scope: 'dashboard' } | async }}\n </div>\n <div class=\"axp-weather-detail-value\">\n {{ getWindSpeed() }} {{ getWindSpeedUnit() | translate: { scope: 'dashboard' } | async }}\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Weather forecast section -->\n @if (showForecast() && weatherData()?.forecast) {\n <div class=\"axp-weather-forecast\">\n <div class=\"axp-weather-forecast-header\">\n <h3 class=\"axp-weather-forecast-title\">\n <i class=\"fa-solid fa-calendar-days\"></i>\n <span class=\"ax-px-1\">{{ 'weather.forecast' | translate: { scope: 'dashboard' } | async }}</span>\n </h3>\n </div>\n <!-- Loading indicator for forecast -->\n <!-- @if (isForecastLoading()) {\n <div class=\"axp-weather-forecast-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>{{ 'weather.loading-forecast' | translate: { scope: 'dashboard' } | async }}</span>\n </div>\n } -->\n <!-- Scrollable forecast days display -->\n <div class=\"axp-weather-forecast-items\">\n @for (day of displayedForecast(); track day.day) {\n <div class=\"axp-weather-forecast-day\">\n <div class=\"axp-weather-forecast-day-name\">\n {{ getDayName(parseDate(day.date)) | translate: { scope: 'dashboard' } | async }}\n </div>\n <div\n class=\"axp-weather-forecast-icon\"\n [title]=\"getConditionName(day.condition) | translate: { scope: 'dashboard' } | async\"\n >\n <i [class]=\"getConditionIcon(day.condition)\" [style.color]=\"getConditionColor(day.condition)\"></i>\n </div>\n <div class=\"axp-weather-forecast-temps\">\n <span class=\"axp-weather-forecast-low\">\n {{ temperatureUnit() === '\u00B0C' ? day.minTempC : day.minTempF\n }}{{ getTemperatureUnit() | translate: { scope: 'dashboard' } | async }}\n </span>\n <span class=\"axp-weather-forecast-high\">\n {{ temperatureUnit() === '\u00B0C' ? day.maxTempC : day.maxTempF\n }}{{ getTemperatureUnit() | translate: { scope: 'dashboard' } | async }}\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Last updated timestamp -->\n <div class=\"axp-weather-last-updated\">\n <span>{{ 'weather.last-updated' | translate: { scope: 'dashboard' } | async }}: {{ getLastUpdated() }}</span>\n </div>\n\n <!-- Manual refresh button -->\n <div class=\"axp-weather-refresh-action\">\n <button\n class=\"axp-weather-refresh-button\"\n (click)=\"refreshWeather()\"\n [attr.aria-label]=\"'weather.refresh' | translate: { scope: 'dashboard' } | async\"\n [title]=\"'weather.refresh' | translate: { scope: 'dashboard' } | async\"\n >\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>{{ 'weather.refresh' | translate: { scope: 'dashboard' } | async }}</span>\n </button>\n </div>\n </div>\n } @else if (!isLoading() && !hasError()) {\n <!-- No data state (not loading, no error) -->\n <div class=\"axp-weather-no-data-state\">\n <i class=\"fa-solid fa-cloud-sun\"></i>\n <p>{{ 'weather.no-data' | translate: { scope: 'dashboard' } | async }}</p>\n <button class=\"axp-weather-refresh-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>{{ 'weather.load-data' | translate: { scope: 'dashboard' } | async }}</span>\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;height:100%;--primary-gradient-start: #2196f3;--primary-gradient-end: #1976d2;--shadow-color: rgba(0, 0, 0, .2);--glass-bg: rgba(255, 255, 255, .15);--glass-border: rgba(255, 255, 255, .2);--text-primary: rgba(255, 255, 255, .95);--text-secondary: rgba(255, 255, 255, .75);--transition-speed: .3s}.axp-weather-container{width:100%;height:100%;overflow:hidden;position:relative;box-shadow:0 4px 8px rgba(0,0,0,.1);color:#fff;min-height:300px;background-color:#2c3e50}.axp-weather-loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(44,62,80,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-loading-spinner{text-align:center}.axp-weather-loading-spinner i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-loading-spinner span{display:block;color:#fff;font-size:1rem}.axp-weather-error-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(189,54,47,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-error-message{text-align:center;padding:1rem}.axp-weather-error-message i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-error-message span{display:block;color:#fff;font-size:1.1rem;margin-bottom:1rem}.axp-weather-error-message .axp-weather-retry-button{color:#bd362f;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-error-message .axp-weather-retry-button:hover{transform:translateY(-1px)}.axp-weather-no-data-state{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;padding:2rem;text-align:center}.axp-weather-no-data-state i{font-size:3rem;margin-bottom:1rem;color:rgba(255,255,255,.8)}.axp-weather-no-data-state p{margin-bottom:1.5rem;font-size:1.1rem}.axp-weather-no-data-state .axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-no-data-state .axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-background-decorations{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.axp-weather-decoration{position:absolute;top:0;left:0;width:100%;height:100%;background-size:cover;background-position:center}.axp-weather-decoration.sunny{background:linear-gradient(135deg,#ff7e00,#f7d358)}.axp-weather-decoration.partlyCloudy{background:linear-gradient(135deg,#7ba2e7,#b4d2f7)}.axp-weather-decoration.cloudy{background:linear-gradient(135deg,#717e8c,#919eab)}.axp-weather-decoration.rain{background:linear-gradient(135deg,#6a8caf,#567a9e)}.axp-weather-decoration.snow{background:linear-gradient(135deg,#99b3cc,#c6d4e1)}.axp-weather-decoration.thunder{background:linear-gradient(135deg,#425777,#2c3e50)}.axp-weather-decoration.mist{background:linear-gradient(135deg,#94a3b8,#cbd5e1)}.axp-weather-gradient-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.5))}.axp-weather-inner{position:relative;z-index:2;height:100%;padding:1.5rem;display:flex;flex-direction:column;justify-content:space-between}.axp-weather-location-info{display:flex;align-items:center;margin-bottom:1.5rem}.axp-weather-location-icon{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background-color:rgba(255,255,255,.2);border-radius:50%;margin-right:.75rem}.axp-weather-location-icon i{color:#fff}.axp-weather-location-name{margin:0;font-size:1.5rem;font-weight:500;text-shadow:1px 1px 3px rgba(0,0,0,.2);text-transform:capitalize}.axp-weather-current-weather{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;flex-wrap:wrap}.axp-weather-condition{display:flex;flex-direction:column;align-items:center}.axp-weather-icon-wrapper{position:relative;margin-bottom:.5rem}.axp-weather-icon{position:relative;z-index:2}.axp-weather-icon i{font-size:2.75rem;filter:drop-shadow(0 0 8px rgba(0,0,0,.3))}.axp-weather-icon-glow{position:absolute;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);width:45px;height:45px;border-radius:50%;filter:blur(15px);opacity:.75}.axp-weather-condition-name{font-size:1.1rem;text-align:center;text-shadow:1px 1px 2px rgba(0,0,0,.2)}.axp-weather-temperature{display:flex;align-items:flex-start;text-shadow:1px 1px 3px rgba(0,0,0,.3)}.axp-weather-temperature-value{font-size:3.5rem;font-weight:500;line-height:1}.axp-weather-temperature-unit{font-size:1.5rem;margin-top:.25rem}.axp-weather-details{display:flex;flex-wrap:wrap;gap:1.5rem;margin-bottom:1rem;padding:1rem;background-color:rgba(0,0,0,.15);border-radius:8px}.axp-weather-detail-item{display:flex;align-items:center;flex:1;min-width:120px}.axp-weather-detail-icon{width:40px;height:40px;border-radius:50%;background-color:rgba(255,255,255,.2);display:flex;align-items:center;justify-content:center;margin-right:.75rem}.axp-weather-detail-icon i{font-size:1.25rem}.axp-weather-detail-info{display:flex;padding-inline:.25rem;flex-direction:column}.axp-weather-detail-label{font-size:.875rem;color:rgba(255,255,255,.8);margin-bottom:.25rem}.axp-weather-detail-value{font-size:1.125rem;font-weight:500}.axp-weather-forecast{margin-bottom:.5rem;background-color:rgba(0,0,0,.15);border-radius:8px;padding:1rem}.axp-weather-forecast-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.axp-weather-forecast-title{margin:0;font-size:1.125rem;font-weight:500;display:flex;align-items:center}.axp-weather-forecast-title i{margin-right:.5rem;opacity:.8}.axp-weather-scroll-indicator{color:rgba(255,255,255,.6)}.axp-weather-forecast-items{display:flex;overflow-x:auto;gap:.75rem;padding-bottom:.5rem}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.3);border-radius:4px}.axp-weather-forecast-items::-webkit-scrollbar-track{background-color:rgba(0,0,0,.1);border-radius:4px}.axp-weather-forecast-day{min-width:90px;display:flex;flex-direction:column;align-items:center;padding:.75rem .5rem;background-color:rgba(255,255,255,.1);border-radius:6px;transition:all .3s ease}.axp-weather-forecast-day:hover{background-color:rgba(255,255,255,.15);transform:translateY(-2px)}.axp-weather-forecast-day-name{font-size:.875rem;margin-bottom:.5rem;font-weight:500}.axp-weather-forecast-icon{font-size:1.5rem;margin-bottom:.5rem}.axp-weather-forecast-icon i{filter:drop-shadow(0 0 5px rgba(0,0,0,.2))}.axp-weather-forecast-temps{display:flex;flex-direction:row;gap:.75rem;align-items:center;font-size:.775rem}.axp-weather-last-updated{text-align:center;font-size:.75rem;opacity:.7;margin-bottom:.5rem}.axp-weather-refresh-action{text-align:center}.axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:.875rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-refresh-button i{font-size:.875rem}@media (max-width: 576px){.axp-weather-inner{padding:.8rem;gap:.4rem}.axp-weather-location-name{font-size:1.1rem;padding-inline:.25rem}.axp-weather-temperature{font-size:2.5rem}.axp-weather-temperature-unit{font-size:1.1rem}.axp-weather-weather-details{flex-direction:column;gap:.5rem}.axp-weather-forecast-items{flex-wrap:nowrap;overflow-x:auto;padding-bottom:.5rem;margin:0 -.4rem;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;scrollbar-width:thin;mask-image:linear-gradient(to right,#000 95%,rgba(0,0,0,0));-webkit-mask-image:linear-gradient(to right,rgb(0,0,0) 95%,rgba(0,0,0,0))}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.2);border-radius:4px}.axp-weather-forecast-day{min-width:60px;flex:0 0 auto;padding:.4rem .6rem}.axp-weather-forecast-day-name{font-size:.7rem}.axp-weather-forecast-icon{padding:.3rem;height:1.6rem}.axp-weather-forecast-temps{font-size:.7rem}.axp-weather-scroll-indicator{display:block}}:host-context(.theme-dark){--glass-bg: rgba(0, 0, 0, .3);--glass-border: rgba(255, 255, 255, .1)}\n"] }]
|
3245
3298
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
3246
3299
|
|
3247
3300
|
var weatherWidget_component = /*#__PURE__*/Object.freeze({
|
@@ -3264,7 +3317,7 @@ const AXPWeatherWidget = {
|
|
3264
3317
|
/* Location Settings */
|
3265
3318
|
{
|
3266
3319
|
name: 'city',
|
3267
|
-
title: '
|
3320
|
+
title: '@dashboard:widgets.weather.city',
|
3268
3321
|
group: AXP_DATA_PROPERTY_GROUP,
|
3269
3322
|
schema: {
|
3270
3323
|
defaultValue: 'New York',
|
@@ -3340,7 +3393,7 @@ const AXPWeatherWidget = {
|
|
3340
3393
|
// },
|
3341
3394
|
{
|
3342
3395
|
name: 'showHumidity',
|
3343
|
-
title: '
|
3396
|
+
title: '@dashboard:widgets.weather.show-humidity',
|
3344
3397
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
3345
3398
|
schema: {
|
3346
3399
|
defaultValue: true,
|
@@ -3355,7 +3408,7 @@ const AXPWeatherWidget = {
|
|
3355
3408
|
},
|
3356
3409
|
{
|
3357
3410
|
name: 'showWind',
|
3358
|
-
title: '
|
3411
|
+
title: '@dashboard:widgets.weather.show-wind',
|
3359
3412
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
3360
3413
|
schema: {
|
3361
3414
|
defaultValue: true,
|
@@ -3370,7 +3423,7 @@ const AXPWeatherWidget = {
|
|
3370
3423
|
},
|
3371
3424
|
{
|
3372
3425
|
name: 'showForecast',
|
3373
|
-
title: '
|
3426
|
+
title: '@dashboard:widgets.weather.show-forecast',
|
3374
3427
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
3375
3428
|
schema: {
|
3376
3429
|
defaultValue: true,
|
@@ -3385,7 +3438,7 @@ const AXPWeatherWidget = {
|
|
3385
3438
|
},
|
3386
3439
|
{
|
3387
3440
|
name: 'forecastDays',
|
3388
|
-
title: '
|
3441
|
+
title: '@dashboard:widgets.weather.forecast-days',
|
3389
3442
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
3390
3443
|
schema: {
|
3391
3444
|
defaultValue: 5,
|
@@ -3406,7 +3459,7 @@ const AXPWeatherWidget = {
|
|
3406
3459
|
/* Units Settings */
|
3407
3460
|
{
|
3408
3461
|
name: 'temperatureUnit',
|
3409
|
-
title: '
|
3462
|
+
title: '@dashboard:widgets.weather.temperature-unit',
|
3410
3463
|
group: AXP_DATA_PROPERTY_GROUP,
|
3411
3464
|
schema: {
|
3412
3465
|
defaultValue: '°C',
|
@@ -3424,7 +3477,7 @@ const AXPWeatherWidget = {
|
|
3424
3477
|
},
|
3425
3478
|
{
|
3426
3479
|
name: 'windSpeedUnit',
|
3427
|
-
title: '
|
3480
|
+
title: '@dashboard:widgets.weather.wind-speed-unit',
|
3428
3481
|
group: AXP_DATA_PROPERTY_GROUP,
|
3429
3482
|
schema: {
|
3430
3483
|
defaultValue: 'km/h',
|
@@ -3443,7 +3496,7 @@ const AXPWeatherWidget = {
|
|
3443
3496
|
/* Refresh Settings */
|
3444
3497
|
{
|
3445
3498
|
name: 'autoRefresh',
|
3446
|
-
title: '
|
3499
|
+
title: '@dashboard:widgets.weather.auto-refresh',
|
3447
3500
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
3448
3501
|
schema: {
|
3449
3502
|
defaultValue: true,
|
@@ -3458,7 +3511,7 @@ const AXPWeatherWidget = {
|
|
3458
3511
|
},
|
3459
3512
|
{
|
3460
3513
|
name: 'refreshInterval',
|
3461
|
-
title: '
|
3514
|
+
title: '@dashboard:widgets.weather.refresh-interval',
|
3462
3515
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
3463
3516
|
schema: {
|
3464
3517
|
defaultValue: 15,
|
@@ -3505,7 +3558,7 @@ class AXPDashboardShortcutWidgetViewComponent extends AXPLayoutWidgetComponent {
|
|
3505
3558
|
super.ngOnInit();
|
3506
3559
|
if (!this.color()) {
|
3507
3560
|
this.setOptions({
|
3508
|
-
color: AXPDataGenerator.color()
|
3561
|
+
color: AXPDataGenerator.color(),
|
3509
3562
|
});
|
3510
3563
|
}
|
3511
3564
|
}
|
@@ -3531,8 +3584,8 @@ class AXPDashboardShortcutWidgetViewComponent extends AXPLayoutWidgetComponent {
|
|
3531
3584
|
title: result.title,
|
3532
3585
|
description: result.description,
|
3533
3586
|
icon: result.icon,
|
3534
|
-
command: result.command
|
3535
|
-
}
|
3587
|
+
command: result.command,
|
3588
|
+
},
|
3536
3589
|
});
|
3537
3590
|
}
|
3538
3591
|
}
|
@@ -3558,56 +3611,68 @@ class AXPDashboardShortcutWidgetViewComponent extends AXPLayoutWidgetComponent {
|
|
3558
3611
|
}
|
3559
3612
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPDashboardShortcutWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
3560
3613
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPDashboardShortcutWidgetViewComponent, isStandalone: true, selector: "ng-component", host: { properties: { "style": "this.__style", "class": "this.__class" } }, usesInheritance: true, ngImport: i0, template: `
|
3561
|
-
@if(item()) {
|
3562
|
-
<div
|
3614
|
+
@if (item()) {
|
3615
|
+
<div
|
3563
3616
|
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden "
|
3564
|
-
(click)="executeCommand()"
|
3617
|
+
(click)="executeCommand()"
|
3618
|
+
>
|
3565
3619
|
<div class="ax-absolute ax-inset-0 ax-bg-black/0 hover:ax-bg-black/10 ax-transition-opacity"></div>
|
3566
3620
|
<i [class]="item().icon + ' ax-text-3xl'"></i>
|
3567
3621
|
<span class="ax-text-xl ax-font-semibold">{{ item().title | translate | async }}</span>
|
3568
|
-
@if(item().description) {
|
3569
|
-
<span class="ax-text-sm ax-opacity-90 ax-text-center ax-px-2">{{
|
3622
|
+
@if (item().description) {
|
3623
|
+
<span class="ax-text-sm ax-opacity-90 ax-text-center ax-px-2">{{
|
3624
|
+
item().description! | translate | async
|
3625
|
+
}}</span>
|
3570
3626
|
}
|
3571
3627
|
</div>
|
3572
3628
|
} @else {
|
3573
|
-
<div
|
3574
|
-
(click)="setCommand()"
|
3575
|
-
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden"
|
3629
|
+
<div
|
3630
|
+
(click)="setCommand()"
|
3631
|
+
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden"
|
3632
|
+
>
|
3576
3633
|
<div class="ax-absolute ax-inset-0 ax-bg-black/0 hover:ax-bg-black/5 ax-transition-opacity"></div>
|
3577
3634
|
<i class="fa-light fa-plus ax-text-3xl"></i>
|
3578
|
-
<span class="ax-text-xl ax-font-semibold">
|
3635
|
+
<span class="ax-text-xl ax-font-semibold">{{
|
3636
|
+
'@dashboard:widgets.dashboard-shortcut.add-shortcut' | translate | async
|
3637
|
+
}}</span>
|
3579
3638
|
</div>
|
3580
3639
|
}
|
3581
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type:
|
3640
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i2$3.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
3582
3641
|
}
|
3583
3642
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPDashboardShortcutWidgetViewComponent, decorators: [{
|
3584
3643
|
type: Component,
|
3585
3644
|
args: [{
|
3586
3645
|
template: `
|
3587
|
-
@if(item()) {
|
3588
|
-
<div
|
3646
|
+
@if (item()) {
|
3647
|
+
<div
|
3589
3648
|
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden "
|
3590
|
-
(click)="executeCommand()"
|
3649
|
+
(click)="executeCommand()"
|
3650
|
+
>
|
3591
3651
|
<div class="ax-absolute ax-inset-0 ax-bg-black/0 hover:ax-bg-black/10 ax-transition-opacity"></div>
|
3592
3652
|
<i [class]="item().icon + ' ax-text-3xl'"></i>
|
3593
3653
|
<span class="ax-text-xl ax-font-semibold">{{ item().title | translate | async }}</span>
|
3594
|
-
@if(item().description) {
|
3595
|
-
<span class="ax-text-sm ax-opacity-90 ax-text-center ax-px-2">{{
|
3654
|
+
@if (item().description) {
|
3655
|
+
<span class="ax-text-sm ax-opacity-90 ax-text-center ax-px-2">{{
|
3656
|
+
item().description! | translate | async
|
3657
|
+
}}</span>
|
3596
3658
|
}
|
3597
3659
|
</div>
|
3598
3660
|
} @else {
|
3599
|
-
<div
|
3600
|
-
(click)="setCommand()"
|
3601
|
-
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden"
|
3661
|
+
<div
|
3662
|
+
(click)="setCommand()"
|
3663
|
+
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden"
|
3664
|
+
>
|
3602
3665
|
<div class="ax-absolute ax-inset-0 ax-bg-black/0 hover:ax-bg-black/5 ax-transition-opacity"></div>
|
3603
3666
|
<i class="fa-light fa-plus ax-text-3xl"></i>
|
3604
|
-
<span class="ax-text-xl ax-font-semibold">
|
3667
|
+
<span class="ax-text-xl ax-font-semibold">{{
|
3668
|
+
'@dashboard:widgets.dashboard-shortcut.add-shortcut' | translate | async
|
3669
|
+
}}</span>
|
3605
3670
|
</div>
|
3606
3671
|
}
|
3607
3672
|
`,
|
3608
3673
|
standalone: true,
|
3609
3674
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
3610
|
-
imports: [CommonModule, AXTranslationModule]
|
3675
|
+
imports: [CommonModule, AXTranslationModule],
|
3611
3676
|
}]
|
3612
3677
|
}], propDecorators: { __style: [{
|
3613
3678
|
type: HostBinding,
|
@@ -3623,15 +3688,18 @@ var dashboardShortcutWidgetView_component = /*#__PURE__*/Object.freeze({
|
|
3623
3688
|
});
|
3624
3689
|
|
3625
3690
|
const AXPDashboardShortcutWidget = {
|
3626
|
-
name:
|
3627
|
-
title:
|
3691
|
+
name: 'dashboard-shortcut',
|
3692
|
+
title: 'Shortcut',
|
3628
3693
|
description: 'Quick access to your key features.',
|
3629
3694
|
type: 'view',
|
3630
3695
|
categories: [AXP_WIDGETS_UTILITY_CATEGORY],
|
3631
3696
|
groups: [AXPWidgetGroupEnum.DashboardWidget],
|
3632
|
-
icon:
|
3697
|
+
icon: 'fa-light fa-link',
|
3633
3698
|
properties: [
|
3634
|
-
|
3699
|
+
{
|
3700
|
+
...AXP_COLOR_PROPERTY,
|
3701
|
+
title: '@dashboard:widgets.dashboard-shortcut.color',
|
3702
|
+
},
|
3635
3703
|
],
|
3636
3704
|
meta: {
|
3637
3705
|
dimensions: {
|
@@ -3647,7 +3715,7 @@ const AXPDashboardShortcutWidget = {
|
|
3647
3715
|
view: {
|
3648
3716
|
component: () => Promise.resolve().then(function () { return dashboardShortcutWidgetView_component; }).then((c) => c.AXPDashboardShortcutWidgetViewComponent),
|
3649
3717
|
},
|
3650
|
-
}
|
3718
|
+
},
|
3651
3719
|
};
|
3652
3720
|
|
3653
3721
|
class AXMMenuProvider {
|
@@ -3843,6 +3911,7 @@ class AXMDashboardWidgetWrapperComponent {
|
|
3843
3911
|
});
|
3844
3912
|
});
|
3845
3913
|
this.hasConfiguration = input(true);
|
3914
|
+
this.isLocked = input(false);
|
3846
3915
|
this.isDropdownOpen = signal(false);
|
3847
3916
|
}
|
3848
3917
|
#init;
|
@@ -3863,11 +3932,11 @@ class AXMDashboardWidgetWrapperComponent {
|
|
3863
3932
|
console.log('Dropdown event:', event);
|
3864
3933
|
}
|
3865
3934
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMDashboardWidgetWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
3866
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXMDashboardWidgetWrapperComponent, isStandalone: true, selector: "axm-dashboard-widget-wrapper", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, hasConfiguration: { classPropertyName: "hasConfiguration", publicName: "hasConfiguration", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDelete: "onDelete", onConfiguration: "onConfiguration", onValueChanged: "onValueChanged", onOptionsChanged: "onOptionsChanged" }, queries: [{ propertyName: "widget", first: true, predicate: AXPWidgetRendererDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<section class=\"ax-relative ax-size-full ax-flex ax-flex-col ax-group ax-overflow-hidden\">\n <!-- Action button - stays absolute -->\n <div\n class=\"ax-p-[0.6125rem] ax-absolute ax-top-0 ax-end-0 ax-z-[99] ax-invisible group-hover:ax-visible\"\n [class.!ax-visible]=\"isDropdownOpen()\"\n >\n <ax-button class=\"ax-sm\" [look]=\"'blank'\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-ellipsis-vertical\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel (onOpened)=\"isDropdownOpen.set(true)\" (onClosed)=\"isDropdownOpen.set(false)\">\n <ng-container *translate=\"let t\">\n <ax-button-item-list (onItemClick)=\"handleOnItemClick($event)\">\n @if(hasConfiguration()){\n <ax-button-item\n [data]=\"'configuration'\"\n [text]=\"(t('configuration', { scope: 'dashboard' }) | async) || 'configuration'\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-divider></ax-divider>\n }\n <ax-button-item
|
3935
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXMDashboardWidgetWrapperComponent, isStandalone: true, selector: "axm-dashboard-widget-wrapper", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, hasConfiguration: { classPropertyName: "hasConfiguration", publicName: "hasConfiguration", isSignal: true, isRequired: false, transformFunction: null }, isLocked: { classPropertyName: "isLocked", publicName: "isLocked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDelete: "onDelete", onConfiguration: "onConfiguration", onValueChanged: "onValueChanged", onOptionsChanged: "onOptionsChanged" }, queries: [{ propertyName: "widget", first: true, predicate: AXPWidgetRendererDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<section class=\"ax-relative ax-size-full ax-flex ax-flex-col ax-group ax-overflow-hidden\">\n <!-- Action button - stays absolute -->\n @if(!isLocked()) {\n <div\n class=\"ax-p-[0.6125rem] ax-absolute ax-top-0 ax-end-0 ax-z-[99] ax-invisible group-hover:ax-visible md:group-hover:ax-visible\"\n [class.!ax-visible]=\"isDropdownOpen()\"\n (touchstart)=\"isDropdownOpen.set(true)\"\n >\n <ax-button class=\"ax-sm ax-main-button\" [look]=\"'blank'\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-ellipsis-vertical\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel (onOpened)=\"isDropdownOpen.set(true)\" (onClosed)=\"isDropdownOpen.set(false)\">\n <ng-container *translate=\"let t\">\n <ax-button-item-list (onItemClick)=\"handleOnItemClick($event)\">\n @if(hasConfiguration()){\n <ax-button-item\n [data]=\"'configuration'\"\n [text]=\"(t('configuration', { scope: 'dashboard' }) | async) || 'configuration'\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-divider></ax-divider>\n }\n <ax-button-item [data]=\"'delete'\" [text]=\"(t('delete') | async) || 'delete'\" color=\"danger\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ng-container>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n }\n\n <!-- Title section -->\n @if(title()) {\n <div class=\"ax-ps-5 ax-pe-8 ax-py-3 ax-border-b\">\n <h3 class=\"ax-text-start ax-text-lg ax-font-medium ax-truncate\">{{title()}}</h3>\n </div>\n }\n\n <!-- Content section -->\n <div class=\"ax-overflow-auto ax-h-full\">\n <ng-content></ng-content>\n </div>\n</section>\n", styles: [":host{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1$2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i3$2.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i2$3.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
3867
3936
|
}
|
3868
3937
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMDashboardWidgetWrapperComponent, decorators: [{
|
3869
3938
|
type: Component,
|
3870
|
-
args: [{ selector: 'axm-dashboard-widget-wrapper', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXButtonModule, AXDecoratorModule, AXDropdownModule, AXTranslationModule, CommonModule], standalone: true, template: "<section class=\"ax-relative ax-size-full ax-flex ax-flex-col ax-group ax-overflow-hidden\">\n <!-- Action button - stays absolute -->\n <div\n class=\"ax-p-[0.6125rem] ax-absolute ax-top-0 ax-end-0 ax-z-[99] ax-invisible group-hover:ax-visible\"\n [class.!ax-visible]=\"isDropdownOpen()\"\n >\n <ax-button class=\"ax-sm\" [look]=\"'blank'\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-ellipsis-vertical\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel (onOpened)=\"isDropdownOpen.set(true)\" (onClosed)=\"isDropdownOpen.set(false)\">\n <ng-container *translate=\"let t\">\n <ax-button-item-list (onItemClick)=\"handleOnItemClick($event)\">\n @if(hasConfiguration()){\n <ax-button-item\n [data]=\"'configuration'\"\n [text]=\"(t('configuration', { scope: 'dashboard' }) | async) || 'configuration'\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-divider></ax-divider>\n }\n <ax-button-item
|
3939
|
+
args: [{ selector: 'axm-dashboard-widget-wrapper', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXButtonModule, AXDecoratorModule, AXDropdownModule, AXTranslationModule, CommonModule], standalone: true, template: "<section class=\"ax-relative ax-size-full ax-flex ax-flex-col ax-group ax-overflow-hidden\">\n <!-- Action button - stays absolute -->\n @if(!isLocked()) {\n <div\n class=\"ax-p-[0.6125rem] ax-absolute ax-top-0 ax-end-0 ax-z-[99] ax-invisible group-hover:ax-visible md:group-hover:ax-visible\"\n [class.!ax-visible]=\"isDropdownOpen()\"\n (touchstart)=\"isDropdownOpen.set(true)\"\n >\n <ax-button class=\"ax-sm ax-main-button\" [look]=\"'blank'\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-ellipsis-vertical\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel (onOpened)=\"isDropdownOpen.set(true)\" (onClosed)=\"isDropdownOpen.set(false)\">\n <ng-container *translate=\"let t\">\n <ax-button-item-list (onItemClick)=\"handleOnItemClick($event)\">\n @if(hasConfiguration()){\n <ax-button-item\n [data]=\"'configuration'\"\n [text]=\"(t('configuration', { scope: 'dashboard' }) | async) || 'configuration'\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-divider></ax-divider>\n }\n <ax-button-item [data]=\"'delete'\" [text]=\"(t('delete') | async) || 'delete'\" color=\"danger\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ng-container>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n }\n\n <!-- Title section -->\n @if(title()) {\n <div class=\"ax-ps-5 ax-pe-8 ax-py-3 ax-border-b\">\n <h3 class=\"ax-text-start ax-text-lg ax-font-medium ax-truncate\">{{title()}}</h3>\n </div>\n }\n\n <!-- Content section -->\n <div class=\"ax-overflow-auto ax-h-full\">\n <ng-content></ng-content>\n </div>\n</section>\n", styles: [":host{display:block;width:100%;height:100%}\n"] }]
|
3871
3940
|
}] });
|
3872
3941
|
|
3873
3942
|
const path = 'home:dashboard:';
|
@@ -3955,14 +4024,16 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3955
4024
|
</ax-select-box>
|
3956
4025
|
</div>
|
3957
4026
|
|
3958
|
-
<div class="ax-
|
3959
|
-
<
|
3960
|
-
|
3961
|
-
|
4027
|
+
<div class="ax-grid grid-cols-2 ax-grid-flow-col ax-gap-8 ax-mt-4">
|
4028
|
+
<div class="ax-flex ax-flex-row ax-items-center ax-gap-2">
|
4029
|
+
<p class="ax-font-semibold">{{ 'disable' | translate: { scope } | async }}</p>
|
4030
|
+
<ax-switch [(ngModel)]="isDisabled" name="isDisabled"></ax-switch>
|
4031
|
+
</div>
|
3962
4032
|
|
3963
|
-
|
3964
|
-
|
3965
|
-
|
4033
|
+
<div class="ax-flex ax-flex-row ax-items-center ax-gap-2">
|
4034
|
+
<p class="ax-font-semibold">{{ 'lock' | translate: { scope } | async }}</p>
|
4035
|
+
<ax-switch [(ngModel)]="isLocked" name="isLocked"></ax-switch>
|
4036
|
+
</div>
|
3966
4037
|
</div>
|
3967
4038
|
}
|
3968
4039
|
</div>
|
@@ -3982,7 +4053,7 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3982
4053
|
</ax-button>
|
3983
4054
|
</ax-suffix>
|
3984
4055
|
</ax-footer>
|
3985
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i3$3.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "mask-options", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type:
|
4056
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i3$3.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "mask-options", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i2$3.AXTranslatorPipe, name: "translate" }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i7.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed"] }, { kind: "ngmodule", type: AXSwitchModule }, { kind: "component", type: i8.AXSwitchComponent, selector: "ax-switch", inputs: ["disabled", "readonly", "color", "tabIndex", "value", "name", "isLoading"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged", "readonlyChange", "disabledChange"] }] }); }
|
3986
4057
|
}
|
3987
4058
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMAddDashboardPopup, decorators: [{
|
3988
4059
|
type: Component,
|
@@ -4014,14 +4085,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
4014
4085
|
</ax-select-box>
|
4015
4086
|
</div>
|
4016
4087
|
|
4017
|
-
<div class="ax-
|
4018
|
-
<
|
4019
|
-
|
4020
|
-
|
4088
|
+
<div class="ax-grid grid-cols-2 ax-grid-flow-col ax-gap-8 ax-mt-4">
|
4089
|
+
<div class="ax-flex ax-flex-row ax-items-center ax-gap-2">
|
4090
|
+
<p class="ax-font-semibold">{{ 'disable' | translate: { scope } | async }}</p>
|
4091
|
+
<ax-switch [(ngModel)]="isDisabled" name="isDisabled"></ax-switch>
|
4092
|
+
</div>
|
4021
4093
|
|
4022
|
-
|
4023
|
-
|
4024
|
-
|
4094
|
+
<div class="ax-flex ax-flex-row ax-items-center ax-gap-2">
|
4095
|
+
<p class="ax-font-semibold">{{ 'lock' | translate: { scope } | async }}</p>
|
4096
|
+
<ax-switch [(ngModel)]="isLocked" name="isLocked"></ax-switch>
|
4097
|
+
</div>
|
4025
4098
|
</div>
|
4026
4099
|
}
|
4027
4100
|
</div>
|
@@ -4051,7 +4124,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
4051
4124
|
CommonModule,
|
4052
4125
|
AXTranslationModule,
|
4053
4126
|
AXSelectBoxModule,
|
4054
|
-
|
4127
|
+
AXSwitchModule,
|
4055
4128
|
],
|
4056
4129
|
standalone: true,
|
4057
4130
|
}]
|
@@ -4120,6 +4193,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
4120
4193
|
class AXMDashboardPopupService {
|
4121
4194
|
constructor() {
|
4122
4195
|
this.popupService = inject(AXPopupService);
|
4196
|
+
this.translateService = inject(AXTranslationService);
|
4123
4197
|
}
|
4124
4198
|
async generateDashboardLayout(data, isAdmin) {
|
4125
4199
|
// Add isAdmin to the data object
|
@@ -4129,7 +4203,7 @@ class AXMDashboardPopupService {
|
|
4129
4203
|
size: 'sm',
|
4130
4204
|
draggable: true,
|
4131
4205
|
hasBackdrop: true,
|
4132
|
-
title: '
|
4206
|
+
title: await this.translateService.translateAsync('dashboard-info', { scope: 'dashboard' }),
|
4133
4207
|
data: dashboardData,
|
4134
4208
|
});
|
4135
4209
|
if (!result.data) {
|
@@ -4178,7 +4252,7 @@ withState(() => {
|
|
4178
4252
|
currentDashboardId: null,
|
4179
4253
|
isAdmin: false,
|
4180
4254
|
dashboardsOption: {
|
4181
|
-
float:
|
4255
|
+
float: false,
|
4182
4256
|
cellHeight: 75,
|
4183
4257
|
gap: 5,
|
4184
4258
|
minRow: 9,
|
@@ -4194,7 +4268,7 @@ withState(() => {
|
|
4194
4268
|
return state;
|
4195
4269
|
}),
|
4196
4270
|
// Computed Properties
|
4197
|
-
withComputed((state, sessionService = inject(AXPSessionService)) => ({
|
4271
|
+
withComputed((state, sessionService = inject(AXPSessionService), layoutThemeService = inject(AXPLayoutThemeService)) => ({
|
4198
4272
|
currentDashboard: computed(() => {
|
4199
4273
|
return state.dashboards().find((dashboard) => dashboard.id === state.currentDashboardId()) || null;
|
4200
4274
|
}),
|
@@ -4211,11 +4285,20 @@ withComputed((state, sessionService = inject(AXPSessionService)) => ({
|
|
4211
4285
|
if (!currentDashboard) {
|
4212
4286
|
return baseOptions;
|
4213
4287
|
}
|
4214
|
-
//
|
4215
|
-
if (
|
4288
|
+
// Always disable drag and resize on mobile devices
|
4289
|
+
if (!layoutThemeService.isDesktopDevice()) {
|
4290
|
+
return {
|
4291
|
+
...baseOptions,
|
4292
|
+
disableDrag: true,
|
4293
|
+
disableResize: true,
|
4294
|
+
};
|
4295
|
+
}
|
4296
|
+
// If the base options already have explicit disableDrag and disableResize values,
|
4297
|
+
// preserve those values (these were likely set by toggleLockDashboard)
|
4298
|
+
if (baseOptions.disableDrag !== undefined && baseOptions.disableResize !== undefined) {
|
4216
4299
|
return baseOptions;
|
4217
4300
|
}
|
4218
|
-
// Check if dashboard is locked
|
4301
|
+
// Check if dashboard is locked - locked dashboards always have drag and resize disabled
|
4219
4302
|
if (currentDashboard.locked === true) {
|
4220
4303
|
return {
|
4221
4304
|
...baseOptions,
|
@@ -4223,6 +4306,10 @@ withComputed((state, sessionService = inject(AXPSessionService)) => ({
|
|
4223
4306
|
disableResize: true,
|
4224
4307
|
};
|
4225
4308
|
}
|
4309
|
+
// If admin, no restrictions unless it's locked (which is checked above)
|
4310
|
+
if (state.isAdmin()) {
|
4311
|
+
return baseOptions;
|
4312
|
+
}
|
4226
4313
|
// Get user role
|
4227
4314
|
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4228
4315
|
// Check if user has role in dashboard
|
@@ -4264,9 +4351,33 @@ withComputed((state, sessionService = inject(AXPSessionService)) => ({
|
|
4264
4351
|
return widget.node?.options?.['hasConfiguration'] ?? true;
|
4265
4352
|
};
|
4266
4353
|
}),
|
4354
|
+
isWidgetLocked: computed(() => {
|
4355
|
+
return (widget) => {
|
4356
|
+
const currentDashboard = state.dashboards().find((dashboard) => dashboard.id === state.currentDashboardId());
|
4357
|
+
if (!currentDashboard)
|
4358
|
+
return false;
|
4359
|
+
// If dashboard is locked, widget is locked
|
4360
|
+
if (currentDashboard.locked === true) {
|
4361
|
+
return true;
|
4362
|
+
}
|
4363
|
+
// If admin, widget is not locked
|
4364
|
+
if (state.isAdmin())
|
4365
|
+
return false;
|
4366
|
+
// Get user role
|
4367
|
+
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4368
|
+
// Check if user has role in dashboard
|
4369
|
+
const hasRoleIds = currentDashboard.roleIds && Array.isArray(currentDashboard.roleIds) && currentDashboard.roleIds.length > 0;
|
4370
|
+
const hasUserRole = userRole && hasRoleIds && currentDashboard.roleIds?.includes(userRole);
|
4371
|
+
// If user is not admin, has role in dashboard, and dashboard has scope 'T', widget is locked
|
4372
|
+
if (hasUserRole && currentDashboard.scope === 'T') {
|
4373
|
+
return true;
|
4374
|
+
}
|
4375
|
+
return false;
|
4376
|
+
};
|
4377
|
+
}),
|
4267
4378
|
})),
|
4268
4379
|
// Methods for State Management
|
4269
|
-
withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogService = inject(AXDialogService), translationService = inject(AXTranslationService), widgetPickerService = inject(AXPWidgetPickerService), dashboardService = inject(AXMDashboardService), settingService = inject(AXPSettingService), sessionService = inject(AXPSessionService)) => {
|
4380
|
+
withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogService = inject(AXDialogService), translationService = inject(AXTranslationService), widgetPickerService = inject(AXPWidgetPickerService), dashboardService = inject(AXMDashboardService), settingService = inject(AXPSettingService), sessionService = inject(AXPSessionService), layoutThemeService = inject(AXPLayoutThemeService)) => {
|
4270
4381
|
// Load dashboards from service - runs on init via effect
|
4271
4382
|
effect(() => {
|
4272
4383
|
loadDashboards();
|
@@ -4521,6 +4632,10 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4521
4632
|
},
|
4522
4633
|
// Handle grid layout changes
|
4523
4634
|
async onGridChange(event) {
|
4635
|
+
// Skip any changes on mobile devices
|
4636
|
+
if (!layoutThemeService.isDesktopDevice()) {
|
4637
|
+
return;
|
4638
|
+
}
|
4524
4639
|
if (!store.currentDashboard()) {
|
4525
4640
|
console.warn('No current dashboard for grid change');
|
4526
4641
|
return;
|
@@ -4666,37 +4781,11 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4666
4781
|
console.error('Error handling widget options change:', error);
|
4667
4782
|
}
|
4668
4783
|
},
|
4669
|
-
//
|
4670
|
-
|
4671
|
-
|
4672
|
-
patchState(store, { isLoading: true });
|
4673
|
-
// Get dashboards from service using query method
|
4674
|
-
const result = await dashboardService.query({ skip: 0, take: 100 });
|
4675
|
-
const dashboardModels = result.items || [];
|
4676
|
-
// Convert dashboard models to AXPDashboardLayout
|
4677
|
-
const dashboards = dashboardModels.map(modelToDashboardLayout);
|
4678
|
-
// Update allDashboards state
|
4679
|
-
patchState(store, {
|
4680
|
-
allDashboards: dashboards,
|
4681
|
-
isLoading: false,
|
4682
|
-
});
|
4683
|
-
// Re-apply filtering based on current isAdmin state
|
4684
|
-
// This will update the dashboards state with filtered results
|
4685
|
-
const userId = sessionService.user?.id;
|
4686
|
-
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4687
|
-
if (userId) {
|
4688
|
-
this.filterDashboardsByScope(store.isAdmin());
|
4689
|
-
}
|
4690
|
-
else {
|
4691
|
-
// If no user, just show all dashboards
|
4692
|
-
patchState(store, { dashboards });
|
4693
|
-
}
|
4694
|
-
}
|
4695
|
-
catch (error) {
|
4696
|
-
console.error('Error refreshing dashboards:', error);
|
4697
|
-
patchState(store, { isLoading: false });
|
4698
|
-
}
|
4784
|
+
// Handle setting admin state
|
4785
|
+
setIsAdmin(isAdmin) {
|
4786
|
+
patchState(store, { isAdmin });
|
4699
4787
|
},
|
4788
|
+
// Filter dashboards by scope
|
4700
4789
|
filterDashboardsByScope(isAdmin) {
|
4701
4790
|
// Get all dashboards from the stored allDashboards array
|
4702
4791
|
const allDashboards = store.allDashboards();
|
@@ -4737,10 +4826,6 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4737
4826
|
this.setCurrentDashboard(filteredDashboards[0].id);
|
4738
4827
|
}
|
4739
4828
|
},
|
4740
|
-
// Add method to set isAdmin state
|
4741
|
-
setIsAdmin(isAdmin) {
|
4742
|
-
patchState(store, { isAdmin });
|
4743
|
-
},
|
4744
4829
|
// Toggle lock state for the current dashboard
|
4745
4830
|
async toggleLockDashboard() {
|
4746
4831
|
const currentDashboard = store.currentDashboard();
|
@@ -4749,6 +4834,18 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4749
4834
|
return;
|
4750
4835
|
}
|
4751
4836
|
try {
|
4837
|
+
// Check permission to toggle lock
|
4838
|
+
const isAdmin = store.isAdmin();
|
4839
|
+
const userId = sessionService.user?.id;
|
4840
|
+
// Determine if user can toggle lock based on the rules:
|
4841
|
+
// 1. If isAdmin is false, user can only toggle their own user-level dashboards
|
4842
|
+
// 2. If isAdmin is true, user can only toggle tenant-level dashboards
|
4843
|
+
const canToggle = (!isAdmin && currentDashboard.scope === 'U' && currentDashboard.createdBy === userId) ||
|
4844
|
+
(isAdmin && currentDashboard.scope === 'T');
|
4845
|
+
if (!canToggle) {
|
4846
|
+
console.warn('User does not have permission to toggle lock for this dashboard');
|
4847
|
+
return;
|
4848
|
+
}
|
4752
4849
|
// Toggle the locked state
|
4753
4850
|
const newLockedState = !currentDashboard.locked;
|
4754
4851
|
// Create an updated dashboard with toggled lock state
|
@@ -4762,8 +4859,24 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4762
4859
|
const updatedDashboards = store
|
4763
4860
|
.dashboards()
|
4764
4861
|
.map((dashboard) => (dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard));
|
4765
|
-
|
4766
|
-
|
4862
|
+
// IMPORTANT: Get the base options BEFORE updating the dashboards state
|
4863
|
+
// This ensures we're getting the current options without the lock state applied yet
|
4864
|
+
const baseOptions = { ...store.dashboardsOption() };
|
4865
|
+
// First update the dashboards state
|
4866
|
+
patchState(store, {
|
4867
|
+
dashboards: updatedDashboards,
|
4868
|
+
});
|
4869
|
+
// Get a fresh reference to the updated options with drag/resize explicitly set
|
4870
|
+
// This ensures the grid layout container gets a new object reference and responds immediately
|
4871
|
+
const updatedOptions = {
|
4872
|
+
...baseOptions,
|
4873
|
+
disableDrag: newLockedState,
|
4874
|
+
disableResize: newLockedState,
|
4875
|
+
};
|
4876
|
+
// Now update the options state separately to force a refresh of the grid layout
|
4877
|
+
patchState(store, {
|
4878
|
+
dashboardsOption: updatedOptions,
|
4879
|
+
});
|
4767
4880
|
}
|
4768
4881
|
catch (error) {
|
4769
4882
|
console.error('Error toggling dashboard lock state:', error);
|
@@ -4780,59 +4893,44 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4780
4893
|
class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
4781
4894
|
constructor() {
|
4782
4895
|
super(...arguments);
|
4783
|
-
//#region ---------------- Services & Dependencies ----------------
|
4784
4896
|
this.rootConfig = RootConfig;
|
4785
|
-
this.
|
4897
|
+
this.activatedRoute = inject(ActivatedRoute);
|
4786
4898
|
this.dialogService = inject(AXDialogService);
|
4787
|
-
this.
|
4899
|
+
this.popupService = inject(AXPopupService);
|
4788
4900
|
this.router = inject(Router);
|
4789
|
-
this.
|
4790
|
-
this.
|
4791
|
-
this.sessionService = inject(AXPSessionService);
|
4792
|
-
// Track if dashboards have been loaded
|
4793
|
-
this.dashboardsLoaded = signal(false);
|
4794
|
-
//#endregion
|
4795
|
-
//#region ---------------- View Properties ----------------
|
4901
|
+
this.store = inject(AXMDashboardStore);
|
4902
|
+
this.themeService = inject(AXPLayoutThemeService);
|
4796
4903
|
this.isEdited = signal(false);
|
4797
4904
|
this.context = signal({});
|
4798
|
-
|
4799
|
-
//#region ---------------- Effects ----------------
|
4800
|
-
// Create an effect to watch for dashboards loading
|
4905
|
+
this.dashboardsLoaded = signal(false);
|
4801
4906
|
this.#dashboardsEffect = effect(() => {
|
4802
4907
|
const allDashboards = this.store.allDashboards();
|
4803
4908
|
if (allDashboards.length > 0 && !this.dashboardsLoaded()) {
|
4804
4909
|
this.dashboardsLoaded.set(true);
|
4805
|
-
// Apply dashboard filtering now that dashboards are loaded
|
4806
4910
|
this.applyDashboardFiltering();
|
4911
|
+
this.recompute();
|
4807
4912
|
}
|
4808
4913
|
});
|
4809
4914
|
this.#loadingEffect = effect(() => {
|
4810
|
-
const isLoading =
|
4811
|
-
this.
|
4915
|
+
const isLoading = this.store.isLoading();
|
4916
|
+
if (isLoading === false && this.dashboardsLoaded()) {
|
4917
|
+
this.recompute;
|
4918
|
+
setTimeout(() => this.recompute(), 0);
|
4919
|
+
}
|
4812
4920
|
});
|
4813
4921
|
}
|
4814
|
-
//#endregion
|
4815
|
-
//#region ---------------- Lifecycle Methods ----------------
|
4816
4922
|
async ngOnInit() {
|
4817
|
-
// Get the child route if it exists
|
4818
4923
|
const childRoute = this.activatedRoute.firstChild || this.activatedRoute;
|
4819
4924
|
childRoute.data.subscribe((data) => {
|
4820
4925
|
const isAdmin = data['isAdmin'] ?? false;
|
4821
|
-
// Set isAdmin state in the store
|
4822
4926
|
this.store.setIsAdmin(isAdmin);
|
4823
4927
|
});
|
4824
4928
|
}
|
4825
4929
|
applyDashboardFiltering() {
|
4826
|
-
// The store now gets user info directly from the session service
|
4827
4930
|
this.store.filterDashboardsByScope(this.store.isAdmin());
|
4828
4931
|
}
|
4829
|
-
//#endregion
|
4830
|
-
//#region ---------------- Effects ----------------
|
4831
|
-
// Create an effect to watch for dashboards loading
|
4832
4932
|
#dashboardsEffect;
|
4833
4933
|
#loadingEffect;
|
4834
|
-
//#endregion
|
4835
|
-
//#region ---------------- Event Handlers ----------------
|
4836
4934
|
toggleEdit() {
|
4837
4935
|
this.isEdited.update((value) => !value);
|
4838
4936
|
}
|
@@ -4847,7 +4945,6 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4847
4945
|
console.error('Error confirming widget deletion:', error);
|
4848
4946
|
}
|
4849
4947
|
}
|
4850
|
-
//#endregion
|
4851
4948
|
getPageTitle() {
|
4852
4949
|
return this.store.currentDashboard()?.title || 'Dashboard';
|
4853
4950
|
}
|
@@ -4885,6 +4982,7 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4885
4982
|
command: {
|
4886
4983
|
name: 'new-widget',
|
4887
4984
|
},
|
4985
|
+
disabled: this.store.dashboards().length < 1,
|
4888
4986
|
},
|
4889
4987
|
],
|
4890
4988
|
},
|
@@ -4894,7 +4992,7 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4894
4992
|
const scope = this.rootConfig.config.i18n;
|
4895
4993
|
const items = [
|
4896
4994
|
{
|
4897
|
-
title: await this.translateService.translateAsync('delete
|
4995
|
+
title: await this.translateService.translateAsync('delete'),
|
4898
4996
|
icon: 'fa-light fa-trash-can',
|
4899
4997
|
color: 'danger',
|
4900
4998
|
disabled: this.store.dashboards().length < 1,
|
@@ -4903,10 +5001,11 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4903
5001
|
},
|
4904
5002
|
},
|
4905
5003
|
];
|
4906
|
-
|
4907
|
-
if (!this.store.isAdmin()) {
|
5004
|
+
if (!this.store.isAdmin() && this.themeService.isDesktopDevice()) {
|
4908
5005
|
items.push({
|
4909
|
-
title: await this.translateService.translateAsync(this.store.isDashboardLocked() ? 'unlock
|
5006
|
+
title: await this.translateService.translateAsync(this.store.isDashboardLocked() ? 'unlock' : 'lock', {
|
5007
|
+
scope: 'dashboard',
|
5008
|
+
}),
|
4910
5009
|
icon: this.store.isDashboardLocked() ? 'fa-light fa-lock-open' : 'fa-light fa-lock',
|
4911
5010
|
color: 'accent3',
|
4912
5011
|
disabled: this.store.dashboards().length < 1,
|
@@ -4941,6 +5040,10 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4941
5040
|
case 'toggle-lock':
|
4942
5041
|
await this.store.toggleLockDashboard();
|
4943
5042
|
this.recompute();
|
5043
|
+
// Add a short delay to ensure the grid layout updates properly
|
5044
|
+
setTimeout(() => {
|
5045
|
+
this.recompute();
|
5046
|
+
}, 50);
|
4944
5047
|
break;
|
4945
5048
|
}
|
4946
5049
|
}
|
@@ -4953,7 +5056,7 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4953
5056
|
provide: AXPBasePage,
|
4954
5057
|
useExisting: AXMDashboardHomeComponent,
|
4955
5058
|
},
|
4956
|
-
], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n <!-- Content Section -->\n\n <axp-page-content class=\"ax-relative\">\n @if(store.isLoading()) {\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-w-full ax-absolute ax-z-10 ax-bg-white/80\"\n >\n <ax-loading></ax-loading>\n <p class=\"ax-mt-3 ax-text-gray-600\">{{ t('loading', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else {\n <axp-widgets-container [context]=\"context()\">\n <ax-grid-layout-container [options]=\"store.dashboardsOption()\" (onChange)=\"store.onGridChange($event)\">\n @
|
5059
|
+
], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n <!-- Content Section -->\n\n <axp-page-content class=\"ax-relative\">\n @if(store.isLoading()) {\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-w-full ax-absolute ax-z-10 ax-bg-white/80\"\n >\n <ax-loading></ax-loading>\n <p class=\"ax-mt-3 ax-text-gray-600\">{{ t('loading', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else {\n <axp-widgets-container [context]=\"context()\">\n <ax-grid-layout-container [options]=\"store.dashboardsOption()\" (onChange)=\"store.onGridChange($event)\">\n @if(!store.dashboards() || store.dashboards().length === 0) {\n <div class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-p-4\">\n <ax-icon icon=\"fa-light fa-shapes\" class=\"ax-text-4xl ax-mb-4\"></ax-icon>\n <h2 class=\"ax-text-xl ax-font-semibold ax-mb-2\">{{ t('no-dashboards', { scope: 'dashboard' }) | async }}</h2>\n <p class=\"ax-text-center ax-mb-6\">{{ t('add-first-dashboard', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else if (!store.currentDashboard()) {\n <div class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-p-4\">\n <ax-icon icon=\"fa-light fa-shapes\" class=\"ax-text-4xl ax-mb-4\"></ax-icon>\n <h2 class=\"ax-text-xl ax-font-semibold ax-mb-2\">\n {{ t('no-current-dashboard', { scope: 'dashboard' }) | async }}\n </h2>\n <p class=\"ax-text-center ax-mb-6\">{{ t('select-dashboard', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else if (!store.currentDashboard()?.widgets || store.currentDashboard()?.widgets.length === 0) {\n <div class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-p-4\">\n <ax-icon icon=\"fa-light fa-shapes\" class=\"ax-text-4xl ax-mb-4\"></ax-icon>\n <h2 class=\"ax-text-xl ax-font-semibold ax-mb-2\">{{ t('no-widgets', { scope: 'dashboard' }) | async }}</h2>\n <p class=\"ax-text-center ax-mb-6\">{{ t('add-first-widget', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else { @for(widget of store.currentDashboard()?.widgets; track widget.config.id) {\n <ax-grid-layout-widget [options]=\"widget.config\">\n <axm-dashboard-widget-wrapper\n [title]=\"widget.node?.options?.['title']\"\n [hasConfiguration]=\"store.canConfigureWidget()(widget)\"\n [isLocked]=\"store.isWidgetLocked()(widget)\"\n (onDelete)=\"confirmWidgetDelete(store.currentDashboard()?.id!, widget.config.id!)\"\n (onConfiguration)=\"store.handlePopupConfiguration(widget.node!)\"\n (onValueChanged)=\"store.handleValueChanged(widget?.node!,$event)\"\n (onOptionsChanged)=\"store.handleOptionsChanged(widget?.node!,$event)\"\n >\n @if(widget.node) {\n <ng-container axp-widget-renderer [node]=\"widget.node\" [mode]=\"'view'\"></ng-container>\n }\n </axm-dashboard-widget-wrapper>\n </ax-grid-layout-widget>\n } }\n </ax-grid-layout-container>\n </axp-widgets-container>\n }\n </axp-page-content>\n</axp-page-layout>\n", styles: ["axm-dashboard-home{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}axm-dashboard-home .placeholder-content{border-radius:.5rem!important;border-width:1px!important;border-style:dashed!important;--tw-border-opacity: 1 !important;border-color:rgba(var(--ax-sys-color-primary-500),var(--tw-border-opacity, 1))!important;background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.5)!important}axm-dashboard-home ax-grid-layout-widget .grid-stack-item-content{border-radius:.375rem!important;border-width:1px!important;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05) !important;--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important;--ax-comp-grid-layout-stack-item-content-bg-color: var(--ax-sys-color-lightest-surface) }\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "component", type: i2$4.AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "ngmodule", type: AXPLayoutBuilderModule }, { kind: "component", type: i3$1.AXPWidgetContainerComponent, selector: "axp-widgets-container", inputs: ["context", "functions"], outputs: ["onContextChanged"] }, { kind: "directive", type: i3$1.AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: ["parentNode", "index", "mode", "node"], outputs: ["onOptionsChanged", "onValueChanged"], exportAs: ["widgetRenderer"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXButtonGroupModule }, { kind: "ngmodule", type: AXGridLayoutBuilderModule }, { kind: "component", type: i4$1.AXGridLayoutContainerComponent, selector: "ax-grid-layout-container", inputs: ["options", "isEmpty"], outputs: ["onAdded", "onRemoved", "onWidgetChange", "onChange", "onRender", "isEmptyChange"] }, { kind: "component", type: i4$1.AXGridLayoutWidgetComponent, selector: "ax-grid-layout-widget", inputs: ["options"] }, { kind: "component", type: AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer, axp-page-header, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-container, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i2$3.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "component", type: AXMDashboardWidgetWrapperComponent, selector: "axm-dashboard-widget-wrapper", inputs: ["title", "hasConfiguration", "isLocked"], outputs: ["onDelete", "onConfiguration", "onValueChanged", "onOptionsChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
4957
5060
|
}
|
4958
5061
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMDashboardHomeComponent, decorators: [{
|
4959
5062
|
type: Component,
|
@@ -4979,7 +5082,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
4979
5082
|
provide: AXPBasePage,
|
4980
5083
|
useExisting: AXMDashboardHomeComponent,
|
4981
5084
|
},
|
4982
|
-
], template: "<axp-page-layout *translate=\"let t\">\n <!-- Content Section -->\n\n <axp-page-content class=\"ax-relative\">\n @if(store.isLoading()) {\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-w-full ax-absolute ax-z-10 ax-bg-white/80\"\n >\n <ax-loading></ax-loading>\n <p class=\"ax-mt-3 ax-text-gray-600\">{{ t('loading', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else {\n <axp-widgets-container [context]=\"context()\">\n <ax-grid-layout-container [options]=\"store.dashboardsOption()\" (onChange)=\"store.onGridChange($event)\">\n @
|
5085
|
+
], template: "<axp-page-layout *translate=\"let t\">\n <!-- Content Section -->\n\n <axp-page-content class=\"ax-relative\">\n @if(store.isLoading()) {\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-w-full ax-absolute ax-z-10 ax-bg-white/80\"\n >\n <ax-loading></ax-loading>\n <p class=\"ax-mt-3 ax-text-gray-600\">{{ t('loading', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else {\n <axp-widgets-container [context]=\"context()\">\n <ax-grid-layout-container [options]=\"store.dashboardsOption()\" (onChange)=\"store.onGridChange($event)\">\n @if(!store.dashboards() || store.dashboards().length === 0) {\n <div class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-p-4\">\n <ax-icon icon=\"fa-light fa-shapes\" class=\"ax-text-4xl ax-mb-4\"></ax-icon>\n <h2 class=\"ax-text-xl ax-font-semibold ax-mb-2\">{{ t('no-dashboards', { scope: 'dashboard' }) | async }}</h2>\n <p class=\"ax-text-center ax-mb-6\">{{ t('add-first-dashboard', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else if (!store.currentDashboard()) {\n <div class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-p-4\">\n <ax-icon icon=\"fa-light fa-shapes\" class=\"ax-text-4xl ax-mb-4\"></ax-icon>\n <h2 class=\"ax-text-xl ax-font-semibold ax-mb-2\">\n {{ t('no-current-dashboard', { scope: 'dashboard' }) | async }}\n </h2>\n <p class=\"ax-text-center ax-mb-6\">{{ t('select-dashboard', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else if (!store.currentDashboard()?.widgets || store.currentDashboard()?.widgets.length === 0) {\n <div class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-p-4\">\n <ax-icon icon=\"fa-light fa-shapes\" class=\"ax-text-4xl ax-mb-4\"></ax-icon>\n <h2 class=\"ax-text-xl ax-font-semibold ax-mb-2\">{{ t('no-widgets', { scope: 'dashboard' }) | async }}</h2>\n <p class=\"ax-text-center ax-mb-6\">{{ t('add-first-widget', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else { @for(widget of store.currentDashboard()?.widgets; track widget.config.id) {\n <ax-grid-layout-widget [options]=\"widget.config\">\n <axm-dashboard-widget-wrapper\n [title]=\"widget.node?.options?.['title']\"\n [hasConfiguration]=\"store.canConfigureWidget()(widget)\"\n [isLocked]=\"store.isWidgetLocked()(widget)\"\n (onDelete)=\"confirmWidgetDelete(store.currentDashboard()?.id!, widget.config.id!)\"\n (onConfiguration)=\"store.handlePopupConfiguration(widget.node!)\"\n (onValueChanged)=\"store.handleValueChanged(widget?.node!,$event)\"\n (onOptionsChanged)=\"store.handleOptionsChanged(widget?.node!,$event)\"\n >\n @if(widget.node) {\n <ng-container axp-widget-renderer [node]=\"widget.node\" [mode]=\"'view'\"></ng-container>\n }\n </axm-dashboard-widget-wrapper>\n </ax-grid-layout-widget>\n } }\n </ax-grid-layout-container>\n </axp-widgets-container>\n }\n </axp-page-content>\n</axp-page-layout>\n", styles: ["axm-dashboard-home{background-color:rgb(var(--ax-sys-color-lighter-surface));color:rgb(var(--ax-sys-color-on-lighter-surface));border-color:rgb(var(--ax-sys-color-border-lighter-surface))}axm-dashboard-home .placeholder-content{border-radius:.5rem!important;border-width:1px!important;border-style:dashed!important;--tw-border-opacity: 1 !important;border-color:rgba(var(--ax-sys-color-primary-500),var(--tw-border-opacity, 1))!important;background-color:rgba(var(--ax-sys-color-primary-lightest-surface),.5)!important}axm-dashboard-home ax-grid-layout-widget .grid-stack-item-content{border-radius:.375rem!important;border-width:1px!important;--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05) !important;--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important;--ax-comp-grid-layout-stack-item-content-bg-color: var(--ax-sys-color-lightest-surface) }\n"] }]
|
4983
5086
|
}] });
|
4984
5087
|
|
4985
5088
|
var homeDashboard = /*#__PURE__*/Object.freeze({
|