@acorex/modules 19.3.6 → 19.3.8
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 +36 -3
- package/dashboard-management/lib/features/home-dashboard/dashboard-home/home-dashboard.store.d.ts +40 -1
- package/dashboard-management/lib/features/home-dashboard/dashboard-popups/add-dashboard-popup.d.ts +7 -7
- package/dashboard-management/lib/features/shared/widgets/bar-chart/bar-chart-widget.component.d.ts +4 -3
- package/dashboard-management/lib/features/shared/widgets/donut-chart/donut-chart-widget.component.d.ts +4 -3
- package/dashboard-management/lib/features/shared/widgets/gauge-chart/gauge-chart-widget.component.d.ts +3 -2
- package/dashboard-management/lib/features/shared/widgets/line-chart/line-chart-widget.component.d.ts +1 -0
- package/fesm2022/acorex-modules-dashboard-management.mjs +1130 -1227
- package/fesm2022/acorex-modules-dashboard-management.mjs.map +1 -1
- package/package.json +9 -9
@@ -3,7 +3,7 @@ import { createAllQueryView, AXPEntityCommandScope, AXPEntityQueryType, AXP_HOME
|
|
3
3
|
import * as i3$1 from '@acorex/platform/layout/builder';
|
4
4
|
import { AXPWidgetsCatalog, AXPValueWidgetComponent, cloneProperty, AXPWidgetGroupEnum, AXPLayoutWidgetComponent, AXPLayoutBuilderModule, AXPWidgetRendererDirective } from '@acorex/platform/layout/builder';
|
5
5
|
import { AXMEntityCrudServiceImpl, AXPEntityService, AXP_ENTITY_CONFIG_TOKEN, AXP_ENTITY_DEFINITION_LOADER } from '@acorex/platform/layout/entity';
|
6
|
-
import { AXP_APPEARANCE_PROPERTY_GROUP,
|
6
|
+
import { AXP_APPEARANCE_PROPERTY_GROUP, AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_BEHAVIOR_PROPERTY_GROUP, AXP_BG_COLOR_PROPERTY, plainTextDefaultProperty, AXP_DATA_PROPERTY_GROUP, AXP_COLOR_PROPERTY, AXPWidgetsModule } from '@acorex/platform/widgets';
|
7
7
|
import * as i0 from '@angular/core';
|
8
8
|
import { Injectable, inject, Injector, computed, ChangeDetectionStrategy, Component, ChangeDetectorRef, signal, viewChild, ElementRef, HostListener, output, InjectionToken, effect, HostBinding, NgModule, input, contentChild, afterNextRender, model, ViewEncapsulation } from '@angular/core';
|
9
9
|
import { AXBarChartComponent } from '@acorex/charts/bar-chart';
|
@@ -454,20 +454,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
454
454
|
*/
|
455
455
|
class AXPBarChartWidgetViewComponent extends AXPValueWidgetComponent {
|
456
456
|
constructor() {
|
457
|
-
super(
|
457
|
+
super();
|
458
458
|
this.barChartData = computed(() => this.getValue());
|
459
459
|
this.barChartOptions = computed(() => this.options());
|
460
|
+
this.setOptions({
|
461
|
+
...this.options(),
|
462
|
+
showXAxis: true,
|
463
|
+
showYAxis: true,
|
464
|
+
barWidth: 80,
|
465
|
+
cornerRadius: 4,
|
466
|
+
showGrid: true,
|
467
|
+
showDataLabels: false,
|
468
|
+
showTooltip: true,
|
469
|
+
animationEasing: 'cubic-out',
|
470
|
+
animationDuration: 800,
|
471
|
+
});
|
460
472
|
}
|
461
473
|
handleBarClick(event) {
|
462
474
|
//console.log(event);
|
463
475
|
}
|
464
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPBarChartWidgetViewComponent, deps:
|
476
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPBarChartWidgetViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
465
477
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.10", type: AXPBarChartWidgetViewComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ax-bar-chart [data]=\"barChartData()\" [options]=\"barChartOptions()\" (barClick)=\"handleBarClick($event)\"></ax-bar-chart>\n", styles: [":host{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: AXBarChartComponent, selector: "ax-bar-chart", inputs: ["data", "options"], outputs: ["barClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
466
478
|
}
|
467
479
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPBarChartWidgetViewComponent, decorators: [{
|
468
480
|
type: Component,
|
469
481
|
args: [{ imports: [AXBarChartComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-bar-chart [data]=\"barChartData()\" [options]=\"barChartOptions()\" (barClick)=\"handleBarClick($event)\"></ax-bar-chart>\n", styles: [":host{display:block;width:100%;height:100%}\n"] }]
|
470
|
-
}] });
|
482
|
+
}], ctorParameters: () => [] });
|
471
483
|
|
472
484
|
var barChartWidget_component = /*#__PURE__*/Object.freeze({
|
473
485
|
__proto__: null,
|
@@ -514,61 +526,7 @@ const AXPBarChartWidget = {
|
|
514
526
|
},
|
515
527
|
visible: true,
|
516
528
|
},
|
517
|
-
// ====== Layout & Dimensions ======
|
518
|
-
{
|
519
|
-
name: 'width',
|
520
|
-
title: '@dashboard:widgets.bar-chart.width',
|
521
|
-
group: AXP_STYLING_PROPERTY_GROUP,
|
522
|
-
schema: {
|
523
|
-
defaultValue: null,
|
524
|
-
dataType: 'number',
|
525
|
-
interface: {
|
526
|
-
name: 'width',
|
527
|
-
path: 'options.width',
|
528
|
-
type: AXPWidgetsCatalog.number,
|
529
|
-
options: {
|
530
|
-
minValue: 0,
|
531
|
-
maxValue: 1200,
|
532
|
-
},
|
533
|
-
},
|
534
|
-
},
|
535
|
-
visible: true,
|
536
|
-
},
|
537
|
-
{
|
538
|
-
name: 'height',
|
539
|
-
title: '@dashboard:widgets.bar-chart.height',
|
540
|
-
group: AXP_STYLING_PROPERTY_GROUP,
|
541
|
-
schema: {
|
542
|
-
defaultValue: 300,
|
543
|
-
dataType: 'number',
|
544
|
-
interface: {
|
545
|
-
name: 'height',
|
546
|
-
path: 'options.height',
|
547
|
-
type: AXPWidgetsCatalog.number,
|
548
|
-
options: {
|
549
|
-
minValue: 0,
|
550
|
-
maxValue: 800,
|
551
|
-
},
|
552
|
-
},
|
553
|
-
},
|
554
|
-
visible: true,
|
555
|
-
},
|
556
529
|
// ====== X Axis Settings ======
|
557
|
-
{
|
558
|
-
name: 'showXAxis',
|
559
|
-
title: '@dashboard:widgets.bar-chart.show-x-axis',
|
560
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
561
|
-
schema: {
|
562
|
-
defaultValue: true,
|
563
|
-
dataType: 'boolean',
|
564
|
-
interface: {
|
565
|
-
name: 'showXAxis',
|
566
|
-
path: 'options.showXAxis',
|
567
|
-
type: AXPWidgetsCatalog.toggle,
|
568
|
-
},
|
569
|
-
},
|
570
|
-
visible: true,
|
571
|
-
},
|
572
530
|
{
|
573
531
|
name: 'xAxisLabel',
|
574
532
|
title: '@dashboard:widgets.bar-chart.x-axis-label',
|
@@ -585,21 +543,6 @@ const AXPBarChartWidget = {
|
|
585
543
|
visible: true,
|
586
544
|
},
|
587
545
|
// ====== Y Axis Settings ======
|
588
|
-
{
|
589
|
-
name: 'showYAxis',
|
590
|
-
title: '@dashboard:widgets.bar-chart.show-y-axis',
|
591
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
592
|
-
schema: {
|
593
|
-
defaultValue: true,
|
594
|
-
dataType: 'boolean',
|
595
|
-
interface: {
|
596
|
-
name: 'showYAxis',
|
597
|
-
path: 'options.showYAxis',
|
598
|
-
type: AXPWidgetsCatalog.toggle,
|
599
|
-
},
|
600
|
-
},
|
601
|
-
visible: true,
|
602
|
-
},
|
603
546
|
{
|
604
547
|
name: 'yAxisLabel',
|
605
548
|
title: '@dashboard:widgets.bar-chart.y-axis-label',
|
@@ -615,145 +558,218 @@ const AXPBarChartWidget = {
|
|
615
558
|
},
|
616
559
|
visible: true,
|
617
560
|
},
|
561
|
+
/* Commented out properties
|
562
|
+
// ====== Layout & Dimensions ======
|
563
|
+
{
|
564
|
+
name: 'width',
|
565
|
+
title: '@dashboard:widgets.bar-chart.width',
|
566
|
+
group: AXP_STYLING_PROPERTY_GROUP,
|
567
|
+
schema: {
|
568
|
+
defaultValue: null,
|
569
|
+
dataType: 'number',
|
570
|
+
interface: {
|
571
|
+
name: 'width',
|
572
|
+
path: 'options.width',
|
573
|
+
type: AXPWidgetsCatalog.number,
|
574
|
+
options: {
|
575
|
+
minValue: 0,
|
576
|
+
maxValue: 1200,
|
577
|
+
},
|
578
|
+
},
|
579
|
+
},
|
580
|
+
visible: true,
|
581
|
+
},
|
582
|
+
{
|
583
|
+
name: 'height',
|
584
|
+
title: '@dashboard:widgets.bar-chart.height',
|
585
|
+
group: AXP_STYLING_PROPERTY_GROUP,
|
586
|
+
schema: {
|
587
|
+
defaultValue: 300,
|
588
|
+
dataType: 'number',
|
589
|
+
interface: {
|
590
|
+
name: 'height',
|
591
|
+
path: 'options.height',
|
592
|
+
type: AXPWidgetsCatalog.number,
|
593
|
+
options: {
|
594
|
+
minValue: 0,
|
595
|
+
maxValue: 800,
|
596
|
+
},
|
597
|
+
},
|
598
|
+
},
|
599
|
+
visible: true,
|
600
|
+
},
|
601
|
+
// ====== X Axis Settings ======
|
602
|
+
{
|
603
|
+
name: 'showXAxis',
|
604
|
+
title: '@dashboard:widgets.bar-chart.show-x-axis',
|
605
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
606
|
+
schema: {
|
607
|
+
defaultValue: true,
|
608
|
+
dataType: 'boolean',
|
609
|
+
interface: {
|
610
|
+
name: 'showXAxis',
|
611
|
+
path: 'options.showXAxis',
|
612
|
+
type: AXPWidgetsCatalog.toggle,
|
613
|
+
},
|
614
|
+
},
|
615
|
+
visible: true,
|
616
|
+
},
|
617
|
+
// ====== Y Axis Settings ======
|
618
|
+
{
|
619
|
+
name: 'showYAxis',
|
620
|
+
title: '@dashboard:widgets.bar-chart.show-y-axis',
|
621
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
622
|
+
schema: {
|
623
|
+
defaultValue: true,
|
624
|
+
dataType: 'boolean',
|
625
|
+
interface: {
|
626
|
+
name: 'showYAxis',
|
627
|
+
path: 'options.showYAxis',
|
628
|
+
type: AXPWidgetsCatalog.toggle,
|
629
|
+
},
|
630
|
+
},
|
631
|
+
visible: true,
|
632
|
+
},
|
618
633
|
// ====== Bar Appearance ======
|
619
634
|
{
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
},
|
635
|
+
name: 'barWidth',
|
636
|
+
title: '@dashboard:widgets.bar-chart.bar-width',
|
637
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
638
|
+
schema: {
|
639
|
+
defaultValue: 80,
|
640
|
+
dataType: 'number',
|
641
|
+
interface: {
|
642
|
+
name: 'barWidth',
|
643
|
+
path: 'options.barWidth',
|
644
|
+
type: AXPWidgetsCatalog.number,
|
645
|
+
options: {
|
646
|
+
placeholder: '1-100',
|
647
|
+
minValue: 1,
|
648
|
+
maxValue: 100,
|
649
|
+
},
|
636
650
|
},
|
637
|
-
|
651
|
+
},
|
652
|
+
visible: true,
|
638
653
|
},
|
639
654
|
{
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
},
|
655
|
+
name: 'cornerRadius',
|
656
|
+
title: '@dashboard:widgets.bar-chart.corner-radius',
|
657
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
658
|
+
schema: {
|
659
|
+
defaultValue: 4,
|
660
|
+
dataType: 'number',
|
661
|
+
interface: {
|
662
|
+
name: 'cornerRadius',
|
663
|
+
path: 'options.cornerRadius',
|
664
|
+
type: AXPWidgetsCatalog.number,
|
665
|
+
options: {
|
666
|
+
placeholder: '0-20',
|
667
|
+
minValue: 0,
|
668
|
+
maxValue: 20,
|
669
|
+
},
|
656
670
|
},
|
657
|
-
|
671
|
+
},
|
672
|
+
visible: true,
|
658
673
|
},
|
659
674
|
// ====== Grid Settings ======
|
660
675
|
{
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
},
|
676
|
+
name: 'showGrid',
|
677
|
+
title: '@dashboard:widgets.bar-chart.show-grid',
|
678
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
679
|
+
schema: {
|
680
|
+
defaultValue: true,
|
681
|
+
dataType: 'boolean',
|
682
|
+
interface: {
|
683
|
+
name: 'showGrid',
|
684
|
+
path: 'options.showGrid',
|
685
|
+
type: AXPWidgetsCatalog.toggle,
|
672
686
|
},
|
673
|
-
|
687
|
+
},
|
688
|
+
visible: true,
|
674
689
|
},
|
675
690
|
{
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
},
|
691
|
+
name: 'showDataLabels',
|
692
|
+
title: '@dashboard:widgets.bar-chart.show-data-labels',
|
693
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
694
|
+
schema: {
|
695
|
+
defaultValue: true,
|
696
|
+
dataType: 'boolean',
|
697
|
+
interface: {
|
698
|
+
name: 'showDataLabels',
|
699
|
+
path: 'options.showDataLabels',
|
700
|
+
type: AXPWidgetsCatalog.toggle,
|
687
701
|
},
|
688
|
-
|
702
|
+
},
|
703
|
+
visible: true,
|
689
704
|
},
|
690
705
|
// ====== Tooltip Settings ======
|
691
706
|
{
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
},
|
707
|
+
name: 'showTooltip',
|
708
|
+
title: '@dashboard:widgets.bar-chart.show-tooltip',
|
709
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
710
|
+
schema: {
|
711
|
+
defaultValue: true,
|
712
|
+
dataType: 'boolean',
|
713
|
+
interface: {
|
714
|
+
name: 'showTooltip',
|
715
|
+
path: 'options.showTooltip',
|
716
|
+
type: AXPWidgetsCatalog.toggle,
|
703
717
|
},
|
704
|
-
|
718
|
+
},
|
719
|
+
visible: true,
|
705
720
|
},
|
706
721
|
// ====== Animation Settings ======
|
707
722
|
{
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
},
|
723
|
+
name: 'animationEasing',
|
724
|
+
title: '@dashboard:widgets.bar-chart.animation-easing',
|
725
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
726
|
+
schema: {
|
727
|
+
defaultValue: 'cubic-out',
|
728
|
+
dataType: 'string',
|
729
|
+
interface: {
|
730
|
+
name: 'animationEasing',
|
731
|
+
path: 'options.animationEasing',
|
732
|
+
type: AXPWidgetsCatalog.select,
|
733
|
+
options: {
|
734
|
+
dataSource: [
|
735
|
+
{ value: 'linear', text: 'Linear' },
|
736
|
+
{ value: 'ease', text: 'Ease' },
|
737
|
+
{ value: 'ease-in', text: 'Ease In' },
|
738
|
+
{ value: 'ease-out', text: 'Ease Out' },
|
739
|
+
{ value: 'ease-in-out', text: 'Ease In Out' },
|
740
|
+
{ value: 'cubic', text: 'Cubic' },
|
741
|
+
{ value: 'cubic-in', text: 'Cubic In' },
|
742
|
+
{ value: 'cubic-out', text: 'Cubic Out' },
|
743
|
+
{ value: 'cubic-in-out', text: 'Cubic In Out' },
|
744
|
+
],
|
745
|
+
textField: 'text',
|
746
|
+
valueField: 'value',
|
747
|
+
},
|
734
748
|
},
|
735
|
-
|
749
|
+
},
|
750
|
+
visible: true,
|
736
751
|
},
|
737
752
|
{
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
},
|
753
|
+
name: 'animationDuration',
|
754
|
+
title: '@dashboard:widgets.bar-chart.animation-duration',
|
755
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
756
|
+
schema: {
|
757
|
+
defaultValue: 800,
|
758
|
+
dataType: 'number',
|
759
|
+
interface: {
|
760
|
+
name: 'animationDuration',
|
761
|
+
path: 'options.animationDuration',
|
762
|
+
type: AXPWidgetsCatalog.number,
|
763
|
+
options: {
|
764
|
+
placeholder: '0-2000',
|
765
|
+
minValue: 0,
|
766
|
+
maxValue: 2000,
|
767
|
+
},
|
754
768
|
},
|
755
|
-
|
769
|
+
},
|
770
|
+
visible: true,
|
756
771
|
},
|
772
|
+
*/
|
757
773
|
],
|
758
774
|
components: {
|
759
775
|
view: {
|
@@ -1126,20 +1142,31 @@ const AXPClockCalendarWidget = {
|
|
1126
1142
|
*/
|
1127
1143
|
class AXPDonutChartWidgetViewComponent extends AXPValueWidgetComponent {
|
1128
1144
|
constructor() {
|
1129
|
-
super(
|
1145
|
+
super();
|
1130
1146
|
this.donutChartData = computed(() => this.getValue());
|
1131
1147
|
this.donutChartOptions = computed(() => this.options());
|
1148
|
+
this.setOptions({
|
1149
|
+
...this.options(),
|
1150
|
+
width: 300,
|
1151
|
+
height: 300,
|
1152
|
+
showDataLabels: false,
|
1153
|
+
donutWidth: 35,
|
1154
|
+
cornerRadius: 4,
|
1155
|
+
showTooltip: true,
|
1156
|
+
animationEasing: 'cubic-out',
|
1157
|
+
animationDuration: 800,
|
1158
|
+
});
|
1132
1159
|
}
|
1133
1160
|
handleDonutChartSegmentClick(event) {
|
1134
1161
|
//console.log(event);
|
1135
1162
|
}
|
1136
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPDonutChartWidgetViewComponent, deps:
|
1163
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPDonutChartWidgetViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
1137
1164
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.10", type: AXPDonutChartWidgetViewComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ax-donut-chart\n [data]=\"donutChartData()\"\n [options]=\"donutChartOptions()\"\n (segmentClick)=\"handleDonutChartSegmentClick($event)\"\n></ax-donut-chart>\n", styles: [":host{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: AXDonutChartComponent, selector: "ax-donut-chart", inputs: ["data", "options"], outputs: ["segmentClick", "segmentHover"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
1138
1165
|
}
|
1139
1166
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPDonutChartWidgetViewComponent, decorators: [{
|
1140
1167
|
type: Component,
|
1141
1168
|
args: [{ imports: [AXDonutChartComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-donut-chart\n [data]=\"donutChartData()\"\n [options]=\"donutChartOptions()\"\n (segmentClick)=\"handleDonutChartSegmentClick($event)\"\n></ax-donut-chart>\n", styles: [":host{display:block;width:100%;height:100%}\n"] }]
|
1142
|
-
}] });
|
1169
|
+
}], ctorParameters: () => [] });
|
1143
1170
|
|
1144
1171
|
var donutChartWidget_component = /*#__PURE__*/Object.freeze({
|
1145
1172
|
__proto__: null,
|
@@ -1175,100 +1202,101 @@ const AXPDonutChartWidget = {
|
|
1175
1202
|
},
|
1176
1203
|
visible: true,
|
1177
1204
|
},
|
1205
|
+
/* Commented out properties
|
1178
1206
|
// ====== Size & Layout ======
|
1179
1207
|
{
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
},
|
1208
|
+
name: 'width',
|
1209
|
+
title: '@dashboard:widgets.donut-chart.width',
|
1210
|
+
group: AXP_STYLING_PROPERTY_GROUP,
|
1211
|
+
schema: {
|
1212
|
+
defaultValue: 300,
|
1213
|
+
dataType: 'number',
|
1214
|
+
interface: {
|
1215
|
+
name: 'width',
|
1216
|
+
path: 'options.width',
|
1217
|
+
type: AXPWidgetsCatalog.number,
|
1218
|
+
options: {
|
1219
|
+
minValue: 200,
|
1220
|
+
maxValue: 1200,
|
1221
|
+
},
|
1195
1222
|
},
|
1196
|
-
|
1223
|
+
},
|
1224
|
+
visible: true,
|
1197
1225
|
},
|
1198
1226
|
{
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
},
|
1227
|
+
name: 'height',
|
1228
|
+
title: '@dashboard:widgets.donut-chart.height',
|
1229
|
+
group: AXP_STYLING_PROPERTY_GROUP,
|
1230
|
+
schema: {
|
1231
|
+
defaultValue: 300,
|
1232
|
+
dataType: 'number',
|
1233
|
+
interface: {
|
1234
|
+
name: 'height',
|
1235
|
+
path: 'options.height',
|
1236
|
+
type: AXPWidgetsCatalog.number,
|
1237
|
+
options: {
|
1238
|
+
minValue: 200,
|
1239
|
+
maxValue: 800,
|
1240
|
+
},
|
1214
1241
|
},
|
1215
|
-
|
1242
|
+
},
|
1243
|
+
visible: true,
|
1216
1244
|
},
|
1217
1245
|
// ====== Donut Appearance ======
|
1218
1246
|
{
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
},
|
1247
|
+
name: 'showDataLabels',
|
1248
|
+
title: '@dashboard:widgets.donut-chart.show-data-labels',
|
1249
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1250
|
+
schema: {
|
1251
|
+
defaultValue: true,
|
1252
|
+
dataType: 'boolean',
|
1253
|
+
interface: {
|
1254
|
+
name: 'showDataLabels',
|
1255
|
+
path: 'options.showDataLabels',
|
1256
|
+
type: AXPWidgetsCatalog.toggle,
|
1230
1257
|
},
|
1231
|
-
|
1258
|
+
},
|
1259
|
+
visible: true,
|
1232
1260
|
},
|
1233
1261
|
{
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
},
|
1262
|
+
name: 'donutWidth',
|
1263
|
+
title: '@dashboard:widgets.donut-chart.donut-width',
|
1264
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1265
|
+
schema: {
|
1266
|
+
defaultValue: 35,
|
1267
|
+
dataType: 'number',
|
1268
|
+
interface: {
|
1269
|
+
name: 'donutWidth',
|
1270
|
+
path: 'options.donutWidth',
|
1271
|
+
type: AXPWidgetsCatalog.number,
|
1272
|
+
options: {
|
1273
|
+
placeholder: '10-80',
|
1274
|
+
minValue: 10,
|
1275
|
+
maxValue: 80,
|
1276
|
+
},
|
1250
1277
|
},
|
1251
|
-
|
1278
|
+
},
|
1279
|
+
visible: true,
|
1252
1280
|
},
|
1253
1281
|
{
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
},
|
1282
|
+
name: 'cornerRadius',
|
1283
|
+
title: '@dashboard:widgets.donut-chart.corner-radius',
|
1284
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1285
|
+
schema: {
|
1286
|
+
defaultValue: 4,
|
1287
|
+
dataType: 'number',
|
1288
|
+
interface: {
|
1289
|
+
name: 'cornerRadius',
|
1290
|
+
path: 'options.cornerRadius',
|
1291
|
+
type: AXPWidgetsCatalog.number,
|
1292
|
+
options: {
|
1293
|
+
placeholder: '0-20',
|
1294
|
+
minValue: 0,
|
1295
|
+
maxValue: 20,
|
1296
|
+
},
|
1270
1297
|
},
|
1271
|
-
|
1298
|
+
},
|
1299
|
+
visible: true,
|
1272
1300
|
},
|
1273
1301
|
// ====== Legend ======
|
1274
1302
|
// {
|
@@ -1306,71 +1334,72 @@ const AXPDonutChartWidget = {
|
|
1306
1334
|
// },
|
1307
1335
|
// ====== Tooltip ======
|
1308
1336
|
{
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
},
|
1337
|
+
name: 'showTooltip',
|
1338
|
+
title: '@dashboard:widgets.donut-chart.show-tooltip',
|
1339
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1340
|
+
schema: {
|
1341
|
+
defaultValue: true,
|
1342
|
+
dataType: 'boolean',
|
1343
|
+
interface: {
|
1344
|
+
name: 'showTooltip',
|
1345
|
+
path: 'options.showTooltip',
|
1346
|
+
type: AXPWidgetsCatalog.toggle,
|
1320
1347
|
},
|
1321
|
-
|
1348
|
+
},
|
1349
|
+
visible: true,
|
1322
1350
|
},
|
1323
1351
|
// ====== Animation Settings ======
|
1324
1352
|
{
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
},
|
1353
|
+
name: 'animationEasing',
|
1354
|
+
title: '@dashboard:widgets.donut-chart.animation-easing',
|
1355
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1356
|
+
schema: {
|
1357
|
+
defaultValue: 'cubic-out',
|
1358
|
+
dataType: 'string',
|
1359
|
+
interface: {
|
1360
|
+
name: 'animationEasing',
|
1361
|
+
path: 'options.animationEasing',
|
1362
|
+
type: AXPWidgetsCatalog.select,
|
1363
|
+
options: {
|
1364
|
+
dataSource: [
|
1365
|
+
{ value: 'linear', text: 'Linear' },
|
1366
|
+
{ value: 'ease', text: 'Ease' },
|
1367
|
+
{ value: 'ease-in', text: 'Ease In' },
|
1368
|
+
{ value: 'ease-out', text: 'Ease Out' },
|
1369
|
+
{ value: 'ease-in-out', text: 'Ease In Out' },
|
1370
|
+
{ value: 'cubic', text: 'Cubic' },
|
1371
|
+
{ value: 'cubic-in', text: 'Cubic In' },
|
1372
|
+
{ value: 'cubic-out', text: 'Cubic Out' },
|
1373
|
+
{ value: 'cubic-in-out', text: 'Cubic In Out' },
|
1374
|
+
],
|
1375
|
+
textField: 'text',
|
1376
|
+
valueField: 'value',
|
1377
|
+
},
|
1351
1378
|
},
|
1352
|
-
|
1379
|
+
},
|
1380
|
+
visible: true,
|
1353
1381
|
},
|
1354
1382
|
{
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
},
|
1383
|
+
name: 'animationDuration',
|
1384
|
+
title: '@dashboard:widgets.donut-chart.animation-duration',
|
1385
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1386
|
+
schema: {
|
1387
|
+
defaultValue: 800,
|
1388
|
+
dataType: 'number',
|
1389
|
+
interface: {
|
1390
|
+
name: 'animationDuration',
|
1391
|
+
path: 'options.animationDuration',
|
1392
|
+
type: AXPWidgetsCatalog.number,
|
1393
|
+
options: {
|
1394
|
+
placeholder: '0-2000',
|
1395
|
+
minValue: 0,
|
1396
|
+
maxValue: 2000,
|
1397
|
+
},
|
1371
1398
|
},
|
1372
|
-
|
1399
|
+
},
|
1400
|
+
visible: true,
|
1373
1401
|
},
|
1402
|
+
*/
|
1374
1403
|
],
|
1375
1404
|
components: {
|
1376
1405
|
view: {
|
@@ -1395,17 +1424,29 @@ const AXPDonutChartWidget = {
|
|
1395
1424
|
*/
|
1396
1425
|
class AXPGaugeChartWidgetViewComponent extends AXPValueWidgetComponent {
|
1397
1426
|
constructor() {
|
1398
|
-
super(
|
1427
|
+
super();
|
1399
1428
|
this.gaugeChartValue = computed(() => this.getValue());
|
1400
1429
|
this.gaugeChartOptions = computed(() => this.options());
|
1430
|
+
this.setOptions({
|
1431
|
+
...this.options(),
|
1432
|
+
width: null,
|
1433
|
+
height: 300,
|
1434
|
+
minValue: 0,
|
1435
|
+
maxValue: 100,
|
1436
|
+
showTooltip: true,
|
1437
|
+
gaugeWidth: 30,
|
1438
|
+
cornerRadius: 4,
|
1439
|
+
animationEasing: 'cubic-out',
|
1440
|
+
animationDuration: 800,
|
1441
|
+
});
|
1401
1442
|
}
|
1402
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPGaugeChartWidgetViewComponent, deps:
|
1443
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPGaugeChartWidgetViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
1403
1444
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.10", type: AXPGaugeChartWidgetViewComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ax-gauge-chart [value]=\"gaugeChartValue()\" [options]=\"gaugeChartOptions()\"></ax-gauge-chart>\n", styles: [":host{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: AXGaugeChartComponent, selector: "ax-gauge-chart", inputs: ["value", "options"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
1404
1445
|
}
|
1405
1446
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPGaugeChartWidgetViewComponent, decorators: [{
|
1406
1447
|
type: Component,
|
1407
1448
|
args: [{ imports: [AXGaugeChartComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-gauge-chart [value]=\"gaugeChartValue()\" [options]=\"gaugeChartOptions()\"></ax-gauge-chart>\n", styles: [":host{display:block;width:100%;height:100%}\n"] }]
|
1408
|
-
}] });
|
1449
|
+
}], ctorParameters: () => [] });
|
1409
1450
|
|
1410
1451
|
var gaugeChartWidget_component = /*#__PURE__*/Object.freeze({
|
1411
1452
|
__proto__: null,
|
@@ -1440,201 +1481,203 @@ const AXPGaugeChartWidget = {
|
|
1440
1481
|
},
|
1441
1482
|
visible: true,
|
1442
1483
|
},
|
1443
|
-
// ======
|
1484
|
+
// ====== Label Display ======
|
1444
1485
|
{
|
1445
|
-
name: '
|
1446
|
-
title: '@dashboard:widgets.gauge-chart.
|
1447
|
-
group:
|
1486
|
+
name: 'label',
|
1487
|
+
title: '@dashboard:widgets.gauge-chart.label',
|
1488
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1448
1489
|
schema: {
|
1449
|
-
defaultValue:
|
1450
|
-
dataType: '
|
1490
|
+
defaultValue: '',
|
1491
|
+
dataType: 'string',
|
1451
1492
|
interface: {
|
1452
|
-
name: '
|
1453
|
-
path: 'options.
|
1454
|
-
type: AXPWidgetsCatalog.
|
1455
|
-
options: {
|
1456
|
-
placeholder: '1-1200',
|
1457
|
-
minValue: 1,
|
1458
|
-
maxValue: 1200,
|
1459
|
-
},
|
1493
|
+
name: 'label',
|
1494
|
+
path: 'options.label',
|
1495
|
+
type: AXPWidgetsCatalog.text,
|
1460
1496
|
},
|
1461
1497
|
},
|
1462
1498
|
visible: true,
|
1463
1499
|
},
|
1500
|
+
/* Commented out properties
|
1501
|
+
// ====== Layout & Dimensions ======
|
1464
1502
|
{
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
},
|
1503
|
+
name: 'width',
|
1504
|
+
title: '@dashboard:widgets.gauge-chart.width',
|
1505
|
+
group: AXP_STYLING_PROPERTY_GROUP,
|
1506
|
+
schema: {
|
1507
|
+
defaultValue: null,
|
1508
|
+
dataType: 'number',
|
1509
|
+
interface: {
|
1510
|
+
name: 'width',
|
1511
|
+
path: 'options.width',
|
1512
|
+
type: AXPWidgetsCatalog.number,
|
1513
|
+
options: {
|
1514
|
+
placeholder: '1-1200',
|
1515
|
+
minValue: 1,
|
1516
|
+
maxValue: 1200,
|
1517
|
+
},
|
1481
1518
|
},
|
1482
|
-
|
1519
|
+
},
|
1520
|
+
visible: true,
|
1483
1521
|
},
|
1484
|
-
// ====== Gauge Configuration ======
|
1485
1522
|
{
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1523
|
+
name: 'height',
|
1524
|
+
title: '@dashboard:widgets.gauge-chart.height',
|
1525
|
+
group: AXP_STYLING_PROPERTY_GROUP,
|
1526
|
+
schema: {
|
1527
|
+
defaultValue: 300,
|
1528
|
+
dataType: 'number',
|
1529
|
+
interface: {
|
1530
|
+
name: 'height',
|
1531
|
+
path: 'options.height',
|
1532
|
+
type: AXPWidgetsCatalog.number,
|
1533
|
+
options: {
|
1534
|
+
placeholder: '1-800',
|
1535
|
+
minValue: 1,
|
1536
|
+
maxValue: 800,
|
1537
|
+
},
|
1497
1538
|
},
|
1498
|
-
|
1539
|
+
},
|
1540
|
+
visible: true,
|
1499
1541
|
},
|
1542
|
+
// ====== Gauge Configuration ======
|
1500
1543
|
{
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
},
|
1544
|
+
name: 'minValue',
|
1545
|
+
title: '@dashboard:widgets.gauge-chart.min-value',
|
1546
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1547
|
+
schema: {
|
1548
|
+
defaultValue: 0,
|
1549
|
+
dataType: 'number',
|
1550
|
+
interface: {
|
1551
|
+
name: 'minValue',
|
1552
|
+
path: 'options.minValue',
|
1553
|
+
type: AXPWidgetsCatalog.number,
|
1512
1554
|
},
|
1513
|
-
|
1555
|
+
},
|
1556
|
+
visible: true,
|
1514
1557
|
},
|
1515
|
-
// ====== Gauge Appearance ======
|
1516
1558
|
{
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
},
|
1559
|
+
name: 'maxValue',
|
1560
|
+
title: '@dashboard:widgets.gauge-chart.max-value',
|
1561
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1562
|
+
schema: {
|
1563
|
+
defaultValue: 100,
|
1564
|
+
dataType: 'number',
|
1565
|
+
interface: {
|
1566
|
+
name: 'maxValue',
|
1567
|
+
path: 'options.maxValue',
|
1568
|
+
type: AXPWidgetsCatalog.number,
|
1528
1569
|
},
|
1529
|
-
|
1570
|
+
},
|
1571
|
+
visible: true,
|
1530
1572
|
},
|
1573
|
+
// ====== Gauge Appearance ======
|
1531
1574
|
{
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
options: {
|
1543
|
-
placeholder: '1-100',
|
1544
|
-
minValue: 1,
|
1545
|
-
maxValue: 100,
|
1546
|
-
},
|
1547
|
-
},
|
1575
|
+
name: 'showTooltip',
|
1576
|
+
title: '@dashboard:widgets.gauge-chart.show-tooltip',
|
1577
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1578
|
+
schema: {
|
1579
|
+
defaultValue: true,
|
1580
|
+
dataType: 'boolean',
|
1581
|
+
interface: {
|
1582
|
+
name: 'showTooltip',
|
1583
|
+
path: 'options.showTooltip',
|
1584
|
+
type: AXPWidgetsCatalog.toggle,
|
1548
1585
|
},
|
1549
|
-
|
1586
|
+
},
|
1587
|
+
visible: true,
|
1550
1588
|
},
|
1551
1589
|
{
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
},
|
1590
|
+
name: 'gaugeWidth',
|
1591
|
+
title: '@dashboard:widgets.gauge-chart.gauge-width',
|
1592
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1593
|
+
schema: {
|
1594
|
+
defaultValue: 30,
|
1595
|
+
dataType: 'number',
|
1596
|
+
interface: {
|
1597
|
+
name: 'gaugeWidth',
|
1598
|
+
path: 'options.gaugeWidth',
|
1599
|
+
type: AXPWidgetsCatalog.number,
|
1600
|
+
options: {
|
1601
|
+
placeholder: '1-100',
|
1602
|
+
minValue: 1,
|
1603
|
+
maxValue: 100,
|
1604
|
+
},
|
1568
1605
|
},
|
1569
|
-
|
1606
|
+
},
|
1607
|
+
visible: true,
|
1570
1608
|
},
|
1571
|
-
// ====== Label Display ======
|
1572
1609
|
{
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1610
|
+
name: 'cornerRadius',
|
1611
|
+
title: '@dashboard:widgets.gauge-chart.corner-radius',
|
1612
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1613
|
+
schema: {
|
1614
|
+
defaultValue: 4,
|
1615
|
+
dataType: 'number',
|
1616
|
+
interface: {
|
1617
|
+
name: 'cornerRadius',
|
1618
|
+
path: 'options.cornerRadius',
|
1619
|
+
type: AXPWidgetsCatalog.number,
|
1620
|
+
options: {
|
1621
|
+
placeholder: '1-20',
|
1622
|
+
minValue: 0,
|
1623
|
+
maxValue: 20,
|
1624
|
+
},
|
1584
1625
|
},
|
1585
|
-
|
1626
|
+
},
|
1627
|
+
visible: true,
|
1586
1628
|
},
|
1587
1629
|
// ====== Animation Settings ======
|
1588
1630
|
{
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1613
|
-
|
1614
|
-
},
|
1631
|
+
name: 'animationEasing',
|
1632
|
+
title: '@dashboard:widgets.gauge-chart.animation-easing',
|
1633
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1634
|
+
schema: {
|
1635
|
+
defaultValue: 'cubic-out',
|
1636
|
+
dataType: 'string',
|
1637
|
+
interface: {
|
1638
|
+
name: 'animationEasing',
|
1639
|
+
path: 'options.animationEasing',
|
1640
|
+
type: AXPWidgetsCatalog.select,
|
1641
|
+
options: {
|
1642
|
+
dataSource: [
|
1643
|
+
{ value: 'linear', text: 'Linear' },
|
1644
|
+
{ value: 'ease', text: 'Ease' },
|
1645
|
+
{ value: 'ease-in', text: 'Ease In' },
|
1646
|
+
{ value: 'ease-out', text: 'Ease Out' },
|
1647
|
+
{ value: 'ease-in-out', text: 'Ease In Out' },
|
1648
|
+
{ value: 'cubic', text: 'Cubic' },
|
1649
|
+
{ value: 'cubic-in', text: 'Cubic In' },
|
1650
|
+
{ value: 'cubic-out', text: 'Cubic Out' },
|
1651
|
+
{ value: 'cubic-in-out', text: 'Cubic In Out' },
|
1652
|
+
],
|
1653
|
+
textField: 'text',
|
1654
|
+
valueField: 'value',
|
1655
|
+
},
|
1615
1656
|
},
|
1616
|
-
|
1657
|
+
},
|
1658
|
+
visible: true,
|
1617
1659
|
},
|
1618
1660
|
{
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
},
|
1661
|
+
name: 'animationDuration',
|
1662
|
+
title: '@dashboard:widgets.gauge-chart.animation-duration',
|
1663
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1664
|
+
schema: {
|
1665
|
+
defaultValue: 800,
|
1666
|
+
dataType: 'number',
|
1667
|
+
interface: {
|
1668
|
+
name: 'animationDuration',
|
1669
|
+
path: 'options.animationDuration',
|
1670
|
+
type: AXPWidgetsCatalog.number,
|
1671
|
+
options: {
|
1672
|
+
placeholder: '0-2000',
|
1673
|
+
minValue: 0,
|
1674
|
+
maxValue: 2000,
|
1675
|
+
},
|
1635
1676
|
},
|
1636
|
-
|
1677
|
+
},
|
1678
|
+
visible: true,
|
1637
1679
|
},
|
1680
|
+
*/
|
1638
1681
|
],
|
1639
1682
|
components: {
|
1640
1683
|
view: {
|
@@ -1659,20 +1702,37 @@ const AXPGaugeChartWidget = {
|
|
1659
1702
|
*/
|
1660
1703
|
class AXPLineChartWidgetViewComponent extends AXPValueWidgetComponent {
|
1661
1704
|
constructor() {
|
1662
|
-
super(
|
1705
|
+
super();
|
1663
1706
|
this.lineChartData = computed(() => this.getValue());
|
1664
1707
|
this.lineChartOptions = computed(() => this.options());
|
1708
|
+
this.setOptions({
|
1709
|
+
...this.options(),
|
1710
|
+
showXAxis: true,
|
1711
|
+
showYAxis: true,
|
1712
|
+
yAxisStartsAtZero: true,
|
1713
|
+
showGrid: true,
|
1714
|
+
showVerticalGrid: true,
|
1715
|
+
lineWidth: 2,
|
1716
|
+
smoothLine: true,
|
1717
|
+
showPoints: true,
|
1718
|
+
pointRadius: 4,
|
1719
|
+
fillOpacity: 80,
|
1720
|
+
showTooltip: true,
|
1721
|
+
showCrosshair: true,
|
1722
|
+
animationEasing: 'cubic-out',
|
1723
|
+
animationDuration: 800,
|
1724
|
+
});
|
1665
1725
|
}
|
1666
1726
|
handleLineChartPointClick(event) {
|
1667
1727
|
//console.log(event);
|
1668
1728
|
}
|
1669
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPLineChartWidgetViewComponent, deps:
|
1729
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPLineChartWidgetViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
1670
1730
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.10", type: AXPLineChartWidgetViewComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<ax-line-chart\n (pointClick)=\"handleLineChartPointClick($event)\"\n [data]=\"lineChartData()\"\n [options]=\"lineChartOptions()\"\n></ax-line-chart>\n", styles: [":host{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: AXLineChartComponent, selector: "ax-line-chart", inputs: ["data", "options"], outputs: ["pointClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
1671
1731
|
}
|
1672
1732
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPLineChartWidgetViewComponent, decorators: [{
|
1673
1733
|
type: Component,
|
1674
1734
|
args: [{ standalone: true, imports: [AXLineChartComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ax-line-chart\n (pointClick)=\"handleLineChartPointClick($event)\"\n [data]=\"lineChartData()\"\n [options]=\"lineChartOptions()\"\n></ax-line-chart>\n", styles: [":host{display:block;width:100%;height:100%}\n"] }]
|
1675
|
-
}] });
|
1735
|
+
}], ctorParameters: () => [] });
|
1676
1736
|
|
1677
1737
|
var lineChartWidget_component = /*#__PURE__*/Object.freeze({
|
1678
1738
|
__proto__: null,
|
@@ -1708,218 +1768,33 @@ const AXPLineChartWidget = {
|
|
1708
1768
|
},
|
1709
1769
|
visible: true,
|
1710
1770
|
},
|
1711
|
-
// ====== Layout & Dimensions ======
|
1712
|
-
{
|
1713
|
-
name: 'width',
|
1714
|
-
title: '@dashboard:widgets.line-chart.width',
|
1715
|
-
group: AXP_STYLING_PROPERTY_GROUP,
|
1716
|
-
schema: {
|
1717
|
-
defaultValue: null,
|
1718
|
-
dataType: 'number',
|
1719
|
-
interface: {
|
1720
|
-
name: 'width',
|
1721
|
-
path: 'options.width',
|
1722
|
-
type: AXPWidgetsCatalog.number,
|
1723
|
-
options: {
|
1724
|
-
minValue: 0,
|
1725
|
-
maxValue: 1200,
|
1726
|
-
},
|
1727
|
-
},
|
1728
|
-
},
|
1729
|
-
visible: true,
|
1730
|
-
},
|
1731
|
-
{
|
1732
|
-
name: 'height',
|
1733
|
-
title: '@dashboard:widgets.line-chart.height',
|
1734
|
-
group: AXP_STYLING_PROPERTY_GROUP,
|
1735
|
-
schema: {
|
1736
|
-
defaultValue: 300,
|
1737
|
-
dataType: 'number',
|
1738
|
-
interface: {
|
1739
|
-
name: 'height',
|
1740
|
-
path: 'options.height',
|
1741
|
-
type: AXPWidgetsCatalog.number,
|
1742
|
-
options: {
|
1743
|
-
minValue: 0,
|
1744
|
-
maxValue: 800,
|
1745
|
-
},
|
1746
|
-
},
|
1747
|
-
},
|
1748
|
-
visible: true,
|
1749
|
-
},
|
1750
1771
|
// ====== Axis Settings ======
|
1751
|
-
{
|
1752
|
-
name: 'showXAxis',
|
1753
|
-
title: '@dashboard:widgets.line-chart.show-x-axis',
|
1754
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1755
|
-
schema: {
|
1756
|
-
defaultValue: true,
|
1757
|
-
dataType: 'boolean',
|
1758
|
-
interface: {
|
1759
|
-
name: 'showXAxis',
|
1760
|
-
path: 'options.showXAxis',
|
1761
|
-
type: AXPWidgetsCatalog.toggle,
|
1762
|
-
},
|
1763
|
-
},
|
1764
|
-
visible: true,
|
1765
|
-
},
|
1766
1772
|
{
|
1767
1773
|
name: 'xAxisLabel',
|
1768
1774
|
title: '@dashboard:widgets.line-chart.x-axis-label',
|
1769
1775
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1770
1776
|
schema: {
|
1771
|
-
defaultValue: '',
|
1772
|
-
dataType: 'string',
|
1773
|
-
interface: {
|
1774
|
-
name: 'xAxisLabel',
|
1775
|
-
path: 'options.xAxisLabel',
|
1776
|
-
type: AXPWidgetsCatalog.text,
|
1777
|
-
},
|
1778
|
-
},
|
1779
|
-
visible: true,
|
1780
|
-
},
|
1781
|
-
{
|
1782
|
-
name: 'showYAxis',
|
1783
|
-
title: '@dashboard:widgets.line-chart.show-y-axis',
|
1784
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1785
|
-
schema: {
|
1786
|
-
defaultValue: true,
|
1787
|
-
dataType: 'boolean',
|
1788
|
-
interface: {
|
1789
|
-
name: 'showYAxis',
|
1790
|
-
path: 'options.showYAxis',
|
1791
|
-
type: AXPWidgetsCatalog.toggle,
|
1792
|
-
},
|
1793
|
-
},
|
1794
|
-
visible: true,
|
1795
|
-
},
|
1796
|
-
{
|
1797
|
-
name: 'yAxisLabel',
|
1798
|
-
title: '@dashboard:widgets.line-chart.y-axis-label',
|
1799
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1800
|
-
schema: {
|
1801
|
-
defaultValue: '',
|
1802
|
-
dataType: 'string',
|
1803
|
-
interface: {
|
1804
|
-
name: 'yAxisLabel',
|
1805
|
-
path: 'options.yAxisLabel',
|
1806
|
-
type: AXPWidgetsCatalog.text,
|
1807
|
-
},
|
1808
|
-
},
|
1809
|
-
visible: true,
|
1810
|
-
},
|
1811
|
-
{
|
1812
|
-
name: 'yAxisStartsAtZero',
|
1813
|
-
title: '@dashboard:widgets.line-chart.y-axis-starts-at-zero',
|
1814
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1815
|
-
schema: {
|
1816
|
-
defaultValue: true,
|
1817
|
-
dataType: 'boolean',
|
1818
|
-
interface: {
|
1819
|
-
name: 'yAxisStartsAtZero',
|
1820
|
-
path: 'options.yAxisStartsAtZero',
|
1821
|
-
type: AXPWidgetsCatalog.toggle,
|
1822
|
-
},
|
1823
|
-
},
|
1824
|
-
visible: true,
|
1825
|
-
},
|
1826
|
-
{
|
1827
|
-
name: 'showGrid',
|
1828
|
-
title: '@dashboard:widgets.line-chart.show-grid',
|
1829
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1830
|
-
schema: {
|
1831
|
-
defaultValue: true,
|
1832
|
-
dataType: 'boolean',
|
1833
|
-
interface: {
|
1834
|
-
name: 'showGrid',
|
1835
|
-
path: 'options.showGrid',
|
1836
|
-
type: AXPWidgetsCatalog.toggle,
|
1837
|
-
},
|
1838
|
-
},
|
1839
|
-
visible: true,
|
1840
|
-
},
|
1841
|
-
{
|
1842
|
-
name: 'showVerticalGrid',
|
1843
|
-
title: '@dashboard:widgets.line-chart.show-vertical-grid',
|
1844
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1845
|
-
schema: {
|
1846
|
-
defaultValue: true,
|
1847
|
-
dataType: 'boolean',
|
1848
|
-
interface: {
|
1849
|
-
name: 'showVerticalGrid',
|
1850
|
-
path: 'options.showVerticalGrid',
|
1851
|
-
type: AXPWidgetsCatalog.toggle,
|
1852
|
-
},
|
1853
|
-
},
|
1854
|
-
visible: true,
|
1855
|
-
},
|
1856
|
-
// ====== Line Appearance ======
|
1857
|
-
{
|
1858
|
-
name: 'lineWidth',
|
1859
|
-
title: '@dashboard:widgets.line-chart.line-width',
|
1860
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1861
|
-
schema: {
|
1862
|
-
defaultValue: 2,
|
1863
|
-
dataType: 'number',
|
1864
|
-
interface: {
|
1865
|
-
name: 'lineWidth',
|
1866
|
-
path: 'options.lineWidth',
|
1867
|
-
type: AXPWidgetsCatalog.number,
|
1868
|
-
options: {
|
1869
|
-
placeholder: '1-10',
|
1870
|
-
minValue: 1,
|
1871
|
-
maxValue: 10,
|
1872
|
-
},
|
1873
|
-
},
|
1874
|
-
},
|
1875
|
-
visible: true,
|
1876
|
-
},
|
1877
|
-
{
|
1878
|
-
name: 'smoothLine',
|
1879
|
-
title: '@dashboard:widgets.line-chart.smooth-line',
|
1880
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1881
|
-
schema: {
|
1882
|
-
defaultValue: true,
|
1883
|
-
dataType: 'boolean',
|
1884
|
-
interface: {
|
1885
|
-
name: 'smoothLine',
|
1886
|
-
path: 'options.smoothLine',
|
1887
|
-
type: AXPWidgetsCatalog.toggle,
|
1888
|
-
},
|
1889
|
-
},
|
1890
|
-
visible: true,
|
1891
|
-
},
|
1892
|
-
{
|
1893
|
-
name: 'showPoints',
|
1894
|
-
title: '@dashboard:widgets.line-chart.show-points',
|
1895
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1896
|
-
schema: {
|
1897
|
-
defaultValue: true,
|
1898
|
-
dataType: 'boolean',
|
1777
|
+
defaultValue: '',
|
1778
|
+
dataType: 'string',
|
1899
1779
|
interface: {
|
1900
|
-
name: '
|
1901
|
-
path: 'options.
|
1902
|
-
type: AXPWidgetsCatalog.
|
1780
|
+
name: 'xAxisLabel',
|
1781
|
+
path: 'options.xAxisLabel',
|
1782
|
+
type: AXPWidgetsCatalog.text,
|
1903
1783
|
},
|
1904
1784
|
},
|
1905
1785
|
visible: true,
|
1906
1786
|
},
|
1907
1787
|
{
|
1908
|
-
name: '
|
1909
|
-
title: '@dashboard:widgets.line-chart.
|
1788
|
+
name: 'yAxisLabel',
|
1789
|
+
title: '@dashboard:widgets.line-chart.y-axis-label',
|
1910
1790
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1911
1791
|
schema: {
|
1912
|
-
defaultValue:
|
1913
|
-
dataType: '
|
1792
|
+
defaultValue: '',
|
1793
|
+
dataType: 'string',
|
1914
1794
|
interface: {
|
1915
|
-
name: '
|
1916
|
-
path: 'options.
|
1917
|
-
type: AXPWidgetsCatalog.
|
1918
|
-
options: {
|
1919
|
-
placeholder: '1-10',
|
1920
|
-
minValue: 1,
|
1921
|
-
maxValue: 10,
|
1922
|
-
},
|
1795
|
+
name: 'yAxisLabel',
|
1796
|
+
path: 'options.yAxisLabel',
|
1797
|
+
type: AXPWidgetsCatalog.text,
|
1923
1798
|
},
|
1924
1799
|
},
|
1925
1800
|
visible: true,
|
@@ -1939,109 +1814,301 @@ const AXPLineChartWidget = {
|
|
1939
1814
|
},
|
1940
1815
|
visible: true,
|
1941
1816
|
},
|
1817
|
+
/* Commented out properties
|
1818
|
+
// ====== Layout & Dimensions ======
|
1942
1819
|
{
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
step: 0.1,
|
1958
|
-
},
|
1959
|
-
},
|
1820
|
+
name: 'width',
|
1821
|
+
title: '@dashboard:widgets.line-chart.width',
|
1822
|
+
group: AXP_STYLING_PROPERTY_GROUP,
|
1823
|
+
schema: {
|
1824
|
+
defaultValue: null,
|
1825
|
+
dataType: 'number',
|
1826
|
+
interface: {
|
1827
|
+
name: 'width',
|
1828
|
+
path: 'options.width',
|
1829
|
+
type: AXPWidgetsCatalog.number,
|
1830
|
+
options: {
|
1831
|
+
minValue: 0,
|
1832
|
+
maxValue: 1200,
|
1833
|
+
},
|
1960
1834
|
},
|
1961
|
-
|
1835
|
+
},
|
1836
|
+
visible: true,
|
1837
|
+
},
|
1838
|
+
{
|
1839
|
+
name: 'height',
|
1840
|
+
title: '@dashboard:widgets.line-chart.height',
|
1841
|
+
group: AXP_STYLING_PROPERTY_GROUP,
|
1842
|
+
schema: {
|
1843
|
+
defaultValue: 300,
|
1844
|
+
dataType: 'number',
|
1845
|
+
interface: {
|
1846
|
+
name: 'height',
|
1847
|
+
path: 'options.height',
|
1848
|
+
type: AXPWidgetsCatalog.number,
|
1849
|
+
options: {
|
1850
|
+
minValue: 0,
|
1851
|
+
maxValue: 800,
|
1852
|
+
},
|
1853
|
+
},
|
1854
|
+
},
|
1855
|
+
visible: true,
|
1856
|
+
},
|
1857
|
+
|
1858
|
+
// ====== Axis Settings ======
|
1859
|
+
{
|
1860
|
+
name: 'showXAxis',
|
1861
|
+
title: '@dashboard:widgets.line-chart.show-x-axis',
|
1862
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1863
|
+
schema: {
|
1864
|
+
defaultValue: true,
|
1865
|
+
dataType: 'boolean',
|
1866
|
+
interface: {
|
1867
|
+
name: 'showXAxis',
|
1868
|
+
path: 'options.showXAxis',
|
1869
|
+
type: AXPWidgetsCatalog.toggle,
|
1870
|
+
},
|
1871
|
+
},
|
1872
|
+
visible: true,
|
1873
|
+
},
|
1874
|
+
{
|
1875
|
+
name: 'showYAxis',
|
1876
|
+
title: '@dashboard:widgets.line-chart.show-y-axis',
|
1877
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1878
|
+
schema: {
|
1879
|
+
defaultValue: true,
|
1880
|
+
dataType: 'boolean',
|
1881
|
+
interface: {
|
1882
|
+
name: 'showYAxis',
|
1883
|
+
path: 'options.showYAxis',
|
1884
|
+
type: AXPWidgetsCatalog.toggle,
|
1885
|
+
},
|
1886
|
+
},
|
1887
|
+
visible: true,
|
1888
|
+
},
|
1889
|
+
{
|
1890
|
+
name: 'yAxisStartsAtZero',
|
1891
|
+
title: '@dashboard:widgets.line-chart.y-axis-starts-at-zero',
|
1892
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1893
|
+
schema: {
|
1894
|
+
defaultValue: true,
|
1895
|
+
dataType: 'boolean',
|
1896
|
+
interface: {
|
1897
|
+
name: 'yAxisStartsAtZero',
|
1898
|
+
path: 'options.yAxisStartsAtZero',
|
1899
|
+
type: AXPWidgetsCatalog.toggle,
|
1900
|
+
},
|
1901
|
+
},
|
1902
|
+
visible: true,
|
1903
|
+
},
|
1904
|
+
|
1905
|
+
{
|
1906
|
+
name: 'showGrid',
|
1907
|
+
title: '@dashboard:widgets.line-chart.show-grid',
|
1908
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1909
|
+
schema: {
|
1910
|
+
defaultValue: true,
|
1911
|
+
dataType: 'boolean',
|
1912
|
+
interface: {
|
1913
|
+
name: 'showGrid',
|
1914
|
+
path: 'options.showGrid',
|
1915
|
+
type: AXPWidgetsCatalog.toggle,
|
1916
|
+
},
|
1917
|
+
},
|
1918
|
+
visible: true,
|
1919
|
+
},
|
1920
|
+
{
|
1921
|
+
name: 'showVerticalGrid',
|
1922
|
+
title: '@dashboard:widgets.line-chart.show-vertical-grid',
|
1923
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1924
|
+
schema: {
|
1925
|
+
defaultValue: true,
|
1926
|
+
dataType: 'boolean',
|
1927
|
+
interface: {
|
1928
|
+
name: 'showVerticalGrid',
|
1929
|
+
path: 'options.showVerticalGrid',
|
1930
|
+
type: AXPWidgetsCatalog.toggle,
|
1931
|
+
},
|
1932
|
+
},
|
1933
|
+
visible: true,
|
1934
|
+
},
|
1935
|
+
|
1936
|
+
// ====== Line Appearance ======
|
1937
|
+
{
|
1938
|
+
name: 'lineWidth',
|
1939
|
+
title: '@dashboard:widgets.line-chart.line-width',
|
1940
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1941
|
+
schema: {
|
1942
|
+
defaultValue: 2,
|
1943
|
+
dataType: 'number',
|
1944
|
+
interface: {
|
1945
|
+
name: 'lineWidth',
|
1946
|
+
path: 'options.lineWidth',
|
1947
|
+
type: AXPWidgetsCatalog.number,
|
1948
|
+
options: {
|
1949
|
+
placeholder: '1-10',
|
1950
|
+
minValue: 1,
|
1951
|
+
maxValue: 10,
|
1952
|
+
},
|
1953
|
+
},
|
1954
|
+
},
|
1955
|
+
visible: true,
|
1956
|
+
},
|
1957
|
+
{
|
1958
|
+
name: 'smoothLine',
|
1959
|
+
title: '@dashboard:widgets.line-chart.smooth-line',
|
1960
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1961
|
+
schema: {
|
1962
|
+
defaultValue: true,
|
1963
|
+
dataType: 'boolean',
|
1964
|
+
interface: {
|
1965
|
+
name: 'smoothLine',
|
1966
|
+
path: 'options.smoothLine',
|
1967
|
+
type: AXPWidgetsCatalog.toggle,
|
1968
|
+
},
|
1969
|
+
},
|
1970
|
+
visible: true,
|
1971
|
+
},
|
1972
|
+
{
|
1973
|
+
name: 'showPoints',
|
1974
|
+
title: '@dashboard:widgets.line-chart.show-points',
|
1975
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1976
|
+
schema: {
|
1977
|
+
defaultValue: true,
|
1978
|
+
dataType: 'boolean',
|
1979
|
+
interface: {
|
1980
|
+
name: 'showPoints',
|
1981
|
+
path: 'options.showPoints',
|
1982
|
+
type: AXPWidgetsCatalog.toggle,
|
1983
|
+
},
|
1984
|
+
},
|
1985
|
+
visible: true,
|
1986
|
+
},
|
1987
|
+
{
|
1988
|
+
name: 'pointRadius',
|
1989
|
+
title: '@dashboard:widgets.line-chart.point-radius',
|
1990
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1991
|
+
schema: {
|
1992
|
+
defaultValue: 4,
|
1993
|
+
dataType: 'number',
|
1994
|
+
interface: {
|
1995
|
+
name: 'pointRadius',
|
1996
|
+
path: 'options.pointRadius',
|
1997
|
+
type: AXPWidgetsCatalog.number,
|
1998
|
+
options: {
|
1999
|
+
placeholder: '1-10',
|
2000
|
+
minValue: 1,
|
2001
|
+
maxValue: 10,
|
2002
|
+
},
|
2003
|
+
},
|
2004
|
+
},
|
2005
|
+
visible: true,
|
2006
|
+
},
|
2007
|
+
{
|
2008
|
+
name: 'fillOpacity',
|
2009
|
+
title: '@dashboard:widgets.line-chart.fill-opacity',
|
2010
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2011
|
+
schema: {
|
2012
|
+
defaultValue: 80,
|
2013
|
+
dataType: 'number',
|
2014
|
+
interface: {
|
2015
|
+
name: 'fillOpacity',
|
2016
|
+
path: 'options.fillOpacity',
|
2017
|
+
type: AXPWidgetsCatalog.number,
|
2018
|
+
options: {
|
2019
|
+
placeholder: '1-100',
|
2020
|
+
minValue: 1,
|
2021
|
+
maxValue: 100,
|
2022
|
+
},
|
2023
|
+
},
|
2024
|
+
},
|
2025
|
+
visible: true,
|
1962
2026
|
},
|
2027
|
+
|
1963
2028
|
// ====== Tooltip Settings ======
|
1964
2029
|
{
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
|
1973
|
-
|
1974
|
-
|
1975
|
-
},
|
2030
|
+
name: 'showTooltip',
|
2031
|
+
title: '@dashboard:widgets.line-chart.show-tooltip',
|
2032
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2033
|
+
schema: {
|
2034
|
+
defaultValue: true,
|
2035
|
+
dataType: 'boolean',
|
2036
|
+
interface: {
|
2037
|
+
name: 'showTooltip',
|
2038
|
+
path: 'options.showTooltip',
|
2039
|
+
type: AXPWidgetsCatalog.toggle,
|
1976
2040
|
},
|
1977
|
-
|
2041
|
+
},
|
2042
|
+
visible: true,
|
1978
2043
|
},
|
1979
2044
|
{
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
},
|
2045
|
+
name: 'showCrosshair',
|
2046
|
+
title: '@dashboard:widgets.line-chart.show-crosshair',
|
2047
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2048
|
+
schema: {
|
2049
|
+
defaultValue: true,
|
2050
|
+
dataType: 'boolean',
|
2051
|
+
interface: {
|
2052
|
+
name: 'showCrosshair',
|
2053
|
+
path: 'options.showCrosshair',
|
2054
|
+
type: AXPWidgetsCatalog.toggle,
|
1991
2055
|
},
|
1992
|
-
|
2056
|
+
},
|
2057
|
+
visible: true,
|
1993
2058
|
},
|
2059
|
+
|
1994
2060
|
// ====== Animation Settings ======
|
1995
2061
|
{
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2021
|
-
},
|
2062
|
+
name: 'animationEasing',
|
2063
|
+
title: '@dashboard:widgets.line-chart.animation-easing',
|
2064
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2065
|
+
schema: {
|
2066
|
+
defaultValue: 'cubic-out',
|
2067
|
+
dataType: 'string',
|
2068
|
+
interface: {
|
2069
|
+
name: 'animationEasing',
|
2070
|
+
path: 'options.animationEasing',
|
2071
|
+
type: AXPWidgetsCatalog.select,
|
2072
|
+
options: {
|
2073
|
+
dataSource: [
|
2074
|
+
{ value: 'linear', text: 'Linear' },
|
2075
|
+
{ value: 'ease', text: 'Ease' },
|
2076
|
+
{ value: 'ease-in', text: 'Ease In' },
|
2077
|
+
{ value: 'ease-out', text: 'Ease Out' },
|
2078
|
+
{ value: 'ease-in-out', text: 'Ease In Out' },
|
2079
|
+
{ value: 'cubic', text: 'Cubic' },
|
2080
|
+
{ value: 'cubic-in', text: 'Cubic In' },
|
2081
|
+
{ value: 'cubic-out', text: 'Cubic Out' },
|
2082
|
+
{ value: 'cubic-in-out', text: 'Cubic In Out' },
|
2083
|
+
],
|
2084
|
+
textField: 'text',
|
2085
|
+
valueField: 'value',
|
2086
|
+
},
|
2022
2087
|
},
|
2023
|
-
|
2088
|
+
},
|
2089
|
+
visible: true,
|
2024
2090
|
},
|
2025
2091
|
{
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
},
|
2092
|
+
name: 'animationDuration',
|
2093
|
+
title: '@dashboard:widgets.line-chart.animation-duration',
|
2094
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2095
|
+
schema: {
|
2096
|
+
defaultValue: 800,
|
2097
|
+
dataType: 'number',
|
2098
|
+
interface: {
|
2099
|
+
name: 'animationDuration',
|
2100
|
+
path: 'options.animationDuration',
|
2101
|
+
type: AXPWidgetsCatalog.number,
|
2102
|
+
options: {
|
2103
|
+
placeholder: '0-2000',
|
2104
|
+
minValue: 0,
|
2105
|
+
maxValue: 2000,
|
2106
|
+
},
|
2042
2107
|
},
|
2043
|
-
|
2108
|
+
},
|
2109
|
+
visible: true,
|
2044
2110
|
},
|
2111
|
+
*/
|
2045
2112
|
],
|
2046
2113
|
components: {
|
2047
2114
|
view: {
|
@@ -2054,8 +2121,8 @@ const AXPLineChartWidget = {
|
|
2054
2121
|
height: 4,
|
2055
2122
|
minWidth: 2,
|
2056
2123
|
minHeight: 2,
|
2057
|
-
maxWidth:
|
2058
|
-
maxHeight:
|
2124
|
+
maxWidth: 6,
|
2125
|
+
maxHeight: 6,
|
2059
2126
|
},
|
2060
2127
|
},
|
2061
2128
|
};
|
@@ -3285,7 +3352,7 @@ class AXPWeatherWidgetViewComponent extends AXPValueWidgetComponent {
|
|
3285
3352
|
provide: AXPWeatherApiAbstract,
|
3286
3353
|
useClass: AXPWeatherApiService,
|
3287
3354
|
},
|
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 }); }
|
3355
|
+
], 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}.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 }); }
|
3289
3356
|
}
|
3290
3357
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPWeatherWidgetViewComponent, decorators: [{
|
3291
3358
|
type: Component,
|
@@ -3294,7 +3361,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
3294
3361
|
provide: AXPWeatherApiAbstract,
|
3295
3362
|
useClass: AXPWeatherApiService,
|
3296
3363
|
},
|
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"] }]
|
3364
|
+
], 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}.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"] }]
|
3298
3365
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
3299
3366
|
|
3300
3367
|
var weatherWidget_component = /*#__PURE__*/Object.freeze({
|
@@ -3949,7 +4016,6 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3949
4016
|
constructor() {
|
3950
4017
|
super(...arguments);
|
3951
4018
|
this.scope = RootConfig.config.i18n;
|
3952
|
-
this.isAdmin = false;
|
3953
4019
|
this.roleService = inject(AXMOrganizationManagementRoleEntityService);
|
3954
4020
|
this.sessionService = inject(AXPSessionService);
|
3955
4021
|
this.title = model('');
|
@@ -3957,6 +4023,7 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3957
4023
|
this.selectedRoleIds = model([]);
|
3958
4024
|
this.isDisabled = model(false);
|
3959
4025
|
this.isLocked = model(false);
|
4026
|
+
this.isAdmin = model(false);
|
3960
4027
|
this.roles = [];
|
3961
4028
|
}
|
3962
4029
|
get isValid() {
|
@@ -3966,14 +4033,20 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3966
4033
|
// Set initial values from input data
|
3967
4034
|
this.title.set(this.data?.title || '');
|
3968
4035
|
this.description.set(this.data?.description || '');
|
3969
|
-
this.selectedRoleIds.set(this.data?.roleIds || []);
|
3970
4036
|
this.isDisabled.set(this.data?.isDeleted || false);
|
3971
4037
|
this.isLocked.set(this.data?.locked || false);
|
4038
|
+
this.isAdmin.set(this.data?.isAdmin || false);
|
3972
4039
|
// Load roles if admin
|
3973
|
-
if (this.isAdmin) {
|
4040
|
+
if (this.isAdmin()) {
|
3974
4041
|
try {
|
3975
4042
|
const result = await this.roleService.query({ skip: 0, take: 100 });
|
3976
|
-
|
4043
|
+
if (result.items && result.items.length > 0) {
|
4044
|
+
this.roles = result.items.map((i) => ({
|
4045
|
+
id: i.id,
|
4046
|
+
title: i.title,
|
4047
|
+
}));
|
4048
|
+
}
|
4049
|
+
this.selectedRoleIds.set(this.roles.filter((i) => this.data?.roleIds?.includes(i.id)).map((i) => i.id));
|
3977
4050
|
}
|
3978
4051
|
catch (error) {
|
3979
4052
|
console.error('Error loading roles:', error);
|
@@ -3985,10 +4058,10 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3985
4058
|
this.close({
|
3986
4059
|
title: this.title()?.trim(),
|
3987
4060
|
description: this.description()?.trim(),
|
3988
|
-
roleIds: this.isAdmin ? this.selectedRoleIds() : undefined,
|
3989
|
-
isDeleted: this.isAdmin ? this.isDisabled() : undefined,
|
3990
|
-
locked: this.isAdmin ? this.isLocked() : undefined,
|
3991
|
-
scope: this.isAdmin ? 'T' : 'U',
|
4061
|
+
roleIds: this.isAdmin() ? this.selectedRoleIds() : undefined,
|
4062
|
+
isDeleted: this.isAdmin() ? this.isDisabled() : undefined,
|
4063
|
+
locked: this.isAdmin() ? this.isLocked() : undefined,
|
4064
|
+
scope: this.isAdmin() ? 'T' : 'U',
|
3992
4065
|
createdBy: this.sessionService.user?.id,
|
3993
4066
|
createdAt: new Date(),
|
3994
4067
|
updatedBy: this.sessionService.user?.id,
|
@@ -3997,7 +4070,7 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3997
4070
|
});
|
3998
4071
|
}
|
3999
4072
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMAddDashboardPopup, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
4000
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXMAddDashboardPopup, isStandalone: true, selector: "ng-component", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, selectedRoleIds: { classPropertyName: "selectedRoleIds", publicName: "selectedRoleIds", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, isLocked: { classPropertyName: "isLocked", publicName: "isLocked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { title: "titleChange", description: "descriptionChange", selectedRoleIds: "selectedRoleIdsChange", isDisabled: "isDisabledChange", isLocked: "isLockedChange" }, usesInheritance: true, ngImport: i0, template: `
|
4073
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXMAddDashboardPopup, isStandalone: true, selector: "ng-component", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, selectedRoleIds: { classPropertyName: "selectedRoleIds", publicName: "selectedRoleIds", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, isLocked: { classPropertyName: "isLocked", publicName: "isLocked", isSignal: true, isRequired: false, transformFunction: null }, isAdmin: { classPropertyName: "isAdmin", publicName: "isAdmin", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { title: "titleChange", description: "descriptionChange", selectedRoleIds: "selectedRoleIdsChange", isDisabled: "isDisabledChange", isLocked: "isLockedChange", isAdmin: "isAdminChange" }, usesInheritance: true, ngImport: i0, template: `
|
4001
4074
|
<div class="ax-card-body ax-p-4">
|
4002
4075
|
<div class="ax-flex ax-flex-col ax-gap-2 ax-pb-4">
|
4003
4076
|
<p class="ax-font-semibold">{{ 'title' | translate | async }}</p>
|
@@ -4009,7 +4082,7 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
4009
4082
|
</ax-text-box>
|
4010
4083
|
</div>
|
4011
4084
|
|
4012
|
-
@if (isAdmin) {
|
4085
|
+
@if (isAdmin()) {
|
4013
4086
|
<div class="ax-flex ax-flex-col ax-gap-2 ax-mt-4">
|
4014
4087
|
<p class="ax-font-semibold">{{ 'roles' | translate: { scope } | async }}</p>
|
4015
4088
|
<ax-select-box
|
@@ -4070,7 +4143,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
4070
4143
|
</ax-text-box>
|
4071
4144
|
</div>
|
4072
4145
|
|
4073
|
-
@if (isAdmin) {
|
4146
|
+
@if (isAdmin()) {
|
4074
4147
|
<div class="ax-flex ax-flex-col ax-gap-2 ax-mt-4">
|
4075
4148
|
<p class="ax-font-semibold">{{ 'roles' | translate: { scope } | async }}</p>
|
4076
4149
|
<ax-select-box
|
@@ -4204,7 +4277,7 @@ class AXMDashboardPopupService {
|
|
4204
4277
|
draggable: true,
|
4205
4278
|
hasBackdrop: true,
|
4206
4279
|
title: await this.translateService.translateAsync('dashboard-info', { scope: 'dashboard' }),
|
4207
|
-
data: dashboardData,
|
4280
|
+
data: { data: dashboardData },
|
4208
4281
|
});
|
4209
4282
|
if (!result.data) {
|
4210
4283
|
return;
|
@@ -4221,7 +4294,7 @@ class AXMDashboardPopupService {
|
|
4221
4294
|
size: 'sm',
|
4222
4295
|
draggable: true,
|
4223
4296
|
hasBackdrop: true,
|
4224
|
-
title: '
|
4297
|
+
title: await this.translateService.translateAsync('widget-configuration', { scope: 'dashboard' }),
|
4225
4298
|
data: { widget },
|
4226
4299
|
});
|
4227
4300
|
if (!result.data) {
|
@@ -4241,139 +4314,115 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
4241
4314
|
args: [{ providedIn: 'root' }]
|
4242
4315
|
}] });
|
4243
4316
|
|
4317
|
+
// Helper functions
|
4318
|
+
const createInitialState = () => ({
|
4319
|
+
dashboards: [],
|
4320
|
+
allDashboards: [],
|
4321
|
+
currentDashboardId: null,
|
4322
|
+
isAdmin: false,
|
4323
|
+
dashboardsOption: {
|
4324
|
+
float: false,
|
4325
|
+
cellHeight: 75,
|
4326
|
+
gap: 5,
|
4327
|
+
minRow: 9,
|
4328
|
+
column: 12,
|
4329
|
+
responsiveLayout: [
|
4330
|
+
{ column: 12, width: 2048 },
|
4331
|
+
{ column: 6, width: 768 },
|
4332
|
+
{ column: 1, width: 480 },
|
4333
|
+
],
|
4334
|
+
},
|
4335
|
+
isLoading: false,
|
4336
|
+
});
|
4337
|
+
const modelToDashboardLayout = (model) => ({
|
4338
|
+
id: model.id || '',
|
4339
|
+
title: model.title,
|
4340
|
+
description: model.description,
|
4341
|
+
widgets: model.widgets || [],
|
4342
|
+
roleIds: model.roleIds,
|
4343
|
+
isDeleted: model.isDeleted,
|
4344
|
+
locked: model.locked,
|
4345
|
+
createdAt: model.createdAt,
|
4346
|
+
updatedAt: model.updatedAt,
|
4347
|
+
createdBy: model.createdBy,
|
4348
|
+
updatedBy: model.updatedBy,
|
4349
|
+
scope: model.scope,
|
4350
|
+
});
|
4351
|
+
const dashboardLayoutToModel = (layout) => ({
|
4352
|
+
id: layout.id,
|
4353
|
+
name: layout.title,
|
4354
|
+
title: layout.title,
|
4355
|
+
description: layout.description || '',
|
4356
|
+
widgets: layout.widgets,
|
4357
|
+
roleIds: layout.roleIds,
|
4358
|
+
isDeleted: layout.isDeleted,
|
4359
|
+
locked: layout.locked,
|
4360
|
+
createdAt: layout.createdAt,
|
4361
|
+
updatedAt: layout.updatedAt,
|
4362
|
+
createdBy: layout.createdBy,
|
4363
|
+
updatedBy: layout.updatedBy,
|
4364
|
+
scope: layout.scope,
|
4365
|
+
});
|
4244
4366
|
// Create the SignalStore
|
4245
4367
|
const AXMDashboardStore = signalStore({ providedIn: 'root' },
|
4246
4368
|
// Initial State Definition
|
4247
|
-
withState(() =>
|
4248
|
-
// Define initial empty state
|
4249
|
-
const state = {
|
4250
|
-
dashboards: [],
|
4251
|
-
allDashboards: [],
|
4252
|
-
currentDashboardId: null,
|
4253
|
-
isAdmin: false,
|
4254
|
-
dashboardsOption: {
|
4255
|
-
float: false,
|
4256
|
-
cellHeight: 75,
|
4257
|
-
gap: 5,
|
4258
|
-
minRow: 9,
|
4259
|
-
column: 12,
|
4260
|
-
responsiveLayout: [
|
4261
|
-
{ column: 12, width: 2048 },
|
4262
|
-
{ column: 6, width: 768 },
|
4263
|
-
{ column: 1, width: 480 },
|
4264
|
-
],
|
4265
|
-
},
|
4266
|
-
isLoading: false,
|
4267
|
-
};
|
4268
|
-
return state;
|
4269
|
-
}),
|
4369
|
+
withState(() => createInitialState()),
|
4270
4370
|
// Computed Properties
|
4271
4371
|
withComputed((state, sessionService = inject(AXPSessionService), layoutThemeService = inject(AXPLayoutThemeService)) => ({
|
4272
|
-
|
4273
|
-
|
4274
|
-
|
4275
|
-
|
4276
|
-
return state.isAdmin();
|
4277
|
-
}),
|
4278
|
-
allDashboards: computed(() => {
|
4279
|
-
return state.allDashboards();
|
4280
|
-
}),
|
4281
|
-
dashboardsOption: computed(() => {
|
4372
|
+
selectedDashboard: computed(() => state.dashboards().find((dashboard) => dashboard.id === state.currentDashboardId()) || null),
|
4373
|
+
isUserAdmin: computed(() => state.isAdmin()),
|
4374
|
+
availableDashboards: computed(() => state.allDashboards()),
|
4375
|
+
currentLayoutOptions: computed(() => {
|
4282
4376
|
const currentDashboard = state.dashboards().find((dashboard) => dashboard.id === state.currentDashboardId());
|
4283
4377
|
const baseOptions = state.dashboardsOption();
|
4284
|
-
|
4285
|
-
if (!currentDashboard) {
|
4378
|
+
if (!currentDashboard)
|
4286
4379
|
return baseOptions;
|
4287
|
-
}
|
4288
|
-
// Always disable drag and resize on mobile devices
|
4289
4380
|
if (!layoutThemeService.isDesktopDevice()) {
|
4290
|
-
return {
|
4291
|
-
...baseOptions,
|
4292
|
-
disableDrag: true,
|
4293
|
-
disableResize: true,
|
4294
|
-
};
|
4381
|
+
return { ...baseOptions, disableDrag: true, disableResize: true };
|
4295
4382
|
}
|
4296
|
-
// If the base options already have explicit disableDrag and disableResize values,
|
4297
|
-
// preserve those values (these were likely set by toggleLockDashboard)
|
4298
4383
|
if (baseOptions.disableDrag !== undefined && baseOptions.disableResize !== undefined) {
|
4299
4384
|
return baseOptions;
|
4300
4385
|
}
|
4301
|
-
// Check if dashboard is locked - locked dashboards always have drag and resize disabled
|
4302
4386
|
if (currentDashboard.locked === true) {
|
4303
|
-
return {
|
4304
|
-
...baseOptions,
|
4305
|
-
disableDrag: true,
|
4306
|
-
disableResize: true,
|
4307
|
-
};
|
4387
|
+
return { ...baseOptions, disableDrag: true, disableResize: true };
|
4308
4388
|
}
|
4309
|
-
|
4310
|
-
if (state.isAdmin()) {
|
4389
|
+
if (state.isAdmin())
|
4311
4390
|
return baseOptions;
|
4312
|
-
}
|
4313
|
-
// Get user role
|
4314
4391
|
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4315
|
-
// Check if user has role in dashboard
|
4316
4392
|
const hasRoleIds = currentDashboard.roleIds && Array.isArray(currentDashboard.roleIds) && currentDashboard.roleIds.length > 0;
|
4317
4393
|
const hasUserRole = userRole && hasRoleIds && currentDashboard.roleIds?.includes(userRole);
|
4318
|
-
// If user is not admin, has role in dashboard, and dashboard has scope 'T', disable drag and resize
|
4319
4394
|
if (!state.isAdmin() && hasUserRole && currentDashboard.scope === 'T') {
|
4320
|
-
return {
|
4321
|
-
...baseOptions,
|
4322
|
-
disableDrag: true,
|
4323
|
-
disableResize: true,
|
4324
|
-
};
|
4395
|
+
return { ...baseOptions, disableDrag: true, disableResize: true };
|
4325
4396
|
}
|
4326
|
-
// Otherwise, return base options
|
4327
4397
|
return baseOptions;
|
4328
4398
|
}),
|
4329
|
-
canConfigureWidget: computed(() => {
|
4330
|
-
|
4331
|
-
|
4332
|
-
|
4333
|
-
|
4334
|
-
// If admin, always allow configuration
|
4335
|
-
if (state.isAdmin())
|
4336
|
-
return widget.node?.options?.['hasConfiguration'] ?? true;
|
4337
|
-
// If dashboard is locked, no configuration allowed
|
4338
|
-
if (currentDashboard.locked === true) {
|
4339
|
-
return false;
|
4340
|
-
}
|
4341
|
-
// Get user role
|
4342
|
-
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4343
|
-
// Check if user has role in dashboard
|
4344
|
-
const hasRoleIds = currentDashboard.roleIds && Array.isArray(currentDashboard.roleIds) && currentDashboard.roleIds.length > 0;
|
4345
|
-
const hasUserRole = userRole && hasRoleIds && currentDashboard.roleIds?.includes(userRole);
|
4346
|
-
// If user is not admin, has role in dashboard, and dashboard has scope 'T', disable configuration
|
4347
|
-
if (hasUserRole && currentDashboard.scope === 'T') {
|
4348
|
-
return false;
|
4349
|
-
}
|
4350
|
-
// Otherwise, use the widget's configuration value or default to true
|
4399
|
+
canConfigureWidget: computed(() => (widget) => {
|
4400
|
+
const currentDashboard = state.dashboards().find((dashboard) => dashboard.id === state.currentDashboardId());
|
4401
|
+
if (!currentDashboard)
|
4402
|
+
return true;
|
4403
|
+
if (state.isAdmin())
|
4351
4404
|
return widget.node?.options?.['hasConfiguration'] ?? true;
|
4352
|
-
|
4405
|
+
if (currentDashboard.locked === true)
|
4406
|
+
return false;
|
4407
|
+
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4408
|
+
const hasRoleIds = currentDashboard.roleIds && Array.isArray(currentDashboard.roleIds) && currentDashboard.roleIds.length > 0;
|
4409
|
+
const hasUserRole = userRole && hasRoleIds && currentDashboard.roleIds?.includes(userRole);
|
4410
|
+
if (hasUserRole && currentDashboard.scope === 'T')
|
4411
|
+
return false;
|
4412
|
+
return widget.node?.options?.['hasConfiguration'] ?? true;
|
4353
4413
|
}),
|
4354
|
-
isWidgetLocked: computed(() => {
|
4355
|
-
|
4356
|
-
|
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
|
-
}
|
4414
|
+
isWidgetLocked: computed(() => (widget) => {
|
4415
|
+
const currentDashboard = state.dashboards().find((dashboard) => dashboard.id === state.currentDashboardId());
|
4416
|
+
if (!currentDashboard)
|
4375
4417
|
return false;
|
4376
|
-
|
4418
|
+
if (currentDashboard.locked === true)
|
4419
|
+
return true;
|
4420
|
+
if (state.isAdmin())
|
4421
|
+
return false;
|
4422
|
+
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4423
|
+
const hasRoleIds = currentDashboard.roleIds && Array.isArray(currentDashboard.roleIds) && currentDashboard.roleIds.length > 0;
|
4424
|
+
const hasUserRole = userRole && hasRoleIds && currentDashboard.roleIds?.includes(userRole);
|
4425
|
+
return hasUserRole && currentDashboard.scope === 'T';
|
4377
4426
|
}),
|
4378
4427
|
})),
|
4379
4428
|
// Methods for State Management
|
@@ -4386,126 +4435,112 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4386
4435
|
async function loadDashboards() {
|
4387
4436
|
try {
|
4388
4437
|
patchState(store, { isLoading: true });
|
4389
|
-
// Get dashboards from service using query method
|
4390
4438
|
const result = await dashboardService.query({ skip: 0, take: 100 });
|
4391
4439
|
const dashboardModels = result.items || [];
|
4392
|
-
// Convert dashboard models to AXPDashboardLayout
|
4393
4440
|
const dashboards = dashboardModels.map(modelToDashboardLayout);
|
4394
|
-
// Get current dashboard from settings
|
4395
4441
|
const currentDashboardId = await settingService
|
4396
4442
|
.scope(AXPPlatformScope.User)
|
4397
4443
|
.get(AXPHomeDashboardSetting.CurrentDashboard);
|
4398
4444
|
let newCurrentDashboardId = null;
|
4399
4445
|
if (dashboards.length > 0) {
|
4400
|
-
// Check if currentDashboardId exists and is valid
|
4401
4446
|
const dashboardExists = currentDashboardId && dashboards.some((d) => d.id === currentDashboardId);
|
4402
|
-
|
4403
|
-
|
4404
|
-
}
|
4405
|
-
else {
|
4406
|
-
// If current dashboard is not valid or not set, use the first one
|
4407
|
-
newCurrentDashboardId = dashboards[0].id;
|
4408
|
-
// Save to user settings
|
4447
|
+
newCurrentDashboardId = dashboardExists ? currentDashboardId : dashboards[0].id;
|
4448
|
+
if (!dashboardExists) {
|
4409
4449
|
settingService
|
4410
4450
|
.scope(AXPPlatformScope.User)
|
4411
4451
|
.set(AXPHomeDashboardSetting.CurrentDashboard, newCurrentDashboardId);
|
4412
4452
|
}
|
4413
4453
|
}
|
4414
|
-
// First, update the state with all dashboards
|
4415
4454
|
patchState(store, {
|
4416
4455
|
allDashboards: dashboards,
|
4417
|
-
dashboards: dashboards,
|
4456
|
+
dashboards: dashboards,
|
4418
4457
|
isLoading: false,
|
4419
4458
|
currentDashboardId: newCurrentDashboardId,
|
4420
4459
|
});
|
4421
|
-
// After state is updated, apply filtering if needed
|
4422
|
-
if (store.isAdmin() !== undefined) {
|
4423
|
-
// We need to use the method from the return object, so we'll call it later
|
4424
|
-
}
|
4425
4460
|
}
|
4426
4461
|
catch (error) {
|
4427
4462
|
console.error('Error loading dashboards:', error);
|
4428
4463
|
patchState(store, { isLoading: false });
|
4429
4464
|
}
|
4430
4465
|
}
|
4431
|
-
// Convert entity model to dashboard layout
|
4432
|
-
function modelToDashboardLayout(model) {
|
4433
|
-
return {
|
4434
|
-
id: model.id || '',
|
4435
|
-
title: model.title,
|
4436
|
-
description: model.description,
|
4437
|
-
widgets: model.widgets || [],
|
4438
|
-
roleIds: model.roleIds,
|
4439
|
-
isDeleted: model.isDeleted,
|
4440
|
-
locked: model.locked,
|
4441
|
-
createdAt: model.createdAt,
|
4442
|
-
updatedAt: model.updatedAt,
|
4443
|
-
createdBy: model.createdBy,
|
4444
|
-
updatedBy: model.updatedBy,
|
4445
|
-
scope: model.scope,
|
4446
|
-
};
|
4447
|
-
}
|
4448
|
-
// Convert dashboard layout to entity model
|
4449
|
-
function dashboardLayoutToModel(layout) {
|
4450
|
-
return {
|
4451
|
-
id: layout.id,
|
4452
|
-
name: layout.title,
|
4453
|
-
title: layout.title,
|
4454
|
-
description: layout.description || '',
|
4455
|
-
widgets: layout.widgets,
|
4456
|
-
roleIds: layout.roleIds,
|
4457
|
-
isDeleted: layout.isDeleted,
|
4458
|
-
locked: layout.locked,
|
4459
|
-
createdAt: layout.createdAt,
|
4460
|
-
updatedAt: layout.updatedAt,
|
4461
|
-
createdBy: layout.createdBy,
|
4462
|
-
updatedBy: layout.updatedBy,
|
4463
|
-
scope: layout.scope,
|
4464
|
-
};
|
4465
|
-
}
|
4466
4466
|
return {
|
4467
|
-
// Set current dashboard
|
4468
4467
|
setCurrentDashboard(dashboardId) {
|
4469
4468
|
patchState(store, { currentDashboardId: dashboardId });
|
4470
4469
|
settingService.scope(AXPPlatformScope.User).set(AXPHomeDashboardSetting.CurrentDashboard, dashboardId);
|
4471
4470
|
},
|
4472
|
-
// Add a new dashboard
|
4473
4471
|
async addDashboard() {
|
4474
4472
|
try {
|
4475
|
-
const newDashboard = await dashboardPopup.generateDashboardLayout({}, store.
|
4473
|
+
const newDashboard = await dashboardPopup.generateDashboardLayout({}, store.isUserAdmin());
|
4476
4474
|
if (!newDashboard)
|
4477
4475
|
return;
|
4478
|
-
// Add creation and update metadata
|
4479
4476
|
const userId = sessionService.user?.id;
|
4480
4477
|
const now = new Date();
|
4481
|
-
|
4482
|
-
|
4483
|
-
|
4484
|
-
|
4485
|
-
|
4486
|
-
|
4487
|
-
|
4478
|
+
const dashboardWithMetadata = {
|
4479
|
+
...newDashboard,
|
4480
|
+
createdBy: userId,
|
4481
|
+
createdAt: now,
|
4482
|
+
updatedBy: userId,
|
4483
|
+
updatedAt: now,
|
4484
|
+
scope: store.isUserAdmin() ? 'T' : 'U',
|
4485
|
+
widgets: [],
|
4486
|
+
};
|
4487
|
+
const dashboardModel = dashboardLayoutToModel(dashboardWithMetadata);
|
4488
4488
|
const createdDashboardId = await dashboardService.insertOne(dashboardModel);
|
4489
|
-
|
4490
|
-
|
4491
|
-
|
4492
|
-
const updatedAllDashboards = [...store.allDashboards(), newDashboard];
|
4493
|
-
const updatedDashboards = [...store.dashboards(), newDashboard];
|
4489
|
+
dashboardWithMetadata.id = createdDashboardId;
|
4490
|
+
const updatedAllDashboards = [...store.availableDashboards(), dashboardWithMetadata];
|
4491
|
+
const updatedDashboards = [...store.dashboards(), dashboardWithMetadata];
|
4494
4492
|
patchState(store, {
|
4495
4493
|
allDashboards: updatedAllDashboards,
|
4496
4494
|
dashboards: updatedDashboards,
|
4497
|
-
currentDashboardId:
|
4495
|
+
currentDashboardId: dashboardWithMetadata.id,
|
4498
4496
|
});
|
4499
|
-
|
4500
|
-
|
4497
|
+
settingService
|
4498
|
+
.scope(AXPPlatformScope.User)
|
4499
|
+
.set(AXPHomeDashboardSetting.CurrentDashboard, dashboardWithMetadata.id);
|
4501
4500
|
}
|
4502
4501
|
catch (error) {
|
4503
4502
|
console.error('Error adding dashboard:', error);
|
4504
4503
|
}
|
4505
4504
|
},
|
4506
|
-
|
4505
|
+
async editDashboard() {
|
4506
|
+
const currentDashboard = store.selectedDashboard();
|
4507
|
+
if (!currentDashboard)
|
4508
|
+
return;
|
4509
|
+
try {
|
4510
|
+
const editedDashboard = await dashboardPopup.generateDashboardLayout({
|
4511
|
+
title: currentDashboard.title,
|
4512
|
+
description: currentDashboard.description,
|
4513
|
+
roleIds: currentDashboard.roleIds,
|
4514
|
+
scope: currentDashboard.scope,
|
4515
|
+
}, store.isUserAdmin());
|
4516
|
+
if (!editedDashboard)
|
4517
|
+
return;
|
4518
|
+
const userId = sessionService.user?.id;
|
4519
|
+
const now = new Date();
|
4520
|
+
const updatedDashboard = {
|
4521
|
+
...currentDashboard,
|
4522
|
+
...editedDashboard,
|
4523
|
+
updatedBy: userId,
|
4524
|
+
updatedAt: now,
|
4525
|
+
};
|
4526
|
+
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4527
|
+
const updatedAllDashboards = store
|
4528
|
+
.availableDashboards()
|
4529
|
+
.map((d) => (d.id === updatedDashboard.id ? updatedDashboard : d));
|
4530
|
+
const updatedDashboards = store
|
4531
|
+
.dashboards()
|
4532
|
+
.map((d) => (d.id === updatedDashboard.id ? updatedDashboard : d));
|
4533
|
+
patchState(store, {
|
4534
|
+
allDashboards: updatedAllDashboards,
|
4535
|
+
dashboards: updatedDashboards,
|
4536
|
+
});
|
4537
|
+
}
|
4538
|
+
catch (error) {
|
4539
|
+
console.error('Error editing dashboard:', error);
|
4540
|
+
}
|
4541
|
+
},
|
4507
4542
|
async addWidget() {
|
4508
|
-
if (!store.
|
4543
|
+
if (!store.selectedDashboard()) {
|
4509
4544
|
console.warn('No current dashboard selected');
|
4510
4545
|
return;
|
4511
4546
|
}
|
@@ -4513,57 +4548,43 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4513
4548
|
const widgets = await widgetPickerService.showPicker({
|
4514
4549
|
groups: [AXPWidgetGroupEnum.DashboardWidget],
|
4515
4550
|
});
|
4516
|
-
|
4517
|
-
|
4518
|
-
|
4519
|
-
|
4520
|
-
filteredWidgets[0].options = {};
|
4551
|
+
const filteredWidgets = widgets.map(({ __meta__, ...rest }) => {
|
4552
|
+
const widget = rest;
|
4553
|
+
if (widget.type === 'sticky-note' && !widget.options) {
|
4554
|
+
widget.options = { hasConfiguration: false };
|
4521
4555
|
}
|
4522
|
-
filteredWidgets[0].options.hasConfiguration = false;
|
4523
|
-
}
|
4524
|
-
filteredWidgets.forEach((widget) => {
|
4525
4556
|
const randomId = AXPDataGenerator.uuid();
|
4526
|
-
widget.name = widget
|
4527
|
-
widget.path = widget
|
4528
|
-
|
4529
|
-
// Step 2: Convert the selected widgets into AXPDashboardWidgetData format
|
4530
|
-
const convertedWidgets = filteredWidgets.map((widget) => {
|
4531
|
-
const id = AXPDataGenerator.uuid();
|
4532
|
-
return {
|
4533
|
-
config: {
|
4534
|
-
height: widget?.meta?.dimensions?.height ?? 2,
|
4535
|
-
width: widget?.meta?.dimensions?.width ?? 2,
|
4536
|
-
minHeight: widget?.meta?.dimensions?.minHeight,
|
4537
|
-
minWidth: widget?.meta?.dimensions?.minWidth,
|
4538
|
-
maxHeight: widget?.meta?.dimensions?.maxHeight,
|
4539
|
-
maxWidth: widget?.meta?.dimensions?.maxWidth,
|
4540
|
-
id,
|
4541
|
-
},
|
4542
|
-
node: { ...widget, name: id },
|
4543
|
-
};
|
4544
|
-
});
|
4545
|
-
// Step 3: Update the dashboards
|
4546
|
-
const updatedDashboards = store.dashboards().map((dashboard) => {
|
4547
|
-
if (dashboard.id === store.currentDashboardId()) {
|
4548
|
-
return {
|
4549
|
-
...dashboard,
|
4550
|
-
widgets: [...dashboard.widgets, ...convertedWidgets],
|
4551
|
-
};
|
4552
|
-
}
|
4553
|
-
return dashboard;
|
4557
|
+
widget.name = `${widget.type}-${randomId}`;
|
4558
|
+
widget.path = `${widget.type}-${randomId}`;
|
4559
|
+
return widget;
|
4554
4560
|
});
|
4555
|
-
|
4556
|
-
|
4557
|
-
|
4558
|
-
|
4559
|
-
|
4561
|
+
const convertedWidgets = filteredWidgets.map((widget) => ({
|
4562
|
+
config: {
|
4563
|
+
height: widget?.meta?.dimensions?.height ?? 2,
|
4564
|
+
width: widget?.meta?.dimensions?.width ?? 2,
|
4565
|
+
minHeight: widget?.meta?.dimensions?.minHeight,
|
4566
|
+
minWidth: widget?.meta?.dimensions?.minWidth,
|
4567
|
+
maxHeight: widget?.meta?.dimensions?.maxHeight,
|
4568
|
+
maxWidth: widget?.meta?.dimensions?.maxWidth,
|
4569
|
+
id: AXPDataGenerator.uuid(),
|
4570
|
+
},
|
4571
|
+
node: { ...widget, name: widget.name },
|
4572
|
+
}));
|
4573
|
+
const currentDashboard = store.selectedDashboard();
|
4574
|
+
const updatedDashboard = {
|
4575
|
+
...currentDashboard,
|
4576
|
+
widgets: [...currentDashboard.widgets, ...convertedWidgets],
|
4577
|
+
};
|
4578
|
+
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4579
|
+
const updatedDashboards = store
|
4580
|
+
.dashboards()
|
4581
|
+
.map((d) => (d.id === updatedDashboard.id ? updatedDashboard : d));
|
4560
4582
|
patchState(store, { dashboards: updatedDashboards });
|
4561
4583
|
}
|
4562
4584
|
catch (error) {
|
4563
4585
|
console.error('Error adding widget:', error);
|
4564
4586
|
}
|
4565
4587
|
},
|
4566
|
-
// Remove a dashboard
|
4567
4588
|
async removeDashboard(id) {
|
4568
4589
|
if (!id) {
|
4569
4590
|
console.warn('No dashboard ID provided for removal');
|
@@ -4572,17 +4593,13 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4572
4593
|
try {
|
4573
4594
|
const dialogResult = await dialogService.confirm(await translationService.translateAsync('workflow.warning'), await translationService.translateAsync('workflow.confirm-delete'), 'danger', 'horizontal');
|
4574
4595
|
if (dialogResult.result) {
|
4575
|
-
// Delete from service
|
4576
4596
|
await dashboardService.deleteOne(id);
|
4577
|
-
|
4578
|
-
const updatedAllDashboards = store.allDashboards().filter((dashboard) => dashboard.id !== id);
|
4597
|
+
const updatedAllDashboards = store.availableDashboards().filter((dashboard) => dashboard.id !== id);
|
4579
4598
|
const updatedDashboards = store.dashboards().filter((dashboard) => dashboard.id !== id);
|
4580
|
-
// Update state and select a new current dashboard if needed
|
4581
4599
|
let newCurrentDashboardId = store.currentDashboardId();
|
4582
4600
|
if (id === store.currentDashboardId()) {
|
4583
4601
|
newCurrentDashboardId =
|
4584
4602
|
updatedDashboards.length > 0 ? updatedDashboards[updatedDashboards.length - 1].id : null;
|
4585
|
-
// Save to settings if we changed the current dashboard
|
4586
4603
|
if (newCurrentDashboardId) {
|
4587
4604
|
settingService
|
4588
4605
|
.scope(AXPPlatformScope.User)
|
@@ -4600,7 +4617,6 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4600
4617
|
console.error('Error removing dashboard:', error);
|
4601
4618
|
}
|
4602
4619
|
},
|
4603
|
-
// Remove a widget from a dashboard
|
4604
4620
|
async removeWidget(dashboardId, widgetId) {
|
4605
4621
|
const currentDashboard = store.dashboards().find((d) => d.id === dashboardId);
|
4606
4622
|
if (!currentDashboard)
|
@@ -4609,92 +4625,56 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4609
4625
|
...currentDashboard,
|
4610
4626
|
widgets: currentDashboard.widgets.filter((widget) => widget.config.id !== widgetId),
|
4611
4627
|
};
|
4612
|
-
// Save to service
|
4613
4628
|
await dashboardService.updateOne(dashboardId, dashboardLayoutToModel(updatedDashboard));
|
4614
|
-
// Update local state
|
4615
4629
|
const updatedDashboards = store
|
4616
4630
|
.dashboards()
|
4617
4631
|
.map((dashboard) => (dashboard.id === dashboardId ? updatedDashboard : dashboard));
|
4618
4632
|
patchState(store, { dashboards: updatedDashboards });
|
4619
4633
|
},
|
4620
|
-
// Handle configuration changes
|
4621
4634
|
async handleConfigChange(dashboard) {
|
4622
|
-
// Save to service
|
4623
4635
|
await dashboardService.updateOne(dashboard.id, dashboardLayoutToModel(dashboard));
|
4624
|
-
// Update local state
|
4625
4636
|
const updatedDashboards = store.dashboards().map((d) => (d.id === dashboard.id ? dashboard : d));
|
4626
4637
|
patchState(store, {
|
4627
4638
|
dashboards: updatedDashboards,
|
4628
4639
|
currentDashboardId: dashboard.id,
|
4629
4640
|
});
|
4630
|
-
// Save current dashboard to settings
|
4631
4641
|
settingService.scope(AXPPlatformScope.User).set(AXPHomeDashboardSetting.CurrentDashboard, dashboard.id);
|
4632
4642
|
},
|
4633
|
-
// Handle grid layout changes
|
4634
4643
|
async onGridChange(event) {
|
4635
|
-
|
4636
|
-
if (!layoutThemeService.isDesktopDevice()) {
|
4637
|
-
return;
|
4638
|
-
}
|
4639
|
-
if (!store.currentDashboard()) {
|
4640
|
-
console.warn('No current dashboard for grid change');
|
4644
|
+
if (!layoutThemeService.isDesktopDevice() || !store.selectedDashboard())
|
4641
4645
|
return;
|
4642
|
-
}
|
4643
|
-
// Extract nodes from the event and remove the `element` property
|
4644
4646
|
const nodes = event.nodes.map(({ element, ...rest }) => rest);
|
4645
|
-
|
4646
|
-
const currentDashboard = store.currentDashboard();
|
4647
|
+
const currentDashboard = store.selectedDashboard();
|
4647
4648
|
const updatedWidgets = currentDashboard.widgets.map((widget) => {
|
4648
4649
|
const updatedNode = nodes.find((node) => node.id === widget.config.id);
|
4649
|
-
|
4650
|
-
return {
|
4651
|
-
...widget,
|
4652
|
-
config: updatedNode,
|
4653
|
-
};
|
4654
|
-
}
|
4655
|
-
return widget;
|
4650
|
+
return updatedNode ? { ...widget, config: updatedNode } : widget;
|
4656
4651
|
});
|
4657
4652
|
const updatedDashboard = {
|
4658
4653
|
...currentDashboard,
|
4659
4654
|
widgets: updatedWidgets,
|
4660
4655
|
};
|
4661
|
-
// Save to service
|
4662
4656
|
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4663
|
-
// Update the dashboards
|
4664
4657
|
const updatedDashboards = store
|
4665
4658
|
.dashboards()
|
4666
4659
|
.map((dashboard) => (dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard));
|
4667
4660
|
patchState(store, { dashboards: updatedDashboards });
|
4668
4661
|
},
|
4669
|
-
// Handle widget configuration
|
4670
4662
|
async handlePopupConfiguration(widgetNode) {
|
4671
|
-
if (!store.
|
4672
|
-
console.warn('No current dashboard selected');
|
4663
|
+
if (!store.selectedDashboard())
|
4673
4664
|
return;
|
4674
|
-
}
|
4675
4665
|
try {
|
4676
4666
|
const updatedNode = await dashboardPopup.handlePopupConfiguration(widgetNode);
|
4677
|
-
if (!updatedNode)
|
4667
|
+
if (!updatedNode)
|
4678
4668
|
return;
|
4679
|
-
|
4680
|
-
|
4681
|
-
|
4682
|
-
|
4683
|
-
if (widget.node?.name === widgetNode.name && widget.node?.path === widgetNode.path) {
|
4684
|
-
return {
|
4685
|
-
...widget,
|
4686
|
-
node: updatedNode,
|
4687
|
-
};
|
4688
|
-
}
|
4689
|
-
return widget;
|
4690
|
-
});
|
4669
|
+
const currentDashboard = store.selectedDashboard();
|
4670
|
+
const updatedWidgets = currentDashboard.widgets.map((widget) => widget.node?.name === widgetNode.name && widget.node?.path === widgetNode.path
|
4671
|
+
? { ...widget, node: updatedNode }
|
4672
|
+
: widget);
|
4691
4673
|
const updatedDashboard = {
|
4692
4674
|
...currentDashboard,
|
4693
4675
|
widgets: updatedWidgets,
|
4694
4676
|
};
|
4695
|
-
// Save to service
|
4696
4677
|
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4697
|
-
// Update the dashboards state
|
4698
4678
|
const updatedDashboards = store
|
4699
4679
|
.dashboards()
|
4700
4680
|
.map((dashboard) => (dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard));
|
@@ -4704,74 +4684,47 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4704
4684
|
console.error('Error handling widget configuration:', error);
|
4705
4685
|
}
|
4706
4686
|
},
|
4707
|
-
// Handle widget value changes
|
4708
4687
|
async handleValueChanged(widgetNode, data) {
|
4709
|
-
if (!store.
|
4710
|
-
console.warn('No current dashboard selected');
|
4688
|
+
if (!store.selectedDashboard())
|
4711
4689
|
return;
|
4712
|
-
}
|
4713
4690
|
try {
|
4714
|
-
|
4715
|
-
const
|
4716
|
-
|
4717
|
-
|
4718
|
-
return {
|
4719
|
-
...widget,
|
4720
|
-
node: {
|
4721
|
-
...widget.node,
|
4722
|
-
defaultValue: data,
|
4723
|
-
},
|
4724
|
-
};
|
4725
|
-
}
|
4726
|
-
return widget;
|
4727
|
-
});
|
4691
|
+
const currentDashboard = store.selectedDashboard();
|
4692
|
+
const updatedWidgets = currentDashboard.widgets.map((widget) => widget.node && widget.node.name === widgetNode.name && widget.node.path === widgetNode.path
|
4693
|
+
? { ...widget, node: { ...widget.node, defaultValue: data } }
|
4694
|
+
: widget);
|
4728
4695
|
const updatedDashboard = {
|
4729
4696
|
...currentDashboard,
|
4730
4697
|
widgets: updatedWidgets,
|
4731
4698
|
};
|
4732
|
-
// Save to service
|
4733
4699
|
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4734
|
-
// Update the dashboards state
|
4735
4700
|
const updatedDashboards = store
|
4736
4701
|
.dashboards()
|
4737
4702
|
.map((dashboard) => (dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard));
|
4738
|
-
|
4703
|
+
patchState(store, { dashboards: updatedDashboards });
|
4739
4704
|
}
|
4740
4705
|
catch (error) {
|
4741
4706
|
console.error('Error handling widget value change:', error);
|
4742
4707
|
}
|
4743
4708
|
},
|
4744
|
-
// Handle widget options changes
|
4745
4709
|
async handleOptionsChanged(widgetNode, data) {
|
4746
|
-
if (!store.
|
4747
|
-
console.warn('No current dashboard selected');
|
4710
|
+
if (!store.selectedDashboard())
|
4748
4711
|
return;
|
4749
|
-
}
|
4750
4712
|
try {
|
4751
|
-
|
4752
|
-
const
|
4753
|
-
|
4754
|
-
|
4755
|
-
|
4756
|
-
...widget,
|
4757
|
-
|
4758
|
-
|
4759
|
-
options: {
|
4760
|
-
...(widget.node.options || {}),
|
4761
|
-
...data,
|
4762
|
-
},
|
4763
|
-
},
|
4764
|
-
};
|
4713
|
+
const currentDashboard = store.selectedDashboard();
|
4714
|
+
const updatedWidgets = currentDashboard.widgets.map((widget) => widget.node && widget.node.name === widgetNode.name && widget.node.path === widgetNode.path
|
4715
|
+
? {
|
4716
|
+
...widget,
|
4717
|
+
node: {
|
4718
|
+
...widget.node,
|
4719
|
+
options: { ...(widget.node.options || {}), ...data },
|
4720
|
+
},
|
4765
4721
|
}
|
4766
|
-
|
4767
|
-
});
|
4722
|
+
: widget);
|
4768
4723
|
const updatedDashboard = {
|
4769
4724
|
...currentDashboard,
|
4770
4725
|
widgets: updatedWidgets,
|
4771
4726
|
};
|
4772
|
-
// Save to service
|
4773
4727
|
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4774
|
-
// Update the dashboards state
|
4775
4728
|
const updatedDashboards = store
|
4776
4729
|
.dashboards()
|
4777
4730
|
.map((dashboard) => (dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard));
|
@@ -4781,110 +4734,70 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4781
4734
|
console.error('Error handling widget options change:', error);
|
4782
4735
|
}
|
4783
4736
|
},
|
4784
|
-
// Handle setting admin state
|
4785
4737
|
setIsAdmin(isAdmin) {
|
4786
4738
|
patchState(store, { isAdmin });
|
4787
4739
|
},
|
4788
|
-
// Filter dashboards by scope
|
4789
4740
|
filterDashboardsByScope(isAdmin) {
|
4790
|
-
|
4791
|
-
const allDashboards = store.allDashboards();
|
4792
|
-
// Get user ID and role from session service
|
4741
|
+
const allDashboards = store.availableDashboards();
|
4793
4742
|
const userId = sessionService.user?.id;
|
4794
4743
|
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4795
4744
|
if (!userId) {
|
4796
|
-
// If no user ID, don't filter
|
4797
4745
|
patchState(store, { dashboards: allDashboards });
|
4798
4746
|
return;
|
4799
4747
|
}
|
4800
|
-
|
4801
|
-
|
4802
|
-
|
4803
|
-
// Admin sees only tenant-level dashboards
|
4804
|
-
filteredDashboards = allDashboards.filter((dashboard) => dashboard.scope === 'T');
|
4805
|
-
}
|
4806
|
-
else {
|
4807
|
-
// Regular users see:
|
4808
|
-
// 1. User-level dashboards they created
|
4809
|
-
// 2. Tenant-level dashboards where their role is included AND isDeleted is false/undefined
|
4810
|
-
filteredDashboards = allDashboards.filter((dashboard) => {
|
4811
|
-
// Check if this is a user-level dashboard created by this user
|
4748
|
+
const filteredDashboards = isAdmin
|
4749
|
+
? allDashboards.filter((dashboard) => dashboard.scope === 'T')
|
4750
|
+
: allDashboards.filter((dashboard) => {
|
4812
4751
|
const isUserDashboard = dashboard.scope === 'U' && dashboard.createdBy === userId;
|
4813
|
-
// Check if this is a tenant-level dashboard with user's role and is not deleted
|
4814
4752
|
const hasRoleIds = dashboard.roleIds && Array.isArray(dashboard.roleIds) && dashboard.roleIds.length > 0;
|
4815
4753
|
const isTenantDashboard = dashboard.scope === 'T';
|
4816
4754
|
const hasUserRole = userRole && hasRoleIds && dashboard.roleIds?.includes(userRole);
|
4817
|
-
const isNotDeleted = dashboard.isDeleted !== true;
|
4755
|
+
const isNotDeleted = dashboard.isDeleted !== true;
|
4818
4756
|
const isTenantDashboardWithRole = isTenantDashboard && hasUserRole && isNotDeleted;
|
4819
4757
|
return isUserDashboard || isTenantDashboardWithRole;
|
4820
4758
|
});
|
4821
|
-
}
|
4822
|
-
// Update dashboards state
|
4823
4759
|
patchState(store, { dashboards: filteredDashboards });
|
4824
|
-
// If current dashboard is not in filtered list, select the first one
|
4825
4760
|
if (filteredDashboards.length > 0 && !filteredDashboards.some((d) => d.id === store.currentDashboardId())) {
|
4826
4761
|
this.setCurrentDashboard(filteredDashboards[0].id);
|
4827
4762
|
}
|
4828
4763
|
},
|
4829
|
-
// Toggle lock state for the current dashboard
|
4830
4764
|
async toggleLockDashboard() {
|
4831
|
-
const currentDashboard = store.
|
4832
|
-
if (!currentDashboard)
|
4833
|
-
console.warn('No current dashboard selected');
|
4765
|
+
const currentDashboard = store.selectedDashboard();
|
4766
|
+
if (!currentDashboard)
|
4834
4767
|
return;
|
4835
|
-
}
|
4836
4768
|
try {
|
4837
|
-
|
4838
|
-
const isAdmin = store.isAdmin();
|
4769
|
+
const isAdmin = store.isUserAdmin();
|
4839
4770
|
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
4771
|
const canToggle = (!isAdmin && currentDashboard.scope === 'U' && currentDashboard.createdBy === userId) ||
|
4844
4772
|
(isAdmin && currentDashboard.scope === 'T');
|
4845
4773
|
if (!canToggle) {
|
4846
4774
|
console.warn('User does not have permission to toggle lock for this dashboard');
|
4847
4775
|
return;
|
4848
4776
|
}
|
4849
|
-
// Toggle the locked state
|
4850
4777
|
const newLockedState = !currentDashboard.locked;
|
4851
|
-
// Create an updated dashboard with toggled lock state
|
4852
4778
|
const updatedDashboard = {
|
4853
4779
|
...currentDashboard,
|
4854
4780
|
locked: newLockedState,
|
4855
4781
|
};
|
4856
|
-
// Save to service
|
4857
4782
|
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4858
|
-
// Update the dashboards in store
|
4859
4783
|
const updatedDashboards = store
|
4860
4784
|
.dashboards()
|
4861
4785
|
.map((dashboard) => (dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard));
|
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
4786
|
const baseOptions = { ...store.dashboardsOption() };
|
4865
|
-
|
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
|
4787
|
+
patchState(store, { dashboards: updatedDashboards });
|
4871
4788
|
const updatedOptions = {
|
4872
4789
|
...baseOptions,
|
4873
4790
|
disableDrag: newLockedState,
|
4874
4791
|
disableResize: newLockedState,
|
4875
4792
|
};
|
4876
|
-
|
4877
|
-
patchState(store, {
|
4878
|
-
dashboardsOption: updatedOptions,
|
4879
|
-
});
|
4793
|
+
patchState(store, { dashboardsOption: updatedOptions });
|
4880
4794
|
}
|
4881
4795
|
catch (error) {
|
4882
4796
|
console.error('Error toggling dashboard lock state:', error);
|
4883
4797
|
}
|
4884
4798
|
},
|
4885
|
-
// Check if dashboard is locked
|
4886
4799
|
isDashboardLocked() {
|
4887
|
-
const currentDashboard = store.
|
4800
|
+
const currentDashboard = store.selectedDashboard();
|
4888
4801
|
return currentDashboard?.locked === true;
|
4889
4802
|
},
|
4890
4803
|
};
|
@@ -4893,6 +4806,7 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4893
4806
|
class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
4894
4807
|
constructor() {
|
4895
4808
|
super(...arguments);
|
4809
|
+
// Dependencies
|
4896
4810
|
this.rootConfig = RootConfig;
|
4897
4811
|
this.activatedRoute = inject(ActivatedRoute);
|
4898
4812
|
this.dialogService = inject(AXDialogService);
|
@@ -4900,25 +4814,20 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4900
4814
|
this.router = inject(Router);
|
4901
4815
|
this.store = inject(AXMDashboardStore);
|
4902
4816
|
this.themeService = inject(AXPLayoutThemeService);
|
4903
|
-
|
4817
|
+
// Component State
|
4904
4818
|
this.context = signal({});
|
4905
4819
|
this.dashboardsLoaded = signal(false);
|
4906
|
-
|
4907
|
-
|
4820
|
+
// Effects
|
4821
|
+
this.#initEffect = effect(() => {
|
4822
|
+
const allDashboards = this.store.availableDashboards();
|
4908
4823
|
if (allDashboards.length > 0 && !this.dashboardsLoaded()) {
|
4909
4824
|
this.dashboardsLoaded.set(true);
|
4910
4825
|
this.applyDashboardFiltering();
|
4911
4826
|
this.recompute();
|
4912
4827
|
}
|
4913
4828
|
});
|
4914
|
-
this.#loadingEffect = effect(() => {
|
4915
|
-
const isLoading = this.store.isLoading();
|
4916
|
-
if (isLoading === false && this.dashboardsLoaded()) {
|
4917
|
-
this.recompute;
|
4918
|
-
setTimeout(() => this.recompute(), 0);
|
4919
|
-
}
|
4920
|
-
});
|
4921
4829
|
}
|
4830
|
+
// Lifecycle Hooks
|
4922
4831
|
async ngOnInit() {
|
4923
4832
|
const childRoute = this.activatedRoute.firstChild || this.activatedRoute;
|
4924
4833
|
childRoute.data.subscribe((data) => {
|
@@ -4926,13 +4835,11 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4926
4835
|
this.store.setIsAdmin(isAdmin);
|
4927
4836
|
});
|
4928
4837
|
}
|
4838
|
+
// Effects
|
4839
|
+
#initEffect;
|
4840
|
+
// Private Methods
|
4929
4841
|
applyDashboardFiltering() {
|
4930
|
-
this.store.filterDashboardsByScope(this.store.
|
4931
|
-
}
|
4932
|
-
#dashboardsEffect;
|
4933
|
-
#loadingEffect;
|
4934
|
-
toggleEdit() {
|
4935
|
-
this.isEdited.update((value) => !value);
|
4842
|
+
this.store.filterDashboardsByScope(this.store.isUserAdmin());
|
4936
4843
|
}
|
4937
4844
|
async confirmWidgetDelete(dashboardId, widgetId) {
|
4938
4845
|
try {
|
@@ -4945,23 +4852,21 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4945
4852
|
console.error('Error confirming widget deletion:', error);
|
4946
4853
|
}
|
4947
4854
|
}
|
4855
|
+
// Page Interface Implementation
|
4948
4856
|
getPageTitle() {
|
4949
|
-
return this.store.
|
4857
|
+
return this.store.selectedDashboard()?.title || 'Dashboard';
|
4950
4858
|
}
|
4951
4859
|
async getPageDescription() {
|
4952
|
-
return this.store.
|
4860
|
+
return this.store.selectedDashboard()?.description || '';
|
4953
4861
|
}
|
4954
4862
|
getTitleActions() {
|
4955
|
-
return
|
4956
|
-
|
4957
|
-
|
4958
|
-
|
4959
|
-
|
4960
|
-
})),
|
4961
|
-
];
|
4863
|
+
return this.store.dashboards().map((dashboard) => ({
|
4864
|
+
title: dashboard.title,
|
4865
|
+
command: { name: dashboard.id, metadata: { isDashboard: true, dashboard } },
|
4866
|
+
icon: dashboard.id === this.store.currentDashboardId() ? 'fa-solid fa-check' : '',
|
4867
|
+
}));
|
4962
4868
|
}
|
4963
4869
|
async getPrimaryMenuItems() {
|
4964
|
-
const scope = this.rootConfig.config.i18n;
|
4965
4870
|
return [
|
4966
4871
|
{
|
4967
4872
|
title: 't("add-item")',
|
@@ -4972,16 +4877,12 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4972
4877
|
title: await this.translateService.translateAsync('dashboard', { scope: 'dashboard' }),
|
4973
4878
|
icon: 'fa-light fa-gauge-high',
|
4974
4879
|
break: true,
|
4975
|
-
command: {
|
4976
|
-
name: 'new-dashboard',
|
4977
|
-
},
|
4880
|
+
command: { name: 'new-dashboard' },
|
4978
4881
|
},
|
4979
4882
|
{
|
4980
4883
|
title: await this.translateService.translateAsync('widget', { scope: 'dashboard' }),
|
4981
4884
|
icon: 'fa-light fa-window-restore',
|
4982
|
-
command: {
|
4983
|
-
name: 'new-widget',
|
4984
|
-
},
|
4885
|
+
command: { name: 'new-widget' },
|
4985
4886
|
disabled: this.store.dashboards().length < 1,
|
4986
4887
|
},
|
4987
4888
|
],
|
@@ -4989,19 +4890,16 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4989
4890
|
];
|
4990
4891
|
}
|
4991
4892
|
async getSecondaryMenuItems() {
|
4992
|
-
const scope = this.rootConfig.config.i18n;
|
4993
4893
|
const items = [
|
4994
4894
|
{
|
4995
|
-
title: await this.translateService.translateAsync('
|
4996
|
-
icon: 'fa-light fa-
|
4997
|
-
color: '
|
4895
|
+
title: await this.translateService.translateAsync('edit'),
|
4896
|
+
icon: 'fa-light fa-pen',
|
4897
|
+
color: 'primary',
|
4998
4898
|
disabled: this.store.dashboards().length < 1,
|
4999
|
-
command: {
|
5000
|
-
name: 'delete',
|
5001
|
-
},
|
4899
|
+
command: { name: 'edit' },
|
5002
4900
|
},
|
5003
4901
|
];
|
5004
|
-
if (!this.store.
|
4902
|
+
if (!this.store.isUserAdmin() && this.themeService.isDesktopDevice()) {
|
5005
4903
|
items.push({
|
5006
4904
|
title: await this.translateService.translateAsync(this.store.isDashboardLocked() ? 'unlock' : 'lock', {
|
5007
4905
|
scope: 'dashboard',
|
@@ -5009,43 +4907,48 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
5009
4907
|
icon: this.store.isDashboardLocked() ? 'fa-light fa-lock-open' : 'fa-light fa-lock',
|
5010
4908
|
color: 'accent3',
|
5011
4909
|
disabled: this.store.dashboards().length < 1,
|
5012
|
-
command: {
|
5013
|
-
name: 'toggle-lock',
|
5014
|
-
},
|
4910
|
+
command: { name: 'toggle-lock' },
|
5015
4911
|
});
|
5016
4912
|
}
|
4913
|
+
items.push({
|
4914
|
+
title: await this.translateService.translateAsync('delete'),
|
4915
|
+
icon: 'fa-light fa-trash-can',
|
4916
|
+
color: 'danger',
|
4917
|
+
disabled: this.store.dashboards().length < 1,
|
4918
|
+
command: { name: 'delete' },
|
4919
|
+
});
|
5017
4920
|
return items;
|
5018
4921
|
}
|
5019
4922
|
async execute(command) {
|
5020
4923
|
if (command.metadata?.['isDashboard']) {
|
5021
4924
|
this.store.handleConfigChange(command.metadata?.['dashboard']);
|
5022
4925
|
this.recompute();
|
4926
|
+
return;
|
5023
4927
|
}
|
5024
|
-
|
5025
|
-
|
5026
|
-
|
5027
|
-
|
5028
|
-
|
5029
|
-
|
5030
|
-
|
5031
|
-
|
5032
|
-
|
5033
|
-
|
5034
|
-
|
5035
|
-
|
5036
|
-
|
5037
|
-
|
5038
|
-
|
5039
|
-
|
5040
|
-
|
5041
|
-
|
5042
|
-
|
5043
|
-
|
5044
|
-
|
5045
|
-
|
5046
|
-
|
5047
|
-
|
5048
|
-
}
|
4928
|
+
switch (command.name) {
|
4929
|
+
case 'new-dashboard':
|
4930
|
+
await this.store.addDashboard();
|
4931
|
+
this.applyDashboardFiltering();
|
4932
|
+
this.recompute();
|
4933
|
+
break;
|
4934
|
+
case 'new-widget':
|
4935
|
+
await this.store.addWidget();
|
4936
|
+
this.recompute();
|
4937
|
+
break;
|
4938
|
+
case 'edit':
|
4939
|
+
await this.store.editDashboard();
|
4940
|
+
this.recompute();
|
4941
|
+
break;
|
4942
|
+
case 'delete':
|
4943
|
+
await this.store.removeDashboard(this.store.selectedDashboard()?.id);
|
4944
|
+
this.applyDashboardFiltering();
|
4945
|
+
this.recompute();
|
4946
|
+
break;
|
4947
|
+
case 'toggle-lock':
|
4948
|
+
await this.store.toggleLockDashboard();
|
4949
|
+
this.recompute();
|
4950
|
+
setTimeout(() => this.recompute(), 50);
|
4951
|
+
break;
|
5049
4952
|
}
|
5050
4953
|
}
|
5051
4954
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMDashboardHomeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
@@ -5056,7 +4959,7 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
5056
4959
|
provide: AXPBasePage,
|
5057
4960
|
useExisting: AXMDashboardHomeComponent,
|
5058
4961
|
},
|
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.
|
4962
|
+
], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n <!-- Content Section -->\n\n <axp-page-content class=\"ax-relative\">\n <!-- Loading State -->\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.currentLayoutOptions()\" (onChange)=\"store.onGridChange($event)\">\n <!-- No Dashboards State -->\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 }\n <!-- No Selected Dashboard State -->\n @else if (!store.selectedDashboard()) {\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 }\n <!-- No Widgets State -->\n @else if (!store.selectedDashboard()?.widgets || store.selectedDashboard()?.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 }\n <!-- Widgets Grid -->\n @else { @for(widget of store.selectedDashboard()?.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.selectedDashboard()?.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 }); }
|
5060
4963
|
}
|
5061
4964
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMDashboardHomeComponent, decorators: [{
|
5062
4965
|
type: Component,
|
@@ -5082,7 +4985,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
5082
4985
|
provide: AXPBasePage,
|
5083
4986
|
useExisting: AXMDashboardHomeComponent,
|
5084
4987
|
},
|
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.
|
4988
|
+
], template: "<axp-page-layout *translate=\"let t\">\n <!-- Content Section -->\n\n <axp-page-content class=\"ax-relative\">\n <!-- Loading State -->\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.currentLayoutOptions()\" (onChange)=\"store.onGridChange($event)\">\n <!-- No Dashboards State -->\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 }\n <!-- No Selected Dashboard State -->\n @else if (!store.selectedDashboard()) {\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 }\n <!-- No Widgets State -->\n @else if (!store.selectedDashboard()?.widgets || store.selectedDashboard()?.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 }\n <!-- Widgets Grid -->\n @else { @for(widget of store.selectedDashboard()?.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.selectedDashboard()?.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"] }]
|
5086
4989
|
}] });
|
5087
4990
|
|
5088
4991
|
var homeDashboard = /*#__PURE__*/Object.freeze({
|