@acorex/modules 19.3.5 → 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 +40 -9
- 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/home-dashboard/dashboard-popups/dashboard-popup.service.d.ts +1 -0
- package/dashboard-management/lib/features/home-dashboard/widget-wrapper/dashboard-widget-wrapper.d.ts +2 -1
- package/dashboard-management/lib/features/shared/widgets/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/dashboard-management/lib/features/shared/widgets/weather/weather-widget.component.d.ts +5 -0
- package/fesm2022/{acorex-modules-auth-acorex-modules-auth-VeeGJcyl.mjs → acorex-modules-auth-acorex-modules-auth-bj5xztse.mjs} +9 -9
- package/fesm2022/{acorex-modules-auth-acorex-modules-auth-VeeGJcyl.mjs.map → acorex-modules-auth-acorex-modules-auth-bj5xztse.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-app-chooser.component-IhAQfHJU.mjs → acorex-modules-auth-app-chooser.component-BOL3VzC1.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-app-chooser.component-IhAQfHJU.mjs.map → acorex-modules-auth-app-chooser.component-BOL3VzC1.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-login.module-B8qqaCq8.mjs → acorex-modules-auth-login.module-C1AoXhCI.mjs} +4 -4
- package/fesm2022/{acorex-modules-auth-login.module-B8qqaCq8.mjs.map → acorex-modules-auth-login.module-C1AoXhCI.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-master.layout-egA9357P.mjs → acorex-modules-auth-master.layout-vuHfrDxu.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-master.layout-egA9357P.mjs.map → acorex-modules-auth-master.layout-vuHfrDxu.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-BimdcHXP.mjs → acorex-modules-auth-password.component-C71v2x71.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-BimdcHXP.mjs.map → acorex-modules-auth-password.component-C71v2x71.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-BMWDHmu6.mjs → acorex-modules-auth-password.component-Dtcz95NV.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-BMWDHmu6.mjs.map → acorex-modules-auth-password.component-Dtcz95NV.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-routes-BYT58dkA.mjs → acorex-modules-auth-routes-lJgHFaQR.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-routes-BYT58dkA.mjs.map → acorex-modules-auth-routes-lJgHFaQR.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-two-factor.module-B_g4P4is.mjs → acorex-modules-auth-two-factor.module-C9SfEHF7.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-two-factor.module-B_g4P4is.mjs.map → acorex-modules-auth-two-factor.module-C9SfEHF7.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-user-sessions.component-DvYAh9cg.mjs → acorex-modules-auth-user-sessions.component-CCsoLecU.mjs} +4 -4
- package/fesm2022/acorex-modules-auth-user-sessions.component-CCsoLecU.mjs.map +1 -0
- package/fesm2022/acorex-modules-auth.mjs +1 -1
- package/fesm2022/acorex-modules-dashboard-management.mjs +1308 -1302
- package/fesm2022/acorex-modules-dashboard-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-notification-management.mjs +11 -11
- package/fesm2022/acorex-modules-notification-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-security-management.mjs +1 -1
- package/fesm2022/acorex-modules-security-management.mjs.map +1 -1
- package/package.json +9 -9
- package/fesm2022/acorex-modules-auth-user-sessions.component-DvYAh9cg.mjs.map +0 -1
@@ -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';
|
@@ -38,14 +38,14 @@ import { AXCheckBoxModule } from '@acorex/components/check-box';
|
|
38
38
|
import { AXImageModule } from '@acorex/components/image';
|
39
39
|
import { AXLabelModule } from '@acorex/components/label';
|
40
40
|
import { AXTabsModule } from '@acorex/components/tabs';
|
41
|
-
import * as
|
41
|
+
import * as i2$3 from '@acorex/core/translation';
|
42
42
|
import { AXTranslationModule, AXTranslationService } from '@acorex/core/translation';
|
43
43
|
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
44
44
|
import { AXPopupService } from '@acorex/components/popup';
|
45
45
|
import { AXP_GLOBAL_SEARCH_CONFIG_TOKEN } from '@acorex/modules/common';
|
46
46
|
import { AXPDataGenerator, AXPPlatformScope } from '@acorex/platform/core';
|
47
47
|
import { AXPWorkflowService } from '@acorex/platform/workflow';
|
48
|
-
import {
|
48
|
+
import { ActivatedRoute, Router } from '@angular/router';
|
49
49
|
import { AXBreadcrumbsModule } from '@acorex/components/breadcrumbs';
|
50
50
|
import { AXButtonGroupModule } from '@acorex/components/button-group';
|
51
51
|
import { AXDialogService } from '@acorex/components/dialog';
|
@@ -55,12 +55,14 @@ import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
|
|
55
55
|
import { AXPWidgetPropertyViewerComponent, AXPWidgetPickerService, AXPDesignerService } from '@acorex/platform/layout/designer';
|
56
56
|
import { AXPBasePageComponent, AXPPageLayoutComponent, AXPBasePage } from '@acorex/platform/themes/default';
|
57
57
|
import { AXPLayoutThemeService, AXPThemeLayoutBlockComponent } from '@acorex/platform/themes/shared';
|
58
|
-
import * as i2$
|
58
|
+
import * as i2$4 from '@acorex/components/loading';
|
59
59
|
import { AXLoadingModule } from '@acorex/components/loading';
|
60
60
|
import { signalStore, withState, withComputed, withMethods, patchState } from '@ngrx/signals';
|
61
61
|
import { AXBasePageComponent } from '@acorex/components/page';
|
62
62
|
import * as i7 from '@acorex/components/select-box';
|
63
63
|
import { AXSelectBoxModule } from '@acorex/components/select-box';
|
64
|
+
import * as i8 from '@acorex/components/switch';
|
65
|
+
import { AXSwitchModule } from '@acorex/components/switch';
|
64
66
|
import * as i3$3 from '@acorex/components/text-box';
|
65
67
|
import { AXTextBoxModule } from '@acorex/components/text-box';
|
66
68
|
import { AXMOrganizationManagementRoleEntityService } from '@acorex/modules/organization-management';
|
@@ -452,20 +454,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
452
454
|
*/
|
453
455
|
class AXPBarChartWidgetViewComponent extends AXPValueWidgetComponent {
|
454
456
|
constructor() {
|
455
|
-
super(
|
457
|
+
super();
|
456
458
|
this.barChartData = computed(() => this.getValue());
|
457
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
|
+
});
|
458
472
|
}
|
459
473
|
handleBarClick(event) {
|
460
474
|
//console.log(event);
|
461
475
|
}
|
462
|
-
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 }); }
|
463
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 }); }
|
464
478
|
}
|
465
479
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPBarChartWidgetViewComponent, decorators: [{
|
466
480
|
type: Component,
|
467
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"] }]
|
468
|
-
}] });
|
482
|
+
}], ctorParameters: () => [] });
|
469
483
|
|
470
484
|
var barChartWidget_component = /*#__PURE__*/Object.freeze({
|
471
485
|
__proto__: null,
|
@@ -496,7 +510,7 @@ const AXPBarChartWidget = {
|
|
496
510
|
// ====== Chart Title ======
|
497
511
|
{
|
498
512
|
name: 'title',
|
499
|
-
title: '
|
513
|
+
title: '@dashboard:widgets.bar-chart.chart-title',
|
500
514
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
501
515
|
schema: {
|
502
516
|
defaultValue: '',
|
@@ -512,64 +526,10 @@ const AXPBarChartWidget = {
|
|
512
526
|
},
|
513
527
|
visible: true,
|
514
528
|
},
|
515
|
-
// ====== Layout & Dimensions ======
|
516
|
-
{
|
517
|
-
name: 'width',
|
518
|
-
title: 'Width',
|
519
|
-
group: AXP_STYLING_PROPERTY_GROUP,
|
520
|
-
schema: {
|
521
|
-
defaultValue: null,
|
522
|
-
dataType: 'number',
|
523
|
-
interface: {
|
524
|
-
name: 'width',
|
525
|
-
path: 'options.width',
|
526
|
-
type: AXPWidgetsCatalog.number,
|
527
|
-
options: {
|
528
|
-
minValue: 0,
|
529
|
-
maxValue: 1200,
|
530
|
-
},
|
531
|
-
},
|
532
|
-
},
|
533
|
-
visible: true,
|
534
|
-
},
|
535
|
-
{
|
536
|
-
name: 'height',
|
537
|
-
title: 'Height',
|
538
|
-
group: AXP_STYLING_PROPERTY_GROUP,
|
539
|
-
schema: {
|
540
|
-
defaultValue: 300,
|
541
|
-
dataType: 'number',
|
542
|
-
interface: {
|
543
|
-
name: 'height',
|
544
|
-
path: 'options.height',
|
545
|
-
type: AXPWidgetsCatalog.number,
|
546
|
-
options: {
|
547
|
-
minValue: 0,
|
548
|
-
maxValue: 800,
|
549
|
-
},
|
550
|
-
},
|
551
|
-
},
|
552
|
-
visible: true,
|
553
|
-
},
|
554
529
|
// ====== X Axis Settings ======
|
555
|
-
{
|
556
|
-
name: 'showXAxis',
|
557
|
-
title: 'Show X Axis',
|
558
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
559
|
-
schema: {
|
560
|
-
defaultValue: true,
|
561
|
-
dataType: 'boolean',
|
562
|
-
interface: {
|
563
|
-
name: 'showXAxis',
|
564
|
-
path: 'options.showXAxis',
|
565
|
-
type: AXPWidgetsCatalog.toggle,
|
566
|
-
},
|
567
|
-
},
|
568
|
-
visible: true,
|
569
|
-
},
|
570
530
|
{
|
571
531
|
name: 'xAxisLabel',
|
572
|
-
title: '
|
532
|
+
title: '@dashboard:widgets.bar-chart.x-axis-label',
|
573
533
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
574
534
|
schema: {
|
575
535
|
defaultValue: '',
|
@@ -583,24 +543,9 @@ const AXPBarChartWidget = {
|
|
583
543
|
visible: true,
|
584
544
|
},
|
585
545
|
// ====== Y Axis Settings ======
|
586
|
-
{
|
587
|
-
name: 'showYAxis',
|
588
|
-
title: 'Show Y Axis',
|
589
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
590
|
-
schema: {
|
591
|
-
defaultValue: true,
|
592
|
-
dataType: 'boolean',
|
593
|
-
interface: {
|
594
|
-
name: 'showYAxis',
|
595
|
-
path: 'options.showYAxis',
|
596
|
-
type: AXPWidgetsCatalog.toggle,
|
597
|
-
},
|
598
|
-
},
|
599
|
-
visible: true,
|
600
|
-
},
|
601
546
|
{
|
602
547
|
name: 'yAxisLabel',
|
603
|
-
title: '
|
548
|
+
title: '@dashboard:widgets.bar-chart.y-axis-label',
|
604
549
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
605
550
|
schema: {
|
606
551
|
defaultValue: '',
|
@@ -613,145 +558,218 @@ const AXPBarChartWidget = {
|
|
613
558
|
},
|
614
559
|
visible: true,
|
615
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
|
+
},
|
616
633
|
// ====== Bar Appearance ======
|
617
634
|
{
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
},
|
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
|
+
},
|
634
650
|
},
|
635
|
-
|
651
|
+
},
|
652
|
+
visible: true,
|
636
653
|
},
|
637
654
|
{
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
},
|
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
|
+
},
|
654
670
|
},
|
655
|
-
|
671
|
+
},
|
672
|
+
visible: true,
|
656
673
|
},
|
657
674
|
// ====== Grid Settings ======
|
658
675
|
{
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
},
|
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,
|
670
686
|
},
|
671
|
-
|
687
|
+
},
|
688
|
+
visible: true,
|
672
689
|
},
|
673
690
|
{
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
},
|
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,
|
685
701
|
},
|
686
|
-
|
702
|
+
},
|
703
|
+
visible: true,
|
687
704
|
},
|
688
705
|
// ====== Tooltip Settings ======
|
689
706
|
{
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
},
|
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,
|
701
717
|
},
|
702
|
-
|
718
|
+
},
|
719
|
+
visible: true,
|
703
720
|
},
|
704
721
|
// ====== Animation Settings ======
|
705
722
|
{
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
},
|
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
|
+
},
|
732
748
|
},
|
733
|
-
|
749
|
+
},
|
750
|
+
visible: true,
|
734
751
|
},
|
735
752
|
{
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
},
|
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
|
+
},
|
752
768
|
},
|
753
|
-
|
769
|
+
},
|
770
|
+
visible: true,
|
754
771
|
},
|
772
|
+
*/
|
755
773
|
],
|
756
774
|
components: {
|
757
775
|
view: {
|
@@ -803,7 +821,7 @@ class AXPClockCalendarWidgetViewComponent extends AXPValueWidgetComponent {
|
|
803
821
|
this.showDayOfWeek = computed(() => this.options()?.showDayOfWeek !== false);
|
804
822
|
this.use24Hour = computed(() => this.options()?.use24Hour === true);
|
805
823
|
this.showSeconds = computed(() => this.options()?.showSeconds !== false);
|
806
|
-
this.dateFormat = computed(() => this.options()?.dateFormat?.id ?? '
|
824
|
+
this.dateFormat = computed(() => this.options()?.dateFormat?.id ?? 'DD MMM YYYY');
|
807
825
|
this.timezone = computed(() => this.options()?.timezone?.id ?? 'local');
|
808
826
|
// protected readonly showTimezoneIndicator: Signal<boolean> = computed(() => this.timezone() !== 'local');
|
809
827
|
this.displayTimezone = computed(() => {
|
@@ -893,11 +911,11 @@ class AXPClockCalendarWidgetViewComponent extends AXPValueWidgetComponent {
|
|
893
911
|
return days[this.currentDate.getDay()];
|
894
912
|
}
|
895
913
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPClockCalendarWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
896
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPClockCalendarWidgetViewComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"axp-clock-calendar-container\">\n <!-- Timezone indicator (only shown when not local) -->\n <!-- @if (showTimezoneIndicator()) {\n <div class=\"axp-clock-calendar-timezone-badge\"><i class=\"fa-solid fa-globe\"></i> {{ displayTimezone() }}</div>\n } -->\n\n <!-- Day of week display -->\n @if (showDayOfWeek()) {\n
|
914
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPClockCalendarWidgetViewComponent, isStandalone: true, selector: "ng-component", usesInheritance: true, ngImport: i0, template: "<div class=\"axp-clock-calendar-container\">\n <!-- Timezone indicator (only shown when not local) -->\n <!-- @if (showTimezoneIndicator()) {\n <div class=\"axp-clock-calendar-timezone-badge\"><i class=\"fa-solid fa-globe\"></i> {{ displayTimezone() }}</div>\n } -->\n\n <!-- Day of week display -->\n @if (showDayOfWeek()) {\n <div class=\"axp-clock-calendar-day-label\">{{ getDayOfWeek() }}</div>\n }\n\n <div class=\"axp-clock-calendar-content\">\n <!-- Digital Clock Display -->\n @if (showDigitalClock()) {\n <div class=\"axp-clock-calendar-digital-clock\">\n {{ currentTime | format: 'datetime' : timeFormat() | async }}\n </div>\n }\n\n <!-- Analog Clock Display -->\n @if (showAnalogClock()) {\n <div class=\"axp-clock-calendar-analog-clock\">\n <!-- Hour markers -->\n @for (hour of clockHours; track hour) {\n <div\n class=\"axp-clock-calendar-hour-marker\"\n [style.transform]=\"'rotate(' + hour * 30 + 'deg) translateY(-80px)'\"\n ></div>\n }\n\n <!-- Clock Numbers -->\n <div class=\"axp-clock-calendar-numbers-container\">\n @for (hour of clockHourNumbers; track hour) {\n <div\n class=\"axp-clock-calendar-hour-number\"\n [style.transform]=\"'rotate(' + hour.angle + 'deg) translateY(-82px)'\"\n >\n <span [style.transform]=\"'rotate(' + -hour.angle + 'deg)'\">{{ hour.number }}</span>\n </div>\n }\n </div>\n\n <!-- Clock Hands -->\n <div class=\"axp-clock-calendar-hands-container\">\n <div class=\"axp-clock-calendar-hour-hand\" [style.transform]=\"'rotate(' + hourRotation + 'deg)'\"></div>\n <div class=\"axp-clock-calendar-minute-hand\" [style.transform]=\"'rotate(' + minuteRotation + 'deg)'\"></div>\n @if (showSeconds()) {\n <div class=\"axp-clock-calendar-second-hand\" [style.transform]=\"'rotate(' + secondRotation + 'deg)'\"></div>\n }\n <div class=\"axp-clock-calendar-center-dot\"></div>\n </div>\n </div>\n }\n\n <!-- Date Display -->\n @if (showDate()) {\n <div class=\"axp-clock-calendar-date-display\">\n <i class=\"fa-regular fa-calendar\"></i>\n {{ currentDate | format: 'datetime' : dateFormat() | async }}\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%;height:100%}.axp-clock-calendar-container{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;padding:1rem;position:relative;overflow:hidden;box-shadow:var(--ax-shadow-sm);background-color:var(--ax-surface-color);color:var(--ax-text-color)}.axp-clock-calendar-content{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;width:100%;height:100%;position:relative}.axp-clock-calendar-timezone-badge{position:absolute;top:.5rem;right:.5rem;font-size:.75rem;padding:.25rem;border-radius:1rem;border-width:1px;border-color:rgba(23,23,23,.5)}.axp-clock-calendar-timezone-badge:is(.ax-dark *){border-color:rgba(245,245,245,.5)}.axp-clock-calendar-timezone-badge{display:flex;align-items:center;gap:.25rem}.axp-clock-calendar-timezone-badge i{font-size:.75rem}.axp-clock-calendar-day-label{font-size:.9rem;font-weight:600;text-transform:uppercase;letter-spacing:.05rem;margin-bottom:.25rem}.axp-clock-calendar-digital-clock{font-size:1.5rem;font-weight:500;letter-spacing:.05rem;font-family:monospace;padding:.5rem .75rem;border-radius:.25rem}.axp-clock-calendar-analog-clock{position:relative;border-radius:50%;border-width:1px;border-color:rgba(23,23,23,.5)}.axp-clock-calendar-analog-clock:is(.ax-dark *){border-color:rgba(245,245,245,.5)}.axp-clock-calendar-analog-clock{display:flex;align-items:center;justify-content:center;background:var(--ax-surface-color);width:min(180px,100%);height:0;padding-bottom:min(180px,100%);margin:.5rem auto;min-width:120px;min-height:120px;box-shadow:var(--ax-shadow-sm)}.axp-clock-calendar-hands-container,.axp-clock-calendar-numbers-container{position:absolute;top:0;left:0;width:100%;height:100%;border-radius:50%}.axp-clock-calendar-hour-marker{position:absolute;left:50%;top:50%;width:2px;height:4%;margin-left:-1px;border-radius:1px;background-color:var(--ax-text-muted);transform-origin:50% 0}.axp-clock-calendar-hour-number{position:absolute;left:50%;top:50%;transform-origin:50% 0;font-size:clamp(.7rem,2.5vw,.9rem);font-weight:600;color:var(--ax-text-color)}.axp-clock-calendar-hour-number span{display:block}.axp-clock-calendar-hour-hand{position:absolute;top:50%;left:50%;width:4px;height:25%;margin-left:-2px;background-color:rgba(23,23,23,.75)}.axp-clock-calendar-hour-hand:is(.ax-dark *){background-color:rgba(245,245,245,.75)}.axp-clock-calendar-hour-hand{transform-origin:50% 0;border-radius:3px;box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-minute-hand{position:absolute;top:50%;left:50%;width:3px;height:38%;margin-left:-1.5px;background-color:rgba(23,23,23,.5)}.axp-clock-calendar-minute-hand:is(.ax-dark *){background-color:rgba(245,245,245,.5)}.axp-clock-calendar-minute-hand{transform-origin:50% 0;border-radius:2px;box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-second-hand{position:absolute;top:50%;left:50%;width:2px;height:42%;margin-left:-1px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-500),var(--tw-bg-opacity, 1))}.axp-clock-calendar-second-hand:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-400),var(--tw-bg-opacity, 1))}.axp-clock-calendar-second-hand{transform-origin:50% 0;border-radius:1px;box-shadow:0 0 3px rgba(0,0,0,.2)}.axp-clock-calendar-center-dot{position:absolute;top:50%;left:50%;width:10px;height:10px;border-radius:50%;margin-top:-5px;margin-left:-5px;background-color:#d81159;border:2px solid var(--ax-surface-color);box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-date-display{display:flex;align-items:center;gap:.5rem;font-size:.85rem;padding:.25rem .6rem;border-radius:.25rem;background-color:var(--ax-surface-hover);color:var(--ax-text-color)}.axp-clock-calendar-date-display i{font-size:.85rem;opacity:.7}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXDateTimeModule }, { kind: "ngmodule", type: AXFormatModule }, { kind: "pipe", type: i2.AXFormatPipe, name: "format" }, { kind: "ngmodule", type: AXTagModule }, { kind: "ngmodule", type: AXDecoratorModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
897
915
|
}
|
898
916
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPClockCalendarWidgetViewComponent, decorators: [{
|
899
917
|
type: Component,
|
900
|
-
args: [{ standalone: true, imports: [CommonModule, AXDateTimeModule, AXFormatModule, AXTagModule, AXDecoratorModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axp-clock-calendar-container\">\n <!-- Timezone indicator (only shown when not local) -->\n <!-- @if (showTimezoneIndicator()) {\n <div class=\"axp-clock-calendar-timezone-badge\"><i class=\"fa-solid fa-globe\"></i> {{ displayTimezone() }}</div>\n } -->\n\n <!-- Day of week display -->\n @if (showDayOfWeek()) {\n
|
918
|
+
args: [{ standalone: true, imports: [CommonModule, AXDateTimeModule, AXFormatModule, AXTagModule, AXDecoratorModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"axp-clock-calendar-container\">\n <!-- Timezone indicator (only shown when not local) -->\n <!-- @if (showTimezoneIndicator()) {\n <div class=\"axp-clock-calendar-timezone-badge\"><i class=\"fa-solid fa-globe\"></i> {{ displayTimezone() }}</div>\n } -->\n\n <!-- Day of week display -->\n @if (showDayOfWeek()) {\n <div class=\"axp-clock-calendar-day-label\">{{ getDayOfWeek() }}</div>\n }\n\n <div class=\"axp-clock-calendar-content\">\n <!-- Digital Clock Display -->\n @if (showDigitalClock()) {\n <div class=\"axp-clock-calendar-digital-clock\">\n {{ currentTime | format: 'datetime' : timeFormat() | async }}\n </div>\n }\n\n <!-- Analog Clock Display -->\n @if (showAnalogClock()) {\n <div class=\"axp-clock-calendar-analog-clock\">\n <!-- Hour markers -->\n @for (hour of clockHours; track hour) {\n <div\n class=\"axp-clock-calendar-hour-marker\"\n [style.transform]=\"'rotate(' + hour * 30 + 'deg) translateY(-80px)'\"\n ></div>\n }\n\n <!-- Clock Numbers -->\n <div class=\"axp-clock-calendar-numbers-container\">\n @for (hour of clockHourNumbers; track hour) {\n <div\n class=\"axp-clock-calendar-hour-number\"\n [style.transform]=\"'rotate(' + hour.angle + 'deg) translateY(-82px)'\"\n >\n <span [style.transform]=\"'rotate(' + -hour.angle + 'deg)'\">{{ hour.number }}</span>\n </div>\n }\n </div>\n\n <!-- Clock Hands -->\n <div class=\"axp-clock-calendar-hands-container\">\n <div class=\"axp-clock-calendar-hour-hand\" [style.transform]=\"'rotate(' + hourRotation + 'deg)'\"></div>\n <div class=\"axp-clock-calendar-minute-hand\" [style.transform]=\"'rotate(' + minuteRotation + 'deg)'\"></div>\n @if (showSeconds()) {\n <div class=\"axp-clock-calendar-second-hand\" [style.transform]=\"'rotate(' + secondRotation + 'deg)'\"></div>\n }\n <div class=\"axp-clock-calendar-center-dot\"></div>\n </div>\n </div>\n }\n\n <!-- Date Display -->\n @if (showDate()) {\n <div class=\"axp-clock-calendar-date-display\">\n <i class=\"fa-regular fa-calendar\"></i>\n {{ currentDate | format: 'datetime' : dateFormat() | async }}\n </div>\n }\n </div>\n</div>\n", styles: [":host{display:block;width:100%;height:100%}.axp-clock-calendar-container{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;padding:1rem;position:relative;overflow:hidden;box-shadow:var(--ax-shadow-sm);background-color:var(--ax-surface-color);color:var(--ax-text-color)}.axp-clock-calendar-content{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;width:100%;height:100%;position:relative}.axp-clock-calendar-timezone-badge{position:absolute;top:.5rem;right:.5rem;font-size:.75rem;padding:.25rem;border-radius:1rem;border-width:1px;border-color:rgba(23,23,23,.5)}.axp-clock-calendar-timezone-badge:is(.ax-dark *){border-color:rgba(245,245,245,.5)}.axp-clock-calendar-timezone-badge{display:flex;align-items:center;gap:.25rem}.axp-clock-calendar-timezone-badge i{font-size:.75rem}.axp-clock-calendar-day-label{font-size:.9rem;font-weight:600;text-transform:uppercase;letter-spacing:.05rem;margin-bottom:.25rem}.axp-clock-calendar-digital-clock{font-size:1.5rem;font-weight:500;letter-spacing:.05rem;font-family:monospace;padding:.5rem .75rem;border-radius:.25rem}.axp-clock-calendar-analog-clock{position:relative;border-radius:50%;border-width:1px;border-color:rgba(23,23,23,.5)}.axp-clock-calendar-analog-clock:is(.ax-dark *){border-color:rgba(245,245,245,.5)}.axp-clock-calendar-analog-clock{display:flex;align-items:center;justify-content:center;background:var(--ax-surface-color);width:min(180px,100%);height:0;padding-bottom:min(180px,100%);margin:.5rem auto;min-width:120px;min-height:120px;box-shadow:var(--ax-shadow-sm)}.axp-clock-calendar-hands-container,.axp-clock-calendar-numbers-container{position:absolute;top:0;left:0;width:100%;height:100%;border-radius:50%}.axp-clock-calendar-hour-marker{position:absolute;left:50%;top:50%;width:2px;height:4%;margin-left:-1px;border-radius:1px;background-color:var(--ax-text-muted);transform-origin:50% 0}.axp-clock-calendar-hour-number{position:absolute;left:50%;top:50%;transform-origin:50% 0;font-size:clamp(.7rem,2.5vw,.9rem);font-weight:600;color:var(--ax-text-color)}.axp-clock-calendar-hour-number span{display:block}.axp-clock-calendar-hour-hand{position:absolute;top:50%;left:50%;width:4px;height:25%;margin-left:-2px;background-color:rgba(23,23,23,.75)}.axp-clock-calendar-hour-hand:is(.ax-dark *){background-color:rgba(245,245,245,.75)}.axp-clock-calendar-hour-hand{transform-origin:50% 0;border-radius:3px;box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-minute-hand{position:absolute;top:50%;left:50%;width:3px;height:38%;margin-left:-1.5px;background-color:rgba(23,23,23,.5)}.axp-clock-calendar-minute-hand:is(.ax-dark *){background-color:rgba(245,245,245,.5)}.axp-clock-calendar-minute-hand{transform-origin:50% 0;border-radius:2px;box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-second-hand{position:absolute;top:50%;left:50%;width:2px;height:42%;margin-left:-1px;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-500),var(--tw-bg-opacity, 1))}.axp-clock-calendar-second-hand:is(.ax-dark *){--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-danger-400),var(--tw-bg-opacity, 1))}.axp-clock-calendar-second-hand{transform-origin:50% 0;border-radius:1px;box-shadow:0 0 3px rgba(0,0,0,.2)}.axp-clock-calendar-center-dot{position:absolute;top:50%;left:50%;width:10px;height:10px;border-radius:50%;margin-top:-5px;margin-left:-5px;background-color:#d81159;border:2px solid var(--ax-surface-color);box-shadow:0 0 4px rgba(0,0,0,.3)}.axp-clock-calendar-date-display{display:flex;align-items:center;gap:.5rem;font-size:.85rem;padding:.25rem .6rem;border-radius:.25rem;background-color:var(--ax-surface-hover);color:var(--ax-text-color)}.axp-clock-calendar-date-display i{font-size:.85rem;opacity:.7}\n"] }]
|
901
919
|
}] });
|
902
920
|
|
903
921
|
var clockCalendarWidget_component = /*#__PURE__*/Object.freeze({
|
@@ -932,10 +950,10 @@ const AXP_TIMEZONE_OPTIONS = [
|
|
932
950
|
* Common date format options for the widget configuration
|
933
951
|
*/
|
934
952
|
const AXP_DATE_FORMAT_OPTIONS = [
|
935
|
-
{ id: '
|
936
|
-
{ id: 'MMM
|
937
|
-
{ id: '
|
938
|
-
{ id: 'MM/
|
953
|
+
{ id: 'DD MMM YYYY', title: '31 Dec 2023' },
|
954
|
+
{ id: 'MMM DD, YYYY', title: 'Dec 31, 2023' },
|
955
|
+
{ id: 'DD/MM/YYYY', title: '31/12/2023' },
|
956
|
+
{ id: 'MM/DD/YYYY', title: '12/31/2023' },
|
939
957
|
];
|
940
958
|
|
941
959
|
const AXPClockCalendarWidget = {
|
@@ -949,7 +967,7 @@ const AXPClockCalendarWidget = {
|
|
949
967
|
// ====== Title ======
|
950
968
|
{
|
951
969
|
name: 'title',
|
952
|
-
title: '
|
970
|
+
title: '@dashboard:widgets.clock-calendar.chart-title',
|
953
971
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
954
972
|
schema: {
|
955
973
|
defaultValue: '',
|
@@ -968,7 +986,7 @@ const AXPClockCalendarWidget = {
|
|
968
986
|
// ====== Display Settings ======
|
969
987
|
{
|
970
988
|
name: 'displayLayout',
|
971
|
-
title: '
|
989
|
+
title: '@dashboard:widgets.clock-calendar.display-layout',
|
972
990
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
973
991
|
schema: {
|
974
992
|
dataType: 'string',
|
@@ -990,7 +1008,7 @@ const AXPClockCalendarWidget = {
|
|
990
1008
|
},
|
991
1009
|
{
|
992
1010
|
name: 'showDate',
|
993
|
-
title: '
|
1011
|
+
title: '@dashboard:widgets.clock-calendar.show-date',
|
994
1012
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
995
1013
|
schema: {
|
996
1014
|
defaultValue: true,
|
@@ -1005,7 +1023,7 @@ const AXPClockCalendarWidget = {
|
|
1005
1023
|
},
|
1006
1024
|
{
|
1007
1025
|
name: 'showDayOfWeek',
|
1008
|
-
title: '
|
1026
|
+
title: '@dashboard:widgets.clock-calendar.show-day-of-week',
|
1009
1027
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1010
1028
|
schema: {
|
1011
1029
|
defaultValue: true,
|
@@ -1021,7 +1039,7 @@ const AXPClockCalendarWidget = {
|
|
1021
1039
|
// ====== Time Format Settings ======
|
1022
1040
|
{
|
1023
1041
|
name: 'use24Hour',
|
1024
|
-
title: '
|
1042
|
+
title: '@dashboard:widgets.clock-calendar.use-24-hour',
|
1025
1043
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
1026
1044
|
schema: {
|
1027
1045
|
defaultValue: false,
|
@@ -1036,7 +1054,7 @@ const AXPClockCalendarWidget = {
|
|
1036
1054
|
},
|
1037
1055
|
{
|
1038
1056
|
name: 'showSeconds',
|
1039
|
-
title: '
|
1057
|
+
title: '@dashboard:widgets.clock-calendar.show-seconds',
|
1040
1058
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
1041
1059
|
schema: {
|
1042
1060
|
defaultValue: true,
|
@@ -1066,10 +1084,10 @@ const AXPClockCalendarWidget = {
|
|
1066
1084
|
// },
|
1067
1085
|
{
|
1068
1086
|
name: 'dateFormat',
|
1069
|
-
title: '
|
1087
|
+
title: '@dashboard:widgets.clock-calendar.date-format',
|
1070
1088
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
1071
1089
|
schema: {
|
1072
|
-
defaultValue: '
|
1090
|
+
defaultValue: 'DD MMM YYYY',
|
1073
1091
|
dataType: 'string',
|
1074
1092
|
interface: {
|
1075
1093
|
name: 'dateFormat',
|
@@ -1084,7 +1102,7 @@ const AXPClockCalendarWidget = {
|
|
1084
1102
|
},
|
1085
1103
|
{
|
1086
1104
|
name: 'timezone',
|
1087
|
-
title: '
|
1105
|
+
title: '@dashboard:widgets.clock-calendar.timezone',
|
1088
1106
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
1089
1107
|
schema: {
|
1090
1108
|
defaultValue: 'local',
|
@@ -1124,20 +1142,31 @@ const AXPClockCalendarWidget = {
|
|
1124
1142
|
*/
|
1125
1143
|
class AXPDonutChartWidgetViewComponent extends AXPValueWidgetComponent {
|
1126
1144
|
constructor() {
|
1127
|
-
super(
|
1145
|
+
super();
|
1128
1146
|
this.donutChartData = computed(() => this.getValue());
|
1129
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
|
+
});
|
1130
1159
|
}
|
1131
1160
|
handleDonutChartSegmentClick(event) {
|
1132
1161
|
//console.log(event);
|
1133
1162
|
}
|
1134
|
-
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 }); }
|
1135
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 }); }
|
1136
1165
|
}
|
1137
1166
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPDonutChartWidgetViewComponent, decorators: [{
|
1138
1167
|
type: Component,
|
1139
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"] }]
|
1140
|
-
}] });
|
1169
|
+
}], ctorParameters: () => [] });
|
1141
1170
|
|
1142
1171
|
var donutChartWidget_component = /*#__PURE__*/Object.freeze({
|
1143
1172
|
__proto__: null,
|
@@ -1157,7 +1186,7 @@ const AXPDonutChartWidget = {
|
|
1157
1186
|
// ====== Chart Title ======
|
1158
1187
|
{
|
1159
1188
|
name: 'title',
|
1160
|
-
title: '
|
1189
|
+
title: '@dashboard:widgets.donut-chart.chart-title',
|
1161
1190
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1162
1191
|
schema: {
|
1163
1192
|
defaultValue: '',
|
@@ -1173,100 +1202,101 @@ const AXPDonutChartWidget = {
|
|
1173
1202
|
},
|
1174
1203
|
visible: true,
|
1175
1204
|
},
|
1205
|
+
/* Commented out properties
|
1176
1206
|
// ====== Size & Layout ======
|
1177
1207
|
{
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
},
|
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
|
+
},
|
1193
1222
|
},
|
1194
|
-
|
1223
|
+
},
|
1224
|
+
visible: true,
|
1195
1225
|
},
|
1196
1226
|
{
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
},
|
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
|
+
},
|
1212
1241
|
},
|
1213
|
-
|
1242
|
+
},
|
1243
|
+
visible: true,
|
1214
1244
|
},
|
1215
1245
|
// ====== Donut Appearance ======
|
1216
1246
|
{
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
},
|
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,
|
1228
1257
|
},
|
1229
|
-
|
1258
|
+
},
|
1259
|
+
visible: true,
|
1230
1260
|
},
|
1231
1261
|
{
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1245
|
-
|
1246
|
-
|
1247
|
-
},
|
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
|
+
},
|
1248
1277
|
},
|
1249
|
-
|
1278
|
+
},
|
1279
|
+
visible: true,
|
1250
1280
|
},
|
1251
1281
|
{
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
},
|
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
|
+
},
|
1268
1297
|
},
|
1269
|
-
|
1298
|
+
},
|
1299
|
+
visible: true,
|
1270
1300
|
},
|
1271
1301
|
// ====== Legend ======
|
1272
1302
|
// {
|
@@ -1304,71 +1334,72 @@ const AXPDonutChartWidget = {
|
|
1304
1334
|
// },
|
1305
1335
|
// ====== Tooltip ======
|
1306
1336
|
{
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
},
|
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,
|
1318
1347
|
},
|
1319
|
-
|
1348
|
+
},
|
1349
|
+
visible: true,
|
1320
1350
|
},
|
1321
1351
|
// ====== Animation Settings ======
|
1322
1352
|
{
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
},
|
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
|
+
},
|
1349
1378
|
},
|
1350
|
-
|
1379
|
+
},
|
1380
|
+
visible: true,
|
1351
1381
|
},
|
1352
1382
|
{
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
},
|
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
|
+
},
|
1369
1398
|
},
|
1370
|
-
|
1399
|
+
},
|
1400
|
+
visible: true,
|
1371
1401
|
},
|
1402
|
+
*/
|
1372
1403
|
],
|
1373
1404
|
components: {
|
1374
1405
|
view: {
|
@@ -1393,17 +1424,29 @@ const AXPDonutChartWidget = {
|
|
1393
1424
|
*/
|
1394
1425
|
class AXPGaugeChartWidgetViewComponent extends AXPValueWidgetComponent {
|
1395
1426
|
constructor() {
|
1396
|
-
super(
|
1427
|
+
super();
|
1397
1428
|
this.gaugeChartValue = computed(() => this.getValue());
|
1398
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
|
+
});
|
1399
1442
|
}
|
1400
|
-
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 }); }
|
1401
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 }); }
|
1402
1445
|
}
|
1403
1446
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPGaugeChartWidgetViewComponent, decorators: [{
|
1404
1447
|
type: Component,
|
1405
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"] }]
|
1406
|
-
}] });
|
1449
|
+
}], ctorParameters: () => [] });
|
1407
1450
|
|
1408
1451
|
var gaugeChartWidget_component = /*#__PURE__*/Object.freeze({
|
1409
1452
|
__proto__: null,
|
@@ -1422,7 +1465,7 @@ const AXPGaugeChartWidget = {
|
|
1422
1465
|
// ====== Chart Title ======
|
1423
1466
|
{
|
1424
1467
|
name: 'title',
|
1425
|
-
title: '
|
1468
|
+
title: '@dashboard:widgets.gauge-chart.chart-title',
|
1426
1469
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1427
1470
|
schema: {
|
1428
1471
|
defaultValue: '',
|
@@ -1438,201 +1481,203 @@ const AXPGaugeChartWidget = {
|
|
1438
1481
|
},
|
1439
1482
|
visible: true,
|
1440
1483
|
},
|
1441
|
-
// ======
|
1484
|
+
// ====== Label Display ======
|
1442
1485
|
{
|
1443
|
-
name: '
|
1444
|
-
title: '
|
1445
|
-
group:
|
1486
|
+
name: 'label',
|
1487
|
+
title: '@dashboard:widgets.gauge-chart.label',
|
1488
|
+
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1446
1489
|
schema: {
|
1447
|
-
defaultValue:
|
1448
|
-
dataType: '
|
1490
|
+
defaultValue: '',
|
1491
|
+
dataType: 'string',
|
1449
1492
|
interface: {
|
1450
|
-
name: '
|
1451
|
-
path: 'options.
|
1452
|
-
type: AXPWidgetsCatalog.
|
1453
|
-
options: {
|
1454
|
-
placeholder: '1-1200',
|
1455
|
-
minValue: 1,
|
1456
|
-
maxValue: 1200,
|
1457
|
-
},
|
1493
|
+
name: 'label',
|
1494
|
+
path: 'options.label',
|
1495
|
+
type: AXPWidgetsCatalog.text,
|
1458
1496
|
},
|
1459
1497
|
},
|
1460
1498
|
visible: true,
|
1461
1499
|
},
|
1500
|
+
/* Commented out properties
|
1501
|
+
// ====== Layout & Dimensions ======
|
1462
1502
|
{
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
},
|
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
|
+
},
|
1479
1518
|
},
|
1480
|
-
|
1519
|
+
},
|
1520
|
+
visible: true,
|
1481
1521
|
},
|
1482
|
-
// ====== Gauge Configuration ======
|
1483
1522
|
{
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
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
|
+
},
|
1495
1538
|
},
|
1496
|
-
|
1539
|
+
},
|
1540
|
+
visible: true,
|
1497
1541
|
},
|
1542
|
+
// ====== Gauge Configuration ======
|
1498
1543
|
{
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
},
|
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,
|
1510
1554
|
},
|
1511
|
-
|
1555
|
+
},
|
1556
|
+
visible: true,
|
1512
1557
|
},
|
1513
|
-
// ====== Gauge Appearance ======
|
1514
1558
|
{
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
},
|
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,
|
1526
1569
|
},
|
1527
|
-
|
1570
|
+
},
|
1571
|
+
visible: true,
|
1528
1572
|
},
|
1573
|
+
// ====== Gauge Appearance ======
|
1529
1574
|
{
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
options: {
|
1541
|
-
placeholder: '1-100',
|
1542
|
-
minValue: 1,
|
1543
|
-
maxValue: 100,
|
1544
|
-
},
|
1545
|
-
},
|
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,
|
1546
1585
|
},
|
1547
|
-
|
1586
|
+
},
|
1587
|
+
visible: true,
|
1548
1588
|
},
|
1549
1589
|
{
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
},
|
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
|
+
},
|
1566
1605
|
},
|
1567
|
-
|
1606
|
+
},
|
1607
|
+
visible: true,
|
1568
1608
|
},
|
1569
|
-
// ====== Label Display ======
|
1570
1609
|
{
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
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
|
+
},
|
1582
1625
|
},
|
1583
|
-
|
1626
|
+
},
|
1627
|
+
visible: true,
|
1584
1628
|
},
|
1585
1629
|
// ====== Animation Settings ======
|
1586
1630
|
{
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
},
|
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
|
+
},
|
1613
1656
|
},
|
1614
|
-
|
1657
|
+
},
|
1658
|
+
visible: true,
|
1615
1659
|
},
|
1616
1660
|
{
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
},
|
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
|
+
},
|
1633
1676
|
},
|
1634
|
-
|
1677
|
+
},
|
1678
|
+
visible: true,
|
1635
1679
|
},
|
1680
|
+
*/
|
1636
1681
|
],
|
1637
1682
|
components: {
|
1638
1683
|
view: {
|
@@ -1657,20 +1702,37 @@ const AXPGaugeChartWidget = {
|
|
1657
1702
|
*/
|
1658
1703
|
class AXPLineChartWidgetViewComponent extends AXPValueWidgetComponent {
|
1659
1704
|
constructor() {
|
1660
|
-
super(
|
1705
|
+
super();
|
1661
1706
|
this.lineChartData = computed(() => this.getValue());
|
1662
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
|
+
});
|
1663
1725
|
}
|
1664
1726
|
handleLineChartPointClick(event) {
|
1665
1727
|
//console.log(event);
|
1666
1728
|
}
|
1667
|
-
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 }); }
|
1668
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 }); }
|
1669
1731
|
}
|
1670
1732
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPLineChartWidgetViewComponent, decorators: [{
|
1671
1733
|
type: Component,
|
1672
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"] }]
|
1673
|
-
}] });
|
1735
|
+
}], ctorParameters: () => [] });
|
1674
1736
|
|
1675
1737
|
var lineChartWidget_component = /*#__PURE__*/Object.freeze({
|
1676
1738
|
__proto__: null,
|
@@ -1690,7 +1752,7 @@ const AXPLineChartWidget = {
|
|
1690
1752
|
// ====== Chart Title ======
|
1691
1753
|
{
|
1692
1754
|
name: 'title',
|
1693
|
-
title: '
|
1755
|
+
title: '@dashboard:widgets.line-chart.chart-title',
|
1694
1756
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1695
1757
|
schema: {
|
1696
1758
|
defaultValue: '',
|
@@ -1706,64 +1768,10 @@ const AXPLineChartWidget = {
|
|
1706
1768
|
},
|
1707
1769
|
visible: true,
|
1708
1770
|
},
|
1709
|
-
// ====== Layout & Dimensions ======
|
1710
|
-
{
|
1711
|
-
name: 'width',
|
1712
|
-
title: 'Width',
|
1713
|
-
group: AXP_STYLING_PROPERTY_GROUP,
|
1714
|
-
schema: {
|
1715
|
-
defaultValue: null,
|
1716
|
-
dataType: 'number',
|
1717
|
-
interface: {
|
1718
|
-
name: 'width',
|
1719
|
-
path: 'options.width',
|
1720
|
-
type: AXPWidgetsCatalog.number,
|
1721
|
-
options: {
|
1722
|
-
minValue: 0,
|
1723
|
-
maxValue: 1200,
|
1724
|
-
},
|
1725
|
-
},
|
1726
|
-
},
|
1727
|
-
visible: true,
|
1728
|
-
},
|
1729
|
-
{
|
1730
|
-
name: 'height',
|
1731
|
-
title: 'Height',
|
1732
|
-
group: AXP_STYLING_PROPERTY_GROUP,
|
1733
|
-
schema: {
|
1734
|
-
defaultValue: 300,
|
1735
|
-
dataType: 'number',
|
1736
|
-
interface: {
|
1737
|
-
name: 'height',
|
1738
|
-
path: 'options.height',
|
1739
|
-
type: AXPWidgetsCatalog.number,
|
1740
|
-
options: {
|
1741
|
-
minValue: 0,
|
1742
|
-
maxValue: 800,
|
1743
|
-
},
|
1744
|
-
},
|
1745
|
-
},
|
1746
|
-
visible: true,
|
1747
|
-
},
|
1748
1771
|
// ====== Axis Settings ======
|
1749
|
-
{
|
1750
|
-
name: 'showXAxis',
|
1751
|
-
title: 'Show X Axis',
|
1752
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1753
|
-
schema: {
|
1754
|
-
defaultValue: true,
|
1755
|
-
dataType: 'boolean',
|
1756
|
-
interface: {
|
1757
|
-
name: 'showXAxis',
|
1758
|
-
path: 'options.showXAxis',
|
1759
|
-
type: AXPWidgetsCatalog.toggle,
|
1760
|
-
},
|
1761
|
-
},
|
1762
|
-
visible: true,
|
1763
|
-
},
|
1764
1772
|
{
|
1765
1773
|
name: 'xAxisLabel',
|
1766
|
-
title: '
|
1774
|
+
title: '@dashboard:widgets.line-chart.x-axis-label',
|
1767
1775
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1768
1776
|
schema: {
|
1769
1777
|
defaultValue: '',
|
@@ -1776,24 +1784,9 @@ const AXPLineChartWidget = {
|
|
1776
1784
|
},
|
1777
1785
|
visible: true,
|
1778
1786
|
},
|
1779
|
-
{
|
1780
|
-
name: 'showYAxis',
|
1781
|
-
title: 'Show Y Axis',
|
1782
|
-
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1783
|
-
schema: {
|
1784
|
-
defaultValue: true,
|
1785
|
-
dataType: 'boolean',
|
1786
|
-
interface: {
|
1787
|
-
name: 'showYAxis',
|
1788
|
-
path: 'options.showYAxis',
|
1789
|
-
type: AXPWidgetsCatalog.toggle,
|
1790
|
-
},
|
1791
|
-
},
|
1792
|
-
visible: true,
|
1793
|
-
},
|
1794
1787
|
{
|
1795
1788
|
name: 'yAxisLabel',
|
1796
|
-
title: '
|
1789
|
+
title: '@dashboard:widgets.line-chart.y-axis-label',
|
1797
1790
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1798
1791
|
schema: {
|
1799
1792
|
defaultValue: '',
|
@@ -1807,238 +1800,315 @@ const AXPLineChartWidget = {
|
|
1807
1800
|
visible: true,
|
1808
1801
|
},
|
1809
1802
|
{
|
1810
|
-
name: '
|
1811
|
-
title: '
|
1803
|
+
name: 'fillArea',
|
1804
|
+
title: '@dashboard:widgets.line-chart.fill-area',
|
1812
1805
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
1813
1806
|
schema: {
|
1814
|
-
defaultValue:
|
1807
|
+
defaultValue: false,
|
1815
1808
|
dataType: 'boolean',
|
1816
1809
|
interface: {
|
1817
|
-
name: '
|
1818
|
-
path: 'options.
|
1810
|
+
name: 'fillArea',
|
1811
|
+
path: 'options.fillArea',
|
1819
1812
|
type: AXPWidgetsCatalog.toggle,
|
1820
1813
|
},
|
1821
1814
|
},
|
1822
1815
|
visible: true,
|
1823
1816
|
},
|
1817
|
+
/* Commented out properties
|
1818
|
+
// ====== Layout & Dimensions ======
|
1824
1819
|
{
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
|
1834
|
-
|
1835
|
-
|
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
|
+
},
|
1836
1834
|
},
|
1837
|
-
|
1835
|
+
},
|
1836
|
+
visible: true,
|
1838
1837
|
},
|
1839
1838
|
{
|
1840
|
-
|
1841
|
-
|
1842
|
-
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
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
|
+
},
|
1851
1853
|
},
|
1852
|
-
|
1854
|
+
},
|
1855
|
+
visible: true,
|
1853
1856
|
},
|
1854
|
-
|
1857
|
+
|
1858
|
+
// ====== Axis Settings ======
|
1855
1859
|
{
|
1856
|
-
|
1857
|
-
|
1858
|
-
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1866
|
-
options: {
|
1867
|
-
placeholder: '1-10',
|
1868
|
-
minValue: 1,
|
1869
|
-
maxValue: 10,
|
1870
|
-
},
|
1871
|
-
},
|
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,
|
1872
1870
|
},
|
1873
|
-
|
1871
|
+
},
|
1872
|
+
visible: true,
|
1874
1873
|
},
|
1875
1874
|
{
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1881
|
-
|
1882
|
-
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
},
|
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,
|
1887
1885
|
},
|
1888
|
-
|
1886
|
+
},
|
1887
|
+
visible: true,
|
1889
1888
|
},
|
1890
1889
|
{
|
1891
|
-
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1898
|
-
|
1899
|
-
|
1900
|
-
|
1901
|
-
},
|
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,
|
1902
1900
|
},
|
1903
|
-
|
1901
|
+
},
|
1902
|
+
visible: true,
|
1904
1903
|
},
|
1904
|
+
|
1905
1905
|
{
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1913
|
-
|
1914
|
-
|
1915
|
-
|
1916
|
-
|
1917
|
-
|
1918
|
-
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
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,
|
1922
1968
|
},
|
1923
|
-
|
1969
|
+
},
|
1970
|
+
visible: true,
|
1924
1971
|
},
|
1925
1972
|
{
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
},
|
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,
|
1937
1983
|
},
|
1938
|
-
|
1984
|
+
},
|
1985
|
+
visible: true,
|
1939
1986
|
},
|
1940
1987
|
{
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
|
1949
|
-
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
},
|
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
|
+
},
|
1957
2003
|
},
|
1958
|
-
|
2004
|
+
},
|
2005
|
+
visible: true,
|
1959
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,
|
2026
|
+
},
|
2027
|
+
|
1960
2028
|
// ====== Tooltip Settings ======
|
1961
2029
|
{
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
1972
|
-
},
|
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,
|
1973
2040
|
},
|
1974
|
-
|
2041
|
+
},
|
2042
|
+
visible: true,
|
1975
2043
|
},
|
1976
2044
|
{
|
1977
|
-
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
},
|
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,
|
1988
2055
|
},
|
1989
|
-
|
2056
|
+
},
|
2057
|
+
visible: true,
|
1990
2058
|
},
|
2059
|
+
|
1991
2060
|
// ====== Animation Settings ======
|
1992
2061
|
{
|
1993
|
-
|
1994
|
-
|
1995
|
-
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
1999
|
-
|
2000
|
-
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2012
|
-
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
},
|
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
|
+
},
|
2019
2087
|
},
|
2020
|
-
|
2088
|
+
},
|
2089
|
+
visible: true,
|
2021
2090
|
},
|
2022
2091
|
{
|
2023
|
-
|
2024
|
-
|
2025
|
-
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
},
|
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
|
+
},
|
2039
2107
|
},
|
2040
|
-
|
2108
|
+
},
|
2109
|
+
visible: true,
|
2041
2110
|
},
|
2111
|
+
*/
|
2042
2112
|
],
|
2043
2113
|
components: {
|
2044
2114
|
view: {
|
@@ -2047,12 +2117,12 @@ const AXPLineChartWidget = {
|
|
2047
2117
|
},
|
2048
2118
|
meta: {
|
2049
2119
|
dimensions: {
|
2050
|
-
width:
|
2051
|
-
height:
|
2120
|
+
width: 3,
|
2121
|
+
height: 4,
|
2052
2122
|
minWidth: 2,
|
2053
2123
|
minHeight: 2,
|
2054
2124
|
maxWidth: 6,
|
2055
|
-
maxHeight:
|
2125
|
+
maxHeight: 6,
|
2056
2126
|
},
|
2057
2127
|
},
|
2058
2128
|
};
|
@@ -2150,7 +2220,17 @@ const AXPStickyNoteWidget = {
|
|
2150
2220
|
groups: [AXPWidgetGroupEnum.DashboardWidget],
|
2151
2221
|
type: 'dashboard',
|
2152
2222
|
icon: 'fa-light fa-sticky-note',
|
2153
|
-
properties: [
|
2223
|
+
properties: [
|
2224
|
+
AXP_DATA_PATH_PROPERTY,
|
2225
|
+
{
|
2226
|
+
...AXP_BG_COLOR_PROPERTY,
|
2227
|
+
title: '@dashboard:widgets.sticky-note.background-color',
|
2228
|
+
},
|
2229
|
+
{
|
2230
|
+
...plainTextDefaultProperty(),
|
2231
|
+
title: '@dashboard:widgets.sticky-note.note-text',
|
2232
|
+
},
|
2233
|
+
],
|
2154
2234
|
components: {
|
2155
2235
|
view: {
|
2156
2236
|
component: () => Promise.resolve().then(function () { return stickyNoteWidget_component; }).then((c) => c.AXPStickyNoteWidgetViewComponent),
|
@@ -2263,7 +2343,7 @@ class AXPTaskListWidgetViewComponent extends AXPValueWidgetComponent {
|
|
2263
2343
|
return 'Tomorrow';
|
2264
2344
|
if (diffDays < 7)
|
2265
2345
|
return this.datePipe.transform(dateObj, 'EEE') || '';
|
2266
|
-
return this.datePipe.transform(dateObj, 'MM/
|
2346
|
+
return this.datePipe.transform(dateObj, 'MM/DD/YYYY') || '';
|
2267
2347
|
}
|
2268
2348
|
getPriorityColor(priority) {
|
2269
2349
|
if (!priority)
|
@@ -2291,7 +2371,7 @@ class AXPTaskListWidgetViewComponent extends AXPValueWidgetComponent {
|
|
2291
2371
|
return Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
2292
2372
|
}
|
2293
2373
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPTaskListWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
2294
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPTaskListWidgetViewComponent, isStandalone: true, selector: "ng-component", outputs: { taskClick: "taskClick", taskCompleted: "taskCompleted" }, providers: [DatePipe], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-size-full ax-p-4\">\n <!-- Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center
|
2374
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPTaskListWidgetViewComponent, isStandalone: true, selector: "ng-component", outputs: { taskClick: "taskClick", taskCompleted: "taskCompleted" }, providers: [DatePipe], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-size-full ax-p-4 ax-flex ax-flex-col\">\n <!-- Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <h3 class=\"ax-text-lg ax-font-semibold ax-flex ax-items-center ax-gap-2\">\n <ax-icon class=\"ax-text-primary-500\">\n <i class=\"fa-light fa-clipboard-list-check\"></i>\n </ax-icon>\n {{ 'tasklist.title' | translate: { scope: 'dashboard' } | async }}\n </h3>\n <div class=\"ax-flex ax-gap-2\">\n @if (getPendingTaskCount() > 0) {\n <ax-badge\n [text]=\"getPendingTaskCount() + ' ' + ('tasklist.pending' | translate: { scope: 'dashboard' } | async)\"\n [color]=\"'warning'\"\n size=\"sm\"\n class=\"ax-ml-1\"\n >\n </ax-badge>\n }\n @if (getCompletedTaskCount() > 0) {\n <ax-badge\n [text]=\"getCompletedTaskCount() + ' ' + ('tasklist.completed' | translate: { scope: 'dashboard' } | async)\"\n [color]=\"'success'\"\n size=\"sm\"\n class=\"ax-ml-1\"\n >\n </ax-badge>\n }\n </div>\n </div>\n\n <!-- Task List -->\n <div class=\"ax-space-y-4 ax-my-4 ax-px-1 ax-overflow-auto ax-grow\">\n @if (showCategories() && hasCategories()) {\n <!-- Categorized Tasks -->\n @for (category of getCategories(); track category) {\n <div class=\"ax-mb-5\">\n <!-- Category Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center ax-mb-3 ax-h-5\">\n <h4 class=\"ax-font-medium category-header\">{{ category }}</h4>\n @if (getCategoryTaskCount(category)) {\n <ax-badge\n [text]=\"getCategoryTaskCount(category).toString()\"\n [color]=\"'primary'\"\n size=\"sm\"\n class=\"ax-rounded-full\"\n ></ax-badge>\n }\n </div>\n <!-- Tasks in Category -->\n <div class=\"ax-space-y-2\">\n @for (task of getTasksByCategory(category); track task.id) {\n <ng-container\n [ngTemplateOutlet]=\"taskItemTemplateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: task }\"\n ></ng-container>\n }\n </div>\n </div>\n }\n } @else {\n <!-- Uncategorized Tasks -->\n <div class=\"ax-space-y-2\">\n @for (task of taskItems(); track task.id) {\n <ng-container\n [ngTemplateOutlet]=\"taskItemTemplateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: task }\"\n ></ng-container>\n } @empty {\n <!-- Empty State -->\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-py-14 ax-px-4 ax-text-gray-400 empty-state\"\n >\n <ax-icon class=\"ax-text-5xl ax-mb-3 ax-text-gray-300\">\n <i class=\"fa-light fa-clipboard-list-check\"></i>\n </ax-icon>\n <p class=\"ax-text-center ax-font-medium\">\n {{ 'tasklist.noTasks' | translate: { scope: 'dashboard' } | async }}\n </p>\n <p class=\"ax-text-center ax-text-sm ax-mt-2\">\n {{ 'tasklist.addTask' | translate: { scope: 'dashboard' } | async }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n</div>\n\n<!-- Task Item Template -->\n<ng-template #taskItemTemplateRef let-task>\n <div\n class=\"ax-flex ax-gap-3 ax-items-start ax-p-3 ax-rounded-lg task-item\"\n [class.priority-high]=\"task.priority === 'high'\"\n [class.priority-medium]=\"task.priority === 'medium'\"\n [class.priority-low]=\"task.priority === 'low'\"\n [class.ax-bg-surface]=\"task.completed\"\n >\n <!-- Checkbox -->\n <ax-check-box\n class=\"ax-flex-shrink-0 ax-mt-1 task-checkbox\"\n [value]=\"task.completed\"\n [disabled]=\"!allowMarkComplete()\"\n (valueChange)=\"onTaskCompletionChange(task, $event)\"\n >\n </ax-check-box>\n\n <!-- Task Details -->\n <div class=\"ax-overflow-hidden ax-grow ax-text-start\" (click)=\"onTaskClick(task)\">\n <!-- Title and Priority -->\n <div class=\"ax-flex ax-items-center ax-gap-2\">\n <h6 class=\"ax-font-medium ax-truncate ax-pb-1\" [title]=\"task.title\" [class.task-completed]=\"task.completed\">\n {{ task.title }}\n </h6>\n @if (showPriority() && task.priority) {\n <ax-badge\n [color]=\"getPriorityColor(task.priority)\"\n [text]=\"task.priority\"\n size=\"sm\"\n class=\"ax-ml-1 ax-rounded-full\"\n ></ax-badge>\n }\n </div>\n\n <!-- Metadata -->\n <div class=\"ax-flex ax-flex-wrap ax-gap-x-3 ax-gap-y-1 ax-mt-2 ax-text-xs ax-text-gray-500\">\n @if (showDate() && task.dueDate) {\n <span\n class=\"ax-flex ax-items-center ax-gap-1 due-date\"\n [class.ax-text-danger-500]=\"getDaysDifference(task.dueDate) < 0\"\n [class.overdue]=\"getDaysDifference(task.dueDate) < 0\"\n >\n <ax-icon><i class=\"fa-light fa-calendar\"></i></ax-icon>\n {{ formatDueDate(task.dueDate) }}\n </span>\n }\n @if (showAssignee() && task.assignedTo) {\n <span class=\"ax-flex ax-items-center ax-gap-1\">\n @if (task.assignedTo.image) {\n <ax-icon class=\"ax-bg-primary-100 ax-text-primary-500 ax-rounded-full ax-p-1\">\n <i class=\"fa-light fa-user\"></i>\n </ax-icon>\n } @else {\n <ax-icon><i class=\"fa-light fa-user\"></i></ax-icon>\n }\n {{ task.assignedTo.name }}\n </span>\n }\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [":host{display:block;height:100%;width:100%}.task-item{border-radius:8px;transition:all .2s ease-in-out;border-left:3px solid transparent}.task-item:hover{background-color:rgba(var(--ax-sys-color-on-surface),.1);transform:translateY(-2px);box-shadow:0 2px 8px rgba(0,0,0,.05)}.task-item.priority-high{border-left-color:rgb(var(--ax-sys-color-danger-500))}.task-item.priority-medium{border-left-color:rgb(var(--ax-sys-color-warning-500))}.task-item.priority-low{border-left-color:rgb(var(--ax-sys-color-success-500))}.task-item:active{transform:translateY(0);box-shadow:0 1px 3px rgba(0,0,0,.05)}.task-completed{text-decoration:line-through;color:var(--ax-text-secondary);opacity:.7;transition:all .3s ease}.category-header{position:relative}.category-header:after{content:\"\";position:absolute;bottom:-8px;left:0;width:40px;height:3px;background-color:var(--ax-primary-500);border-radius:3px;transition:width .3s ease}.category-header:hover:after{width:60px}.empty-state{animation:fadeIn .5s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.task-checkbox ::ng-deep .ax-checkbox{transition:all .2s ease}.task-checkbox ::ng-deep .ax-checkbox:hover{transform:scale(1.1)}.due-date.overdue{animation:pulse 2s infinite}@keyframes pulse{0%{opacity:.7}50%{opacity:1}to{opacity:.7}}.ax-space-y-2>*{animation:slideInRight .3s ease forwards;opacity:0}.ax-space-y-2>*:nth-child(1){animation-delay:.05s}.ax-space-y-2>*:nth-child(2){animation-delay:.1s}.ax-space-y-2>*:nth-child(3){animation-delay:.15s}.ax-space-y-2>*:nth-child(4){animation-delay:.2s}.ax-space-y-2>*:nth-child(5){animation-delay:.25s}.ax-space-y-2>*:nth-child(6){animation-delay:.3s}.ax-space-y-2>*:nth-child(7){animation-delay:.35s}.ax-space-y-2>*:nth-child(8){animation-delay:.4s}.ax-space-y-2>*:nth-child(9){animation-delay:.45s}.ax-space-y-2>*:nth-child(10){animation-delay:.5s}@keyframes slideInRight{0%{opacity:0;transform:translate(10px)}to{opacity:1;transform:translate(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i3.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXAvatarModule }, { kind: "ngmodule", type: AXImageModule }, { kind: "ngmodule", type: AXCheckBoxModule }, { kind: "component", type: i4.AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "checked", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i2$3.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
2295
2375
|
}
|
2296
2376
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPTaskListWidgetViewComponent, decorators: [{
|
2297
2377
|
type: Component,
|
@@ -2306,7 +2386,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
2306
2386
|
AXCheckBoxModule,
|
2307
2387
|
AXLabelModule,
|
2308
2388
|
AXTranslationModule,
|
2309
|
-
], providers: [DatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ax-size-full ax-p-4\">\n <!-- Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center
|
2389
|
+
], providers: [DatePipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ax-size-full ax-p-4 ax-flex ax-flex-col\">\n <!-- Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center\">\n <h3 class=\"ax-text-lg ax-font-semibold ax-flex ax-items-center ax-gap-2\">\n <ax-icon class=\"ax-text-primary-500\">\n <i class=\"fa-light fa-clipboard-list-check\"></i>\n </ax-icon>\n {{ 'tasklist.title' | translate: { scope: 'dashboard' } | async }}\n </h3>\n <div class=\"ax-flex ax-gap-2\">\n @if (getPendingTaskCount() > 0) {\n <ax-badge\n [text]=\"getPendingTaskCount() + ' ' + ('tasklist.pending' | translate: { scope: 'dashboard' } | async)\"\n [color]=\"'warning'\"\n size=\"sm\"\n class=\"ax-ml-1\"\n >\n </ax-badge>\n }\n @if (getCompletedTaskCount() > 0) {\n <ax-badge\n [text]=\"getCompletedTaskCount() + ' ' + ('tasklist.completed' | translate: { scope: 'dashboard' } | async)\"\n [color]=\"'success'\"\n size=\"sm\"\n class=\"ax-ml-1\"\n >\n </ax-badge>\n }\n </div>\n </div>\n\n <!-- Task List -->\n <div class=\"ax-space-y-4 ax-my-4 ax-px-1 ax-overflow-auto ax-grow\">\n @if (showCategories() && hasCategories()) {\n <!-- Categorized Tasks -->\n @for (category of getCategories(); track category) {\n <div class=\"ax-mb-5\">\n <!-- Category Header -->\n <div class=\"ax-flex ax-justify-between ax-items-center ax-mb-3 ax-h-5\">\n <h4 class=\"ax-font-medium category-header\">{{ category }}</h4>\n @if (getCategoryTaskCount(category)) {\n <ax-badge\n [text]=\"getCategoryTaskCount(category).toString()\"\n [color]=\"'primary'\"\n size=\"sm\"\n class=\"ax-rounded-full\"\n ></ax-badge>\n }\n </div>\n <!-- Tasks in Category -->\n <div class=\"ax-space-y-2\">\n @for (task of getTasksByCategory(category); track task.id) {\n <ng-container\n [ngTemplateOutlet]=\"taskItemTemplateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: task }\"\n ></ng-container>\n }\n </div>\n </div>\n }\n } @else {\n <!-- Uncategorized Tasks -->\n <div class=\"ax-space-y-2\">\n @for (task of taskItems(); track task.id) {\n <ng-container\n [ngTemplateOutlet]=\"taskItemTemplateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: task }\"\n ></ng-container>\n } @empty {\n <!-- Empty State -->\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-py-14 ax-px-4 ax-text-gray-400 empty-state\"\n >\n <ax-icon class=\"ax-text-5xl ax-mb-3 ax-text-gray-300\">\n <i class=\"fa-light fa-clipboard-list-check\"></i>\n </ax-icon>\n <p class=\"ax-text-center ax-font-medium\">\n {{ 'tasklist.noTasks' | translate: { scope: 'dashboard' } | async }}\n </p>\n <p class=\"ax-text-center ax-text-sm ax-mt-2\">\n {{ 'tasklist.addTask' | translate: { scope: 'dashboard' } | async }}\n </p>\n </div>\n }\n </div>\n }\n </div>\n</div>\n\n<!-- Task Item Template -->\n<ng-template #taskItemTemplateRef let-task>\n <div\n class=\"ax-flex ax-gap-3 ax-items-start ax-p-3 ax-rounded-lg task-item\"\n [class.priority-high]=\"task.priority === 'high'\"\n [class.priority-medium]=\"task.priority === 'medium'\"\n [class.priority-low]=\"task.priority === 'low'\"\n [class.ax-bg-surface]=\"task.completed\"\n >\n <!-- Checkbox -->\n <ax-check-box\n class=\"ax-flex-shrink-0 ax-mt-1 task-checkbox\"\n [value]=\"task.completed\"\n [disabled]=\"!allowMarkComplete()\"\n (valueChange)=\"onTaskCompletionChange(task, $event)\"\n >\n </ax-check-box>\n\n <!-- Task Details -->\n <div class=\"ax-overflow-hidden ax-grow ax-text-start\" (click)=\"onTaskClick(task)\">\n <!-- Title and Priority -->\n <div class=\"ax-flex ax-items-center ax-gap-2\">\n <h6 class=\"ax-font-medium ax-truncate ax-pb-1\" [title]=\"task.title\" [class.task-completed]=\"task.completed\">\n {{ task.title }}\n </h6>\n @if (showPriority() && task.priority) {\n <ax-badge\n [color]=\"getPriorityColor(task.priority)\"\n [text]=\"task.priority\"\n size=\"sm\"\n class=\"ax-ml-1 ax-rounded-full\"\n ></ax-badge>\n }\n </div>\n\n <!-- Metadata -->\n <div class=\"ax-flex ax-flex-wrap ax-gap-x-3 ax-gap-y-1 ax-mt-2 ax-text-xs ax-text-gray-500\">\n @if (showDate() && task.dueDate) {\n <span\n class=\"ax-flex ax-items-center ax-gap-1 due-date\"\n [class.ax-text-danger-500]=\"getDaysDifference(task.dueDate) < 0\"\n [class.overdue]=\"getDaysDifference(task.dueDate) < 0\"\n >\n <ax-icon><i class=\"fa-light fa-calendar\"></i></ax-icon>\n {{ formatDueDate(task.dueDate) }}\n </span>\n }\n @if (showAssignee() && task.assignedTo) {\n <span class=\"ax-flex ax-items-center ax-gap-1\">\n @if (task.assignedTo.image) {\n <ax-icon class=\"ax-bg-primary-100 ax-text-primary-500 ax-rounded-full ax-p-1\">\n <i class=\"fa-light fa-user\"></i>\n </ax-icon>\n } @else {\n <ax-icon><i class=\"fa-light fa-user\"></i></ax-icon>\n }\n {{ task.assignedTo.name }}\n </span>\n }\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [":host{display:block;height:100%;width:100%}.task-item{border-radius:8px;transition:all .2s ease-in-out;border-left:3px solid transparent}.task-item:hover{background-color:rgba(var(--ax-sys-color-on-surface),.1);transform:translateY(-2px);box-shadow:0 2px 8px rgba(0,0,0,.05)}.task-item.priority-high{border-left-color:rgb(var(--ax-sys-color-danger-500))}.task-item.priority-medium{border-left-color:rgb(var(--ax-sys-color-warning-500))}.task-item.priority-low{border-left-color:rgb(var(--ax-sys-color-success-500))}.task-item:active{transform:translateY(0);box-shadow:0 1px 3px rgba(0,0,0,.05)}.task-completed{text-decoration:line-through;color:var(--ax-text-secondary);opacity:.7;transition:all .3s ease}.category-header{position:relative}.category-header:after{content:\"\";position:absolute;bottom:-8px;left:0;width:40px;height:3px;background-color:var(--ax-primary-500);border-radius:3px;transition:width .3s ease}.category-header:hover:after{width:60px}.empty-state{animation:fadeIn .5s ease}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.task-checkbox ::ng-deep .ax-checkbox{transition:all .2s ease}.task-checkbox ::ng-deep .ax-checkbox:hover{transform:scale(1.1)}.due-date.overdue{animation:pulse 2s infinite}@keyframes pulse{0%{opacity:.7}50%{opacity:1}to{opacity:.7}}.ax-space-y-2>*{animation:slideInRight .3s ease forwards;opacity:0}.ax-space-y-2>*:nth-child(1){animation-delay:.05s}.ax-space-y-2>*:nth-child(2){animation-delay:.1s}.ax-space-y-2>*:nth-child(3){animation-delay:.15s}.ax-space-y-2>*:nth-child(4){animation-delay:.2s}.ax-space-y-2>*:nth-child(5){animation-delay:.25s}.ax-space-y-2>*:nth-child(6){animation-delay:.3s}.ax-space-y-2>*:nth-child(7){animation-delay:.35s}.ax-space-y-2>*:nth-child(8){animation-delay:.4s}.ax-space-y-2>*:nth-child(9){animation-delay:.45s}.ax-space-y-2>*:nth-child(10){animation-delay:.5s}@keyframes slideInRight{0%{opacity:0;transform:translate(10px)}to{opacity:1;transform:translate(0)}}\n"] }]
|
2310
2390
|
}] });
|
2311
2391
|
|
2312
2392
|
var tasklistWidget_component = /*#__PURE__*/Object.freeze({
|
@@ -2326,7 +2406,7 @@ const AXPTaskListWidget = {
|
|
2326
2406
|
// ====== Title ======
|
2327
2407
|
{
|
2328
2408
|
name: 'title',
|
2329
|
-
title: '
|
2409
|
+
title: '@dashboard:widgets.task-list.chart-title',
|
2330
2410
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2331
2411
|
schema: {
|
2332
2412
|
defaultValue: '',
|
@@ -2345,7 +2425,7 @@ const AXPTaskListWidget = {
|
|
2345
2425
|
// Display options
|
2346
2426
|
{
|
2347
2427
|
name: 'maxItems',
|
2348
|
-
title: '
|
2428
|
+
title: '@dashboard:widgets.task-list.max-items',
|
2349
2429
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2350
2430
|
schema: {
|
2351
2431
|
defaultValue: 10,
|
@@ -2364,7 +2444,7 @@ const AXPTaskListWidget = {
|
|
2364
2444
|
},
|
2365
2445
|
{
|
2366
2446
|
name: 'showDate',
|
2367
|
-
title: '
|
2447
|
+
title: '@dashboard:widgets.task-list.show-date',
|
2368
2448
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2369
2449
|
schema: {
|
2370
2450
|
defaultValue: true,
|
@@ -2379,7 +2459,7 @@ const AXPTaskListWidget = {
|
|
2379
2459
|
},
|
2380
2460
|
{
|
2381
2461
|
name: 'showAssignee',
|
2382
|
-
title: '
|
2462
|
+
title: '@dashboard:widgets.task-list.show-assignee',
|
2383
2463
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2384
2464
|
schema: {
|
2385
2465
|
defaultValue: true,
|
@@ -2394,7 +2474,7 @@ const AXPTaskListWidget = {
|
|
2394
2474
|
},
|
2395
2475
|
{
|
2396
2476
|
name: 'groupByCategory',
|
2397
|
-
title: '
|
2477
|
+
title: '@dashboard:widgets.task-list.group-by-category',
|
2398
2478
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2399
2479
|
schema: {
|
2400
2480
|
defaultValue: true,
|
@@ -2409,7 +2489,7 @@ const AXPTaskListWidget = {
|
|
2409
2489
|
},
|
2410
2490
|
{
|
2411
2491
|
name: 'showPriority',
|
2412
|
-
title: '
|
2492
|
+
title: '@dashboard:widgets.task-list.show-priority',
|
2413
2493
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2414
2494
|
schema: {
|
2415
2495
|
defaultValue: true,
|
@@ -2424,7 +2504,7 @@ const AXPTaskListWidget = {
|
|
2424
2504
|
},
|
2425
2505
|
{
|
2426
2506
|
name: 'allowMarkComplete',
|
2427
|
-
title: '
|
2507
|
+
title: '@dashboard:widgets.task-list.allow-complete',
|
2428
2508
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
2429
2509
|
schema: {
|
2430
2510
|
defaultValue: true,
|
@@ -2445,7 +2525,7 @@ const AXPTaskListWidget = {
|
|
2445
2525
|
},
|
2446
2526
|
meta: {
|
2447
2527
|
dimensions: {
|
2448
|
-
width:
|
2528
|
+
width: 3,
|
2449
2529
|
height: 7,
|
2450
2530
|
minWidth: 3,
|
2451
2531
|
minHeight: 4,
|
@@ -3080,8 +3160,7 @@ class AXPWeatherWidgetViewComponent extends AXPValueWidgetComponent {
|
|
3080
3160
|
setTimeout(() => this.cdr.detectChanges());
|
3081
3161
|
},
|
3082
3162
|
error: (error) => {
|
3083
|
-
this.
|
3084
|
-
this.errorMessage.set(error.message || 'Failed to load weather data. Please try again.');
|
3163
|
+
this.handleError(error);
|
3085
3164
|
this.isLoading.set(false);
|
3086
3165
|
this.isForecastLoading.set(false);
|
3087
3166
|
this.cdr.detectChanges();
|
@@ -3102,8 +3181,7 @@ class AXPWeatherWidgetViewComponent extends AXPValueWidgetComponent {
|
|
3102
3181
|
setTimeout(() => this.cdr.detectChanges());
|
3103
3182
|
},
|
3104
3183
|
error: (error) => {
|
3105
|
-
this.
|
3106
|
-
this.errorMessage.set(error.message || 'Failed to load weather data. Please try again.');
|
3184
|
+
this.handleError(error);
|
3107
3185
|
this.isLoading.set(false);
|
3108
3186
|
this.cdr.detectChanges();
|
3109
3187
|
},
|
@@ -3208,7 +3286,11 @@ class AXPWeatherWidgetViewComponent extends AXPValueWidgetComponent {
|
|
3208
3286
|
*/
|
3209
3287
|
getConditionName(conditionId) {
|
3210
3288
|
const condition = this.weatherService.getCondition(conditionId);
|
3211
|
-
|
3289
|
+
if (!condition?.name)
|
3290
|
+
return 'weather.conditions.sunny';
|
3291
|
+
// Convert condition name to lowercase and replace spaces with hyphens
|
3292
|
+
const formattedName = condition.name.toLowerCase().replace(/\s+/g, '-');
|
3293
|
+
return `weather.conditions.${formattedName}`;
|
3212
3294
|
}
|
3213
3295
|
/**
|
3214
3296
|
* Gets the color for a weather condition
|
@@ -3226,22 +3308,60 @@ class AXPWeatherWidgetViewComponent extends AXPValueWidgetComponent {
|
|
3226
3308
|
cleanupChart() {
|
3227
3309
|
this.clearRefreshTimer();
|
3228
3310
|
}
|
3311
|
+
handleError(error) {
|
3312
|
+
console.error('Weather widget error:', error);
|
3313
|
+
this.hasError.set(true);
|
3314
|
+
// Check if it's a network error
|
3315
|
+
if (error.status === 0) {
|
3316
|
+
this.errorMessage.set('weather.error.network');
|
3317
|
+
return;
|
3318
|
+
}
|
3319
|
+
// Check if it's an API error
|
3320
|
+
if (error.status >= 400 && error.status < 500) {
|
3321
|
+
this.errorMessage.set('weather.error.api');
|
3322
|
+
return;
|
3323
|
+
}
|
3324
|
+
// Default error message
|
3325
|
+
this.errorMessage.set('weather.error.general');
|
3326
|
+
}
|
3327
|
+
getTemperatureUnit() {
|
3328
|
+
return this.temperatureUnit() === '°C' ? 'weather.units.celsius' : 'weather.units.fahrenheit';
|
3329
|
+
}
|
3330
|
+
getWindSpeedUnit() {
|
3331
|
+
return this.windSpeedUnit() === 'km/h' ? 'weather.units.kmh' : 'weather.units.mph';
|
3332
|
+
}
|
3333
|
+
getDayName(date) {
|
3334
|
+
const today = new Date();
|
3335
|
+
const tomorrow = new Date(today);
|
3336
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
3337
|
+
if (date.toDateString() === today.toDateString()) {
|
3338
|
+
return 'weather.days.today';
|
3339
|
+
}
|
3340
|
+
if (date.toDateString() === tomorrow.toDateString()) {
|
3341
|
+
return 'weather.days.tomorrow';
|
3342
|
+
}
|
3343
|
+
const days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
|
3344
|
+
return `weather.days.${days[date.getDay()]}`;
|
3345
|
+
}
|
3346
|
+
parseDate(dateStr) {
|
3347
|
+
return new Date(dateStr);
|
3348
|
+
}
|
3229
3349
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPWeatherWidgetViewComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
3230
3350
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPWeatherWidgetViewComponent, isStandalone: true, selector: "ng-component", providers: [
|
3231
3351
|
{
|
3232
3352
|
provide: AXPWeatherApiAbstract,
|
3233
3353
|
useClass: AXPWeatherApiService,
|
3234
3354
|
},
|
3235
|
-
], viewQueries: [{ propertyName: "containerEl", first: true, predicate: ["containerElement"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<!-- Weather Widget Component Template -->\n<div class=\"axp-weather-container\" #containerElement>\n <!-- Loading indicator -->\n @if (isLoading()) {\n <div class=\"axp-weather-loading-overlay\">\n <div class=\"axp-weather-loading-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading weather data...</span>\n </div>\n </div>\n }\n\n <!-- Error message -->\n @if (hasError()) {\n <div class=\"axp-weather-error-overlay\">\n <div class=\"axp-weather-error-message\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ errorMessage() }}</span>\n <button class=\"axp-weather-retry-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Retry</span>\n </button>\n </div>\n </div>\n }\n\n <!-- Weather content - only show when we have data -->\n @if (weatherData()) {\n <!-- Background decorations based on weather condition -->\n <div class=\"axp-weather-background-decorations\">\n <div class=\"axp-weather-decoration\" [ngClass]=\"weatherData()?.current?.condition?.toLowerCase()\"></div>\n <div class=\"axp-weather-gradient-overlay\"></div>\n </div>\n\n <div class=\"axp-weather-inner\">\n <!-- Location information section -->\n <div class=\"axp-weather-location-info\">\n <div class=\"axp-weather-location-icon\">\n <i class=\"fa-solid fa-location-dot\"></i>\n </div>\n <div class=\"axp-weather-location-text\">\n <h2 class=\"axp-weather-location-name\">{{ city() }}</h2>\n </div>\n </div>\n\n <!-- Current weather conditions section -->\n <div class=\"axp-weather-current-weather\">\n <!-- Weather icon and condition name -->\n @if (showCurrentCondition()) {\n <div class=\"axp-weather-condition\">\n <div class=\"axp-weather-icon-wrapper\">\n <div class=\"axp-weather-icon\">\n <i\n [class]=\"getConditionIcon(weatherData()?.current?.condition || '')\"\n [style.color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></i>\n </div>\n <div\n class=\"axp-weather-icon-glow\"\n [style.background-color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></div>\n </div>\n <div class=\"axp-weather-condition-name\">{{ getCurrentCondition() }}</div>\n </div>\n }\n\n <!-- Temperature display -->\n @if (showTemperature()) {\n <div class=\"axp-weather-temperature\">\n <span class=\"axp-weather-temperature-value\">{{ getCurrentTemperature() }}</span>\n <span class=\"axp-weather-temperature-unit\">{{ temperatureUnit() }}</span>\n </div>\n }\n </div>\n\n <!-- Weather details section (humidity and wind) -->\n @if (showHumidity() || showWind()) {\n <div class=\"axp-weather-details\">\n <!-- Humidity information -->\n @if (showHumidity()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-droplet\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">Humidity</div>\n <div class=\"axp-weather-detail-value\">{{ getHumidity() }}%</div>\n </div>\n </div>\n }\n\n <!-- Wind speed information -->\n @if (showWind()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-wind\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">Wind</div>\n <div class=\"axp-weather-detail-value\">{{ getWindSpeed() }} {{ windSpeedUnit() }}</div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Weather forecast section -->\n @if (showForecast() && weatherData()?.forecast) {\n <div class=\"axp-weather-forecast\">\n <div class=\"axp-weather-forecast-header\">\n <h3 class=\"axp-weather-forecast-title\">\n <i class=\"fa-solid fa-calendar-days\"></i>\n <span>Forecast</span>\n </h3>\n <!-- <div class=\"axp-weather-scroll-indicator\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </div> -->\n </div>\n <!-- Loading indicator for forecast -->\n @if (isForecastLoading()) {\n <div class=\"axp-weather-forecast-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading forecast...</span>\n </div>\n }\n <!-- Scrollable forecast days display -->\n <div class=\"axp-weather-forecast-items\">\n @for (day of displayedForecast(); track day.day) {\n <div class=\"axp-weather-forecast-day\">\n <div class=\"axp-weather-forecast-day-name\">{{ day.day }}</div>\n <div class=\"axp-weather-forecast-icon\" title=\"{{ getConditionName(day.condition) }}\">\n <i [class]=\"getConditionIcon(day.condition)\" [style.color]=\"getConditionColor(day.condition)\"></i>\n </div>\n <div class=\"axp-weather-forecast-temps\">\n <span class=\"axp-weather-forecast-low\">\n {{ temperatureUnit() === '\u00B0C' ? day.minTempC : day.minTempF }}\u00B0\n </span>\n <span class=\"axp-weather-forecast-high\">\n {{ temperatureUnit() === '\u00B0C' ? day.maxTempC : day.maxTempF }}\u00B0\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Last updated timestamp -->\n <div class=\"axp-weather-last-updated\">\n <span>Last updated: {{ getLastUpdated() }}</span>\n </div>\n\n <!-- Manual refresh button -->\n <div class=\"axp-weather-refresh-action\">\n <button\n class=\"axp-weather-refresh-button\"\n (click)=\"refreshWeather()\"\n [attr.aria-label]=\"'Refresh weather data'\"\n title=\"Refresh weather data\"\n >\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Refresh</span>\n </button>\n </div>\n </div>\n } @else if (!isLoading() && !hasError()) {\n <!-- No data state (not loading, no error) -->\n <div class=\"axp-weather-no-data-state\">\n <i class=\"fa-solid fa-cloud-sun\"></i>\n <p>No weather data available</p>\n <button class=\"axp-weather-refresh-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Load Data</span>\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;height:100%;--primary-gradient-start: #2196f3;--primary-gradient-end: #1976d2;--shadow-color: rgba(0, 0, 0, .2);--glass-bg: rgba(255, 255, 255, .15);--glass-border: rgba(255, 255, 255, .2);--text-primary: rgba(255, 255, 255, .95);--text-secondary: rgba(255, 255, 255, .75);--transition-speed: .3s}.axp-weather-container{width:100%;height:100%;border-radius:8px;overflow:hidden;position:relative;box-shadow:0 4px 8px rgba(0,0,0,.1);color:#fff;min-height:300px;background-color:#2c3e50}.axp-weather-loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(44,62,80,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-loading-spinner{text-align:center}.axp-weather-loading-spinner i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-loading-spinner span{display:block;color:#fff;font-size:1rem}.axp-weather-error-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(189,54,47,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-error-message{text-align:center;padding:1rem}.axp-weather-error-message i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-error-message span{display:block;color:#fff;font-size:1.1rem;margin-bottom:1rem}.axp-weather-error-message .axp-weather-retry-button{color:#bd362f;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-error-message .axp-weather-retry-button:hover{transform:translateY(-1px)}.axp-weather-no-data-state{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;padding:2rem;text-align:center}.axp-weather-no-data-state i{font-size:3rem;margin-bottom:1rem;color:rgba(255,255,255,.8)}.axp-weather-no-data-state p{margin-bottom:1.5rem;font-size:1.1rem}.axp-weather-no-data-state .axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-no-data-state .axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-background-decorations{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.axp-weather-decoration{position:absolute;top:0;left:0;width:100%;height:100%;background-size:cover;background-position:center}.axp-weather-decoration.sunny{background:linear-gradient(135deg,#ff7e00,#f7d358)}.axp-weather-decoration.partlyCloudy{background:linear-gradient(135deg,#7ba2e7,#b4d2f7)}.axp-weather-decoration.cloudy{background:linear-gradient(135deg,#717e8c,#919eab)}.axp-weather-decoration.rain{background:linear-gradient(135deg,#6a8caf,#567a9e)}.axp-weather-decoration.snow{background:linear-gradient(135deg,#99b3cc,#c6d4e1)}.axp-weather-decoration.thunder{background:linear-gradient(135deg,#425777,#2c3e50)}.axp-weather-decoration.mist{background:linear-gradient(135deg,#94a3b8,#cbd5e1)}.axp-weather-gradient-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.5))}.axp-weather-inner{position:relative;z-index:2;height:100%;padding:1.5rem;display:flex;flex-direction:column}.axp-weather-location-info{display:flex;align-items:center;margin-bottom:1.5rem}.axp-weather-location-icon{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background-color:rgba(255,255,255,.2);border-radius:50%;margin-right:.75rem}.axp-weather-location-icon i{color:#fff}.axp-weather-location-name{margin:0;font-size:1.5rem;font-weight:500;text-shadow:1px 1px 3px rgba(0,0,0,.2);text-transform:capitalize}.axp-weather-current-weather{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;flex-wrap:wrap}.axp-weather-condition{display:flex;flex-direction:column;align-items:center}.axp-weather-icon-wrapper{position:relative;margin-bottom:.5rem}.axp-weather-icon{position:relative;z-index:2}.axp-weather-icon i{font-size:2.75rem;filter:drop-shadow(0 0 8px rgba(0,0,0,.3))}.axp-weather-icon-glow{position:absolute;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);width:45px;height:45px;border-radius:50%;filter:blur(15px);opacity:.75}.axp-weather-condition-name{font-size:1.1rem;text-align:center;text-shadow:1px 1px 2px rgba(0,0,0,.2)}.axp-weather-temperature{display:flex;align-items:flex-start;text-shadow:1px 1px 3px rgba(0,0,0,.3)}.axp-weather-temperature-value{font-size:3.5rem;font-weight:500;line-height:1}.axp-weather-temperature-unit{font-size:1.5rem;margin-top:.25rem}.axp-weather-details{display:flex;flex-wrap:wrap;gap:1.5rem;margin-bottom:1.5rem;padding:1rem;background-color:rgba(0,0,0,.15);border-radius:8px}.axp-weather-detail-item{display:flex;align-items:center;flex:1;min-width:120px}.axp-weather-detail-icon{width:40px;height:40px;border-radius:50%;background-color:rgba(255,255,255,.2);display:flex;align-items:center;justify-content:center;margin-right:.75rem}.axp-weather-detail-icon i{font-size:1.25rem}.axp-weather-detail-info{display:flex;flex-direction:column}.axp-weather-detail-label{font-size:.875rem;color:rgba(255,255,255,.8);margin-bottom:.25rem}.axp-weather-detail-value{font-size:1.125rem;font-weight:500}.axp-weather-forecast{margin-top:auto;margin-bottom:1rem;background-color:rgba(0,0,0,.15);border-radius:8px;padding:1rem}.axp-weather-forecast-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.axp-weather-forecast-title{margin:0;font-size:1.125rem;font-weight:500;display:flex;align-items:center}.axp-weather-forecast-title i{margin-right:.5rem;opacity:.8}.axp-weather-scroll-indicator{color:rgba(255,255,255,.6)}.axp-weather-forecast-items{display:flex;overflow-x:auto;gap:.75rem;padding-bottom:.5rem}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.3);border-radius:4px}.axp-weather-forecast-items::-webkit-scrollbar-track{background-color:rgba(0,0,0,.1);border-radius:4px}.axp-weather-forecast-day{min-width:80px;display:flex;flex-direction:column;align-items:center;padding:.75rem .5rem;background-color:rgba(255,255,255,.1);border-radius:6px;transition:all .3s ease}.axp-weather-forecast-day:hover{background-color:rgba(255,255,255,.15);transform:translateY(-2px)}.axp-weather-forecast-day-name{font-size:.875rem;margin-bottom:.5rem;font-weight:500}.axp-weather-forecast-icon{font-size:1.5rem;margin-bottom:.5rem}.axp-weather-forecast-icon i{filter:drop-shadow(0 0 5px rgba(0,0,0,.2))}.axp-weather-forecast-temps{display:flex;flex-direction:row;gap:.75rem;align-items:center;font-size:.875rem}.axp-weather-last-updated{text-align:center;font-size:.75rem;opacity:.7;margin-bottom:.5rem}.axp-weather-refresh-action{text-align:center}.axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:.875rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-refresh-button i{font-size:.875rem}@media (max-width: 576px){.axp-weather-inner{padding:.8rem;gap:.4rem}.axp-weather-location-name{font-size:1.1rem}.axp-weather-temperature{font-size:2.5rem}.axp-weather-temperature-unit{font-size:1.1rem}.axp-weather-weather-details{flex-direction:column;gap:.5rem}.axp-weather-forecast-items{flex-wrap:nowrap;overflow-x:auto;padding-bottom:.5rem;margin:0 -.4rem;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;scrollbar-width:thin;mask-image:linear-gradient(to right,#000 95%,rgba(0,0,0,0));-webkit-mask-image:linear-gradient(to right,rgb(0,0,0) 95%,rgba(0,0,0,0))}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.2);border-radius:4px}.axp-weather-forecast-day{min-width:60px;flex:0 0 auto;padding:.4rem .6rem}.axp-weather-forecast-day-name{font-size:.7rem}.axp-weather-forecast-icon{padding:.3rem;height:1.6rem}.axp-weather-forecast-temps{font-size:.7rem}.axp-weather-scroll-indicator{display:block}}:host-context(.theme-dark){--glass-bg: rgba(0, 0, 0, .3);--glass-border: rgba(255, 255, 255, .1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: AXDateTimeModule }, { kind: "ngmodule", type: AXFormatModule }, { kind: "ngmodule", type: HttpClientModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
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 }); }
|
3236
3356
|
}
|
3237
3357
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPWeatherWidgetViewComponent, decorators: [{
|
3238
3358
|
type: Component,
|
3239
|
-
args: [{ standalone: true, imports: [CommonModule, AXDateTimeModule, AXFormatModule, HttpClientModule], providers: [
|
3359
|
+
args: [{ standalone: true, imports: [CommonModule, AXDateTimeModule, AXFormatModule, HttpClientModule, AXTranslationModule], providers: [
|
3240
3360
|
{
|
3241
3361
|
provide: AXPWeatherApiAbstract,
|
3242
3362
|
useClass: AXPWeatherApiService,
|
3243
3363
|
},
|
3244
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Weather Widget Component Template -->\n<div class=\"axp-weather-container\" #containerElement>\n <!-- Loading indicator -->\n @if (isLoading()) {\n <div class=\"axp-weather-loading-overlay\">\n <div class=\"axp-weather-loading-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading weather data...</span>\n </div>\n </div>\n }\n\n <!-- Error message -->\n @if (hasError()) {\n <div class=\"axp-weather-error-overlay\">\n <div class=\"axp-weather-error-message\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ errorMessage() }}</span>\n <button class=\"axp-weather-retry-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Retry</span>\n </button>\n </div>\n </div>\n }\n\n <!-- Weather content - only show when we have data -->\n @if (weatherData()) {\n <!-- Background decorations based on weather condition -->\n <div class=\"axp-weather-background-decorations\">\n <div class=\"axp-weather-decoration\" [ngClass]=\"weatherData()?.current?.condition?.toLowerCase()\"></div>\n <div class=\"axp-weather-gradient-overlay\"></div>\n </div>\n\n <div class=\"axp-weather-inner\">\n <!-- Location information section -->\n <div class=\"axp-weather-location-info\">\n <div class=\"axp-weather-location-icon\">\n <i class=\"fa-solid fa-location-dot\"></i>\n </div>\n <div class=\"axp-weather-location-text\">\n <h2 class=\"axp-weather-location-name\">{{ city() }}</h2>\n </div>\n </div>\n\n <!-- Current weather conditions section -->\n <div class=\"axp-weather-current-weather\">\n <!-- Weather icon and condition name -->\n @if (showCurrentCondition()) {\n <div class=\"axp-weather-condition\">\n <div class=\"axp-weather-icon-wrapper\">\n <div class=\"axp-weather-icon\">\n <i\n [class]=\"getConditionIcon(weatherData()?.current?.condition || '')\"\n [style.color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></i>\n </div>\n <div\n class=\"axp-weather-icon-glow\"\n [style.background-color]=\"getConditionColor(weatherData()?.current?.condition || '')\"\n ></div>\n </div>\n <div class=\"axp-weather-condition-name\">{{ getCurrentCondition() }}</div>\n </div>\n }\n\n <!-- Temperature display -->\n @if (showTemperature()) {\n <div class=\"axp-weather-temperature\">\n <span class=\"axp-weather-temperature-value\">{{ getCurrentTemperature() }}</span>\n <span class=\"axp-weather-temperature-unit\">{{ temperatureUnit() }}</span>\n </div>\n }\n </div>\n\n <!-- Weather details section (humidity and wind) -->\n @if (showHumidity() || showWind()) {\n <div class=\"axp-weather-details\">\n <!-- Humidity information -->\n @if (showHumidity()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-droplet\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">Humidity</div>\n <div class=\"axp-weather-detail-value\">{{ getHumidity() }}%</div>\n </div>\n </div>\n }\n\n <!-- Wind speed information -->\n @if (showWind()) {\n <div class=\"axp-weather-detail-item\">\n <div class=\"axp-weather-detail-icon\">\n <i class=\"fa-solid fa-wind\"></i>\n </div>\n <div class=\"axp-weather-detail-info\">\n <div class=\"axp-weather-detail-label\">Wind</div>\n <div class=\"axp-weather-detail-value\">{{ getWindSpeed() }} {{ windSpeedUnit() }}</div>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Weather forecast section -->\n @if (showForecast() && weatherData()?.forecast) {\n <div class=\"axp-weather-forecast\">\n <div class=\"axp-weather-forecast-header\">\n <h3 class=\"axp-weather-forecast-title\">\n <i class=\"fa-solid fa-calendar-days\"></i>\n <span>Forecast</span>\n </h3>\n <!-- <div class=\"axp-weather-scroll-indicator\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </div> -->\n </div>\n <!-- Loading indicator for forecast -->\n @if (isForecastLoading()) {\n <div class=\"axp-weather-forecast-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading forecast...</span>\n </div>\n }\n <!-- Scrollable forecast days display -->\n <div class=\"axp-weather-forecast-items\">\n @for (day of displayedForecast(); track day.day) {\n <div class=\"axp-weather-forecast-day\">\n <div class=\"axp-weather-forecast-day-name\">{{ day.day }}</div>\n <div class=\"axp-weather-forecast-icon\" title=\"{{ getConditionName(day.condition) }}\">\n <i [class]=\"getConditionIcon(day.condition)\" [style.color]=\"getConditionColor(day.condition)\"></i>\n </div>\n <div class=\"axp-weather-forecast-temps\">\n <span class=\"axp-weather-forecast-low\">\n {{ temperatureUnit() === '\u00B0C' ? day.minTempC : day.minTempF }}\u00B0\n </span>\n <span class=\"axp-weather-forecast-high\">\n {{ temperatureUnit() === '\u00B0C' ? day.maxTempC : day.maxTempF }}\u00B0\n </span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Last updated timestamp -->\n <div class=\"axp-weather-last-updated\">\n <span>Last updated: {{ getLastUpdated() }}</span>\n </div>\n\n <!-- Manual refresh button -->\n <div class=\"axp-weather-refresh-action\">\n <button\n class=\"axp-weather-refresh-button\"\n (click)=\"refreshWeather()\"\n [attr.aria-label]=\"'Refresh weather data'\"\n title=\"Refresh weather data\"\n >\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Refresh</span>\n </button>\n </div>\n </div>\n } @else if (!isLoading() && !hasError()) {\n <!-- No data state (not loading, no error) -->\n <div class=\"axp-weather-no-data-state\">\n <i class=\"fa-solid fa-cloud-sun\"></i>\n <p>No weather data available</p>\n <button class=\"axp-weather-refresh-button\" (click)=\"refreshWeather()\">\n <i class=\"fa-solid fa-sync-alt\"></i>\n <span>Load Data</span>\n </button>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;height:100%;--primary-gradient-start: #2196f3;--primary-gradient-end: #1976d2;--shadow-color: rgba(0, 0, 0, .2);--glass-bg: rgba(255, 255, 255, .15);--glass-border: rgba(255, 255, 255, .2);--text-primary: rgba(255, 255, 255, .95);--text-secondary: rgba(255, 255, 255, .75);--transition-speed: .3s}.axp-weather-container{width:100%;height:100%;border-radius:8px;overflow:hidden;position:relative;box-shadow:0 4px 8px rgba(0,0,0,.1);color:#fff;min-height:300px;background-color:#2c3e50}.axp-weather-loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(44,62,80,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-loading-spinner{text-align:center}.axp-weather-loading-spinner i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-loading-spinner span{display:block;color:#fff;font-size:1rem}.axp-weather-error-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:rgba(189,54,47,.85);display:flex;justify-content:center;align-items:center;z-index:100}.axp-weather-error-message{text-align:center;padding:1rem}.axp-weather-error-message i{font-size:2.5rem;color:#fff;margin-bottom:.5rem}.axp-weather-error-message span{display:block;color:#fff;font-size:1.1rem;margin-bottom:1rem}.axp-weather-error-message .axp-weather-retry-button{color:#bd362f;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-error-message .axp-weather-retry-button:hover{transform:translateY(-1px)}.axp-weather-no-data-state{display:flex;flex-direction:column;justify-content:center;align-items:center;height:100%;padding:2rem;text-align:center}.axp-weather-no-data-state i{font-size:3rem;margin-bottom:1rem;color:rgba(255,255,255,.8)}.axp-weather-no-data-state p{margin-bottom:1.5rem;font-size:1.1rem}.axp-weather-no-data-state .axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:1rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-no-data-state .axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-background-decorations{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1}.axp-weather-decoration{position:absolute;top:0;left:0;width:100%;height:100%;background-size:cover;background-position:center}.axp-weather-decoration.sunny{background:linear-gradient(135deg,#ff7e00,#f7d358)}.axp-weather-decoration.partlyCloudy{background:linear-gradient(135deg,#7ba2e7,#b4d2f7)}.axp-weather-decoration.cloudy{background:linear-gradient(135deg,#717e8c,#919eab)}.axp-weather-decoration.rain{background:linear-gradient(135deg,#6a8caf,#567a9e)}.axp-weather-decoration.snow{background:linear-gradient(135deg,#99b3cc,#c6d4e1)}.axp-weather-decoration.thunder{background:linear-gradient(135deg,#425777,#2c3e50)}.axp-weather-decoration.mist{background:linear-gradient(135deg,#94a3b8,#cbd5e1)}.axp-weather-gradient-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.5))}.axp-weather-inner{position:relative;z-index:2;height:100%;padding:1.5rem;display:flex;flex-direction:column}.axp-weather-location-info{display:flex;align-items:center;margin-bottom:1.5rem}.axp-weather-location-icon{width:32px;height:32px;display:flex;align-items:center;justify-content:center;background-color:rgba(255,255,255,.2);border-radius:50%;margin-right:.75rem}.axp-weather-location-icon i{color:#fff}.axp-weather-location-name{margin:0;font-size:1.5rem;font-weight:500;text-shadow:1px 1px 3px rgba(0,0,0,.2);text-transform:capitalize}.axp-weather-current-weather{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;flex-wrap:wrap}.axp-weather-condition{display:flex;flex-direction:column;align-items:center}.axp-weather-icon-wrapper{position:relative;margin-bottom:.5rem}.axp-weather-icon{position:relative;z-index:2}.axp-weather-icon i{font-size:2.75rem;filter:drop-shadow(0 0 8px rgba(0,0,0,.3))}.axp-weather-icon-glow{position:absolute;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);width:45px;height:45px;border-radius:50%;filter:blur(15px);opacity:.75}.axp-weather-condition-name{font-size:1.1rem;text-align:center;text-shadow:1px 1px 2px rgba(0,0,0,.2)}.axp-weather-temperature{display:flex;align-items:flex-start;text-shadow:1px 1px 3px rgba(0,0,0,.3)}.axp-weather-temperature-value{font-size:3.5rem;font-weight:500;line-height:1}.axp-weather-temperature-unit{font-size:1.5rem;margin-top:.25rem}.axp-weather-details{display:flex;flex-wrap:wrap;gap:1.5rem;margin-bottom:1.5rem;padding:1rem;background-color:rgba(0,0,0,.15);border-radius:8px}.axp-weather-detail-item{display:flex;align-items:center;flex:1;min-width:120px}.axp-weather-detail-icon{width:40px;height:40px;border-radius:50%;background-color:rgba(255,255,255,.2);display:flex;align-items:center;justify-content:center;margin-right:.75rem}.axp-weather-detail-icon i{font-size:1.25rem}.axp-weather-detail-info{display:flex;flex-direction:column}.axp-weather-detail-label{font-size:.875rem;color:rgba(255,255,255,.8);margin-bottom:.25rem}.axp-weather-detail-value{font-size:1.125rem;font-weight:500}.axp-weather-forecast{margin-top:auto;margin-bottom:1rem;background-color:rgba(0,0,0,.15);border-radius:8px;padding:1rem}.axp-weather-forecast-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.axp-weather-forecast-title{margin:0;font-size:1.125rem;font-weight:500;display:flex;align-items:center}.axp-weather-forecast-title i{margin-right:.5rem;opacity:.8}.axp-weather-scroll-indicator{color:rgba(255,255,255,.6)}.axp-weather-forecast-items{display:flex;overflow-x:auto;gap:.75rem;padding-bottom:.5rem}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.3);border-radius:4px}.axp-weather-forecast-items::-webkit-scrollbar-track{background-color:rgba(0,0,0,.1);border-radius:4px}.axp-weather-forecast-day{min-width:80px;display:flex;flex-direction:column;align-items:center;padding:.75rem .5rem;background-color:rgba(255,255,255,.1);border-radius:6px;transition:all .3s ease}.axp-weather-forecast-day:hover{background-color:rgba(255,255,255,.15);transform:translateY(-2px)}.axp-weather-forecast-day-name{font-size:.875rem;margin-bottom:.5rem;font-weight:500}.axp-weather-forecast-icon{font-size:1.5rem;margin-bottom:.5rem}.axp-weather-forecast-icon i{filter:drop-shadow(0 0 5px rgba(0,0,0,.2))}.axp-weather-forecast-temps{display:flex;flex-direction:row;gap:.75rem;align-items:center;font-size:.875rem}.axp-weather-last-updated{text-align:center;font-size:.75rem;opacity:.7;margin-bottom:.5rem}.axp-weather-refresh-action{text-align:center}.axp-weather-refresh-button{background-color:rgba(255,255,255,.2);color:#fff;border:none;border-radius:4px;padding:.5rem 1rem;font-size:.875rem;cursor:pointer;transition:all .3s ease;display:inline-flex;align-items:center;gap:.5rem}.axp-weather-refresh-button:hover{background-color:rgba(255,255,255,.3);transform:translateY(-1px)}.axp-weather-refresh-button i{font-size:.875rem}@media (max-width: 576px){.axp-weather-inner{padding:.8rem;gap:.4rem}.axp-weather-location-name{font-size:1.1rem}.axp-weather-temperature{font-size:2.5rem}.axp-weather-temperature-unit{font-size:1.1rem}.axp-weather-weather-details{flex-direction:column;gap:.5rem}.axp-weather-forecast-items{flex-wrap:nowrap;overflow-x:auto;padding-bottom:.5rem;margin:0 -.4rem;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;scrollbar-width:thin;mask-image:linear-gradient(to right,#000 95%,rgba(0,0,0,0));-webkit-mask-image:linear-gradient(to right,rgb(0,0,0) 95%,rgba(0,0,0,0))}.axp-weather-forecast-items::-webkit-scrollbar{height:4px}.axp-weather-forecast-items::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,.2);border-radius:4px}.axp-weather-forecast-day{min-width:60px;flex:0 0 auto;padding:.4rem .6rem}.axp-weather-forecast-day-name{font-size:.7rem}.axp-weather-forecast-icon{padding:.3rem;height:1.6rem}.axp-weather-forecast-temps{font-size:.7rem}.axp-weather-scroll-indicator{display:block}}:host-context(.theme-dark){--glass-bg: rgba(0, 0, 0, .3);--glass-border: rgba(255, 255, 255, .1)}\n"] }]
|
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"] }]
|
3245
3365
|
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
|
3246
3366
|
|
3247
3367
|
var weatherWidget_component = /*#__PURE__*/Object.freeze({
|
@@ -3264,7 +3384,7 @@ const AXPWeatherWidget = {
|
|
3264
3384
|
/* Location Settings */
|
3265
3385
|
{
|
3266
3386
|
name: 'city',
|
3267
|
-
title: '
|
3387
|
+
title: '@dashboard:widgets.weather.city',
|
3268
3388
|
group: AXP_DATA_PROPERTY_GROUP,
|
3269
3389
|
schema: {
|
3270
3390
|
defaultValue: 'New York',
|
@@ -3340,7 +3460,7 @@ const AXPWeatherWidget = {
|
|
3340
3460
|
// },
|
3341
3461
|
{
|
3342
3462
|
name: 'showHumidity',
|
3343
|
-
title: '
|
3463
|
+
title: '@dashboard:widgets.weather.show-humidity',
|
3344
3464
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
3345
3465
|
schema: {
|
3346
3466
|
defaultValue: true,
|
@@ -3355,7 +3475,7 @@ const AXPWeatherWidget = {
|
|
3355
3475
|
},
|
3356
3476
|
{
|
3357
3477
|
name: 'showWind',
|
3358
|
-
title: '
|
3478
|
+
title: '@dashboard:widgets.weather.show-wind',
|
3359
3479
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
3360
3480
|
schema: {
|
3361
3481
|
defaultValue: true,
|
@@ -3370,7 +3490,7 @@ const AXPWeatherWidget = {
|
|
3370
3490
|
},
|
3371
3491
|
{
|
3372
3492
|
name: 'showForecast',
|
3373
|
-
title: '
|
3493
|
+
title: '@dashboard:widgets.weather.show-forecast',
|
3374
3494
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
3375
3495
|
schema: {
|
3376
3496
|
defaultValue: true,
|
@@ -3385,7 +3505,7 @@ const AXPWeatherWidget = {
|
|
3385
3505
|
},
|
3386
3506
|
{
|
3387
3507
|
name: 'forecastDays',
|
3388
|
-
title: '
|
3508
|
+
title: '@dashboard:widgets.weather.forecast-days',
|
3389
3509
|
group: AXP_APPEARANCE_PROPERTY_GROUP,
|
3390
3510
|
schema: {
|
3391
3511
|
defaultValue: 5,
|
@@ -3406,7 +3526,7 @@ const AXPWeatherWidget = {
|
|
3406
3526
|
/* Units Settings */
|
3407
3527
|
{
|
3408
3528
|
name: 'temperatureUnit',
|
3409
|
-
title: '
|
3529
|
+
title: '@dashboard:widgets.weather.temperature-unit',
|
3410
3530
|
group: AXP_DATA_PROPERTY_GROUP,
|
3411
3531
|
schema: {
|
3412
3532
|
defaultValue: '°C',
|
@@ -3424,7 +3544,7 @@ const AXPWeatherWidget = {
|
|
3424
3544
|
},
|
3425
3545
|
{
|
3426
3546
|
name: 'windSpeedUnit',
|
3427
|
-
title: '
|
3547
|
+
title: '@dashboard:widgets.weather.wind-speed-unit',
|
3428
3548
|
group: AXP_DATA_PROPERTY_GROUP,
|
3429
3549
|
schema: {
|
3430
3550
|
defaultValue: 'km/h',
|
@@ -3443,7 +3563,7 @@ const AXPWeatherWidget = {
|
|
3443
3563
|
/* Refresh Settings */
|
3444
3564
|
{
|
3445
3565
|
name: 'autoRefresh',
|
3446
|
-
title: '
|
3566
|
+
title: '@dashboard:widgets.weather.auto-refresh',
|
3447
3567
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
3448
3568
|
schema: {
|
3449
3569
|
defaultValue: true,
|
@@ -3458,7 +3578,7 @@ const AXPWeatherWidget = {
|
|
3458
3578
|
},
|
3459
3579
|
{
|
3460
3580
|
name: 'refreshInterval',
|
3461
|
-
title: '
|
3581
|
+
title: '@dashboard:widgets.weather.refresh-interval',
|
3462
3582
|
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
3463
3583
|
schema: {
|
3464
3584
|
defaultValue: 15,
|
@@ -3505,7 +3625,7 @@ class AXPDashboardShortcutWidgetViewComponent extends AXPLayoutWidgetComponent {
|
|
3505
3625
|
super.ngOnInit();
|
3506
3626
|
if (!this.color()) {
|
3507
3627
|
this.setOptions({
|
3508
|
-
color: AXPDataGenerator.color()
|
3628
|
+
color: AXPDataGenerator.color(),
|
3509
3629
|
});
|
3510
3630
|
}
|
3511
3631
|
}
|
@@ -3531,8 +3651,8 @@ class AXPDashboardShortcutWidgetViewComponent extends AXPLayoutWidgetComponent {
|
|
3531
3651
|
title: result.title,
|
3532
3652
|
description: result.description,
|
3533
3653
|
icon: result.icon,
|
3534
|
-
command: result.command
|
3535
|
-
}
|
3654
|
+
command: result.command,
|
3655
|
+
},
|
3536
3656
|
});
|
3537
3657
|
}
|
3538
3658
|
}
|
@@ -3558,56 +3678,68 @@ class AXPDashboardShortcutWidgetViewComponent extends AXPLayoutWidgetComponent {
|
|
3558
3678
|
}
|
3559
3679
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPDashboardShortcutWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
3560
3680
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXPDashboardShortcutWidgetViewComponent, isStandalone: true, selector: "ng-component", host: { properties: { "style": "this.__style", "class": "this.__class" } }, usesInheritance: true, ngImport: i0, template: `
|
3561
|
-
@if(item()) {
|
3562
|
-
<div
|
3681
|
+
@if (item()) {
|
3682
|
+
<div
|
3563
3683
|
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden "
|
3564
|
-
(click)="executeCommand()"
|
3684
|
+
(click)="executeCommand()"
|
3685
|
+
>
|
3565
3686
|
<div class="ax-absolute ax-inset-0 ax-bg-black/0 hover:ax-bg-black/10 ax-transition-opacity"></div>
|
3566
3687
|
<i [class]="item().icon + ' ax-text-3xl'"></i>
|
3567
3688
|
<span class="ax-text-xl ax-font-semibold">{{ item().title | translate | async }}</span>
|
3568
|
-
@if(item().description) {
|
3569
|
-
<span class="ax-text-sm ax-opacity-90 ax-text-center ax-px-2">{{
|
3689
|
+
@if (item().description) {
|
3690
|
+
<span class="ax-text-sm ax-opacity-90 ax-text-center ax-px-2">{{
|
3691
|
+
item().description! | translate | async
|
3692
|
+
}}</span>
|
3570
3693
|
}
|
3571
3694
|
</div>
|
3572
3695
|
} @else {
|
3573
|
-
<div
|
3574
|
-
(click)="setCommand()"
|
3575
|
-
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden"
|
3696
|
+
<div
|
3697
|
+
(click)="setCommand()"
|
3698
|
+
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden"
|
3699
|
+
>
|
3576
3700
|
<div class="ax-absolute ax-inset-0 ax-bg-black/0 hover:ax-bg-black/5 ax-transition-opacity"></div>
|
3577
3701
|
<i class="fa-light fa-plus ax-text-3xl"></i>
|
3578
|
-
<span class="ax-text-xl ax-font-semibold">
|
3702
|
+
<span class="ax-text-xl ax-font-semibold">{{
|
3703
|
+
'@dashboard:widgets.dashboard-shortcut.add-shortcut' | translate | async
|
3704
|
+
}}</span>
|
3579
3705
|
</div>
|
3580
3706
|
}
|
3581
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type:
|
3707
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i2$3.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
3582
3708
|
}
|
3583
3709
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXPDashboardShortcutWidgetViewComponent, decorators: [{
|
3584
3710
|
type: Component,
|
3585
3711
|
args: [{
|
3586
3712
|
template: `
|
3587
|
-
@if(item()) {
|
3588
|
-
<div
|
3713
|
+
@if (item()) {
|
3714
|
+
<div
|
3589
3715
|
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden "
|
3590
|
-
(click)="executeCommand()"
|
3716
|
+
(click)="executeCommand()"
|
3717
|
+
>
|
3591
3718
|
<div class="ax-absolute ax-inset-0 ax-bg-black/0 hover:ax-bg-black/10 ax-transition-opacity"></div>
|
3592
3719
|
<i [class]="item().icon + ' ax-text-3xl'"></i>
|
3593
3720
|
<span class="ax-text-xl ax-font-semibold">{{ item().title | translate | async }}</span>
|
3594
|
-
@if(item().description) {
|
3595
|
-
<span class="ax-text-sm ax-opacity-90 ax-text-center ax-px-2">{{
|
3721
|
+
@if (item().description) {
|
3722
|
+
<span class="ax-text-sm ax-opacity-90 ax-text-center ax-px-2">{{
|
3723
|
+
item().description! | translate | async
|
3724
|
+
}}</span>
|
3596
3725
|
}
|
3597
3726
|
</div>
|
3598
3727
|
} @else {
|
3599
|
-
<div
|
3600
|
-
(click)="setCommand()"
|
3601
|
-
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden"
|
3728
|
+
<div
|
3729
|
+
(click)="setCommand()"
|
3730
|
+
class="ax-group ax-flex ax-flex-col ax-items-center ax-justify-center ax-p-3 ax-w-full ax-h-full ax-relative ax-overflow-hidden"
|
3731
|
+
>
|
3602
3732
|
<div class="ax-absolute ax-inset-0 ax-bg-black/0 hover:ax-bg-black/5 ax-transition-opacity"></div>
|
3603
3733
|
<i class="fa-light fa-plus ax-text-3xl"></i>
|
3604
|
-
<span class="ax-text-xl ax-font-semibold">
|
3734
|
+
<span class="ax-text-xl ax-font-semibold">{{
|
3735
|
+
'@dashboard:widgets.dashboard-shortcut.add-shortcut' | translate | async
|
3736
|
+
}}</span>
|
3605
3737
|
</div>
|
3606
3738
|
}
|
3607
3739
|
`,
|
3608
3740
|
standalone: true,
|
3609
3741
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
3610
|
-
imports: [CommonModule, AXTranslationModule]
|
3742
|
+
imports: [CommonModule, AXTranslationModule],
|
3611
3743
|
}]
|
3612
3744
|
}], propDecorators: { __style: [{
|
3613
3745
|
type: HostBinding,
|
@@ -3623,15 +3755,18 @@ var dashboardShortcutWidgetView_component = /*#__PURE__*/Object.freeze({
|
|
3623
3755
|
});
|
3624
3756
|
|
3625
3757
|
const AXPDashboardShortcutWidget = {
|
3626
|
-
name:
|
3627
|
-
title:
|
3758
|
+
name: 'dashboard-shortcut',
|
3759
|
+
title: 'Shortcut',
|
3628
3760
|
description: 'Quick access to your key features.',
|
3629
3761
|
type: 'view',
|
3630
3762
|
categories: [AXP_WIDGETS_UTILITY_CATEGORY],
|
3631
3763
|
groups: [AXPWidgetGroupEnum.DashboardWidget],
|
3632
|
-
icon:
|
3764
|
+
icon: 'fa-light fa-link',
|
3633
3765
|
properties: [
|
3634
|
-
|
3766
|
+
{
|
3767
|
+
...AXP_COLOR_PROPERTY,
|
3768
|
+
title: '@dashboard:widgets.dashboard-shortcut.color',
|
3769
|
+
},
|
3635
3770
|
],
|
3636
3771
|
meta: {
|
3637
3772
|
dimensions: {
|
@@ -3647,7 +3782,7 @@ const AXPDashboardShortcutWidget = {
|
|
3647
3782
|
view: {
|
3648
3783
|
component: () => Promise.resolve().then(function () { return dashboardShortcutWidgetView_component; }).then((c) => c.AXPDashboardShortcutWidgetViewComponent),
|
3649
3784
|
},
|
3650
|
-
}
|
3785
|
+
},
|
3651
3786
|
};
|
3652
3787
|
|
3653
3788
|
class AXMMenuProvider {
|
@@ -3843,6 +3978,7 @@ class AXMDashboardWidgetWrapperComponent {
|
|
3843
3978
|
});
|
3844
3979
|
});
|
3845
3980
|
this.hasConfiguration = input(true);
|
3981
|
+
this.isLocked = input(false);
|
3846
3982
|
this.isDropdownOpen = signal(false);
|
3847
3983
|
}
|
3848
3984
|
#init;
|
@@ -3863,11 +3999,11 @@ class AXMDashboardWidgetWrapperComponent {
|
|
3863
3999
|
console.log('Dropdown event:', event);
|
3864
4000
|
}
|
3865
4001
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMDashboardWidgetWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
3866
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXMDashboardWidgetWrapperComponent, isStandalone: true, selector: "axm-dashboard-widget-wrapper", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, hasConfiguration: { classPropertyName: "hasConfiguration", publicName: "hasConfiguration", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDelete: "onDelete", onConfiguration: "onConfiguration", onValueChanged: "onValueChanged", onOptionsChanged: "onOptionsChanged" }, queries: [{ propertyName: "widget", first: true, predicate: AXPWidgetRendererDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<section class=\"ax-relative ax-size-full ax-flex ax-flex-col ax-group ax-overflow-hidden\">\n <!-- Action button - stays absolute -->\n <div\n class=\"ax-p-[0.6125rem] ax-absolute ax-top-0 ax-end-0 ax-z-[99] ax-invisible group-hover:ax-visible\"\n [class.!ax-visible]=\"isDropdownOpen()\"\n >\n <ax-button class=\"ax-sm\" [look]=\"'blank'\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-ellipsis-vertical\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel (onOpened)=\"isDropdownOpen.set(true)\" (onClosed)=\"isDropdownOpen.set(false)\">\n <ng-container *translate=\"let t\">\n <ax-button-item-list (onItemClick)=\"handleOnItemClick($event)\">\n @if(hasConfiguration()){\n <ax-button-item\n [data]=\"'configuration'\"\n [text]=\"(t('configuration', { scope: 'dashboard' }) | async) || 'configuration'\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-divider></ax-divider>\n }\n <ax-button-item
|
4002
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.10", type: AXMDashboardWidgetWrapperComponent, isStandalone: true, selector: "axm-dashboard-widget-wrapper", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, hasConfiguration: { classPropertyName: "hasConfiguration", publicName: "hasConfiguration", isSignal: true, isRequired: false, transformFunction: null }, isLocked: { classPropertyName: "isLocked", publicName: "isLocked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onDelete: "onDelete", onConfiguration: "onConfiguration", onValueChanged: "onValueChanged", onOptionsChanged: "onOptionsChanged" }, queries: [{ propertyName: "widget", first: true, predicate: AXPWidgetRendererDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<section class=\"ax-relative ax-size-full ax-flex ax-flex-col ax-group ax-overflow-hidden\">\n <!-- Action button - stays absolute -->\n @if(!isLocked()) {\n <div\n class=\"ax-p-[0.6125rem] ax-absolute ax-top-0 ax-end-0 ax-z-[99] ax-invisible group-hover:ax-visible md:group-hover:ax-visible\"\n [class.!ax-visible]=\"isDropdownOpen()\"\n (touchstart)=\"isDropdownOpen.set(true)\"\n >\n <ax-button class=\"ax-sm ax-main-button\" [look]=\"'blank'\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-ellipsis-vertical\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel (onOpened)=\"isDropdownOpen.set(true)\" (onClosed)=\"isDropdownOpen.set(false)\">\n <ng-container *translate=\"let t\">\n <ax-button-item-list (onItemClick)=\"handleOnItemClick($event)\">\n @if(hasConfiguration()){\n <ax-button-item\n [data]=\"'configuration'\"\n [text]=\"(t('configuration', { scope: 'dashboard' }) | async) || 'configuration'\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-divider></ax-divider>\n }\n <ax-button-item [data]=\"'delete'\" [text]=\"(t('delete') | async) || 'delete'\" color=\"danger\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ng-container>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n }\n\n <!-- Title section -->\n @if(title()) {\n <div class=\"ax-ps-5 ax-pe-8 ax-py-3 ax-border-b\">\n <h3 class=\"ax-text-start ax-text-lg ax-font-medium ax-truncate\">{{title()}}</h3>\n </div>\n }\n\n <!-- Content section -->\n <div class=\"ax-overflow-auto ax-h-full\">\n <ng-content></ng-content>\n </div>\n</section>\n", styles: [":host{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i1$2.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "component", type: i1$2.AXButtonItemListComponent, selector: "ax-button-item-list", inputs: ["items"], outputs: ["onItemClick"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXDropdownModule }, { kind: "component", type: i3$2.AXDropdownPanelComponent, selector: "ax-dropdown-panel", inputs: ["isOpen", "fitParent", "dropdownWidth", "position", "placement", "_target", "adaptivityEnabled"], outputs: ["onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i2$3.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
3867
4003
|
}
|
3868
4004
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMDashboardWidgetWrapperComponent, decorators: [{
|
3869
4005
|
type: Component,
|
3870
|
-
args: [{ selector: 'axm-dashboard-widget-wrapper', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXButtonModule, AXDecoratorModule, AXDropdownModule, AXTranslationModule, CommonModule], standalone: true, template: "<section class=\"ax-relative ax-size-full ax-flex ax-flex-col ax-group ax-overflow-hidden\">\n <!-- Action button - stays absolute -->\n <div\n class=\"ax-p-[0.6125rem] ax-absolute ax-top-0 ax-end-0 ax-z-[99] ax-invisible group-hover:ax-visible\"\n [class.!ax-visible]=\"isDropdownOpen()\"\n >\n <ax-button class=\"ax-sm\" [look]=\"'blank'\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-ellipsis-vertical\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel (onOpened)=\"isDropdownOpen.set(true)\" (onClosed)=\"isDropdownOpen.set(false)\">\n <ng-container *translate=\"let t\">\n <ax-button-item-list (onItemClick)=\"handleOnItemClick($event)\">\n @if(hasConfiguration()){\n <ax-button-item\n [data]=\"'configuration'\"\n [text]=\"(t('configuration', { scope: 'dashboard' }) | async) || 'configuration'\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-divider></ax-divider>\n }\n <ax-button-item
|
4006
|
+
args: [{ selector: 'axm-dashboard-widget-wrapper', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AXButtonModule, AXDecoratorModule, AXDropdownModule, AXTranslationModule, CommonModule], standalone: true, template: "<section class=\"ax-relative ax-size-full ax-flex ax-flex-col ax-group ax-overflow-hidden\">\n <!-- Action button - stays absolute -->\n @if(!isLocked()) {\n <div\n class=\"ax-p-[0.6125rem] ax-absolute ax-top-0 ax-end-0 ax-z-[99] ax-invisible group-hover:ax-visible md:group-hover:ax-visible\"\n [class.!ax-visible]=\"isDropdownOpen()\"\n (touchstart)=\"isDropdownOpen.set(true)\"\n >\n <ax-button class=\"ax-sm ax-main-button\" [look]=\"'blank'\">\n <ax-prefix>\n <ax-icon icon=\"fa-light fa-ellipsis-vertical\"></ax-icon>\n </ax-prefix>\n <ax-dropdown-panel (onOpened)=\"isDropdownOpen.set(true)\" (onClosed)=\"isDropdownOpen.set(false)\">\n <ng-container *translate=\"let t\">\n <ax-button-item-list (onItemClick)=\"handleOnItemClick($event)\">\n @if(hasConfiguration()){\n <ax-button-item\n [data]=\"'configuration'\"\n [text]=\"(t('configuration', { scope: 'dashboard' }) | async) || 'configuration'\"\n >\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-cog\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n <ax-divider></ax-divider>\n }\n <ax-button-item [data]=\"'delete'\" [text]=\"(t('delete') | async) || 'delete'\" color=\"danger\">\n <ax-prefix>\n <ax-icon icon=\"fa-solid fa-trash-can\"></ax-icon>\n </ax-prefix>\n </ax-button-item>\n </ax-button-item-list>\n </ng-container>\n </ax-dropdown-panel>\n </ax-button>\n </div>\n }\n\n <!-- Title section -->\n @if(title()) {\n <div class=\"ax-ps-5 ax-pe-8 ax-py-3 ax-border-b\">\n <h3 class=\"ax-text-start ax-text-lg ax-font-medium ax-truncate\">{{title()}}</h3>\n </div>\n }\n\n <!-- Content section -->\n <div class=\"ax-overflow-auto ax-h-full\">\n <ng-content></ng-content>\n </div>\n</section>\n", styles: [":host{display:block;width:100%;height:100%}\n"] }]
|
3871
4007
|
}] });
|
3872
4008
|
|
3873
4009
|
const path = 'home:dashboard:';
|
@@ -3880,7 +4016,6 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3880
4016
|
constructor() {
|
3881
4017
|
super(...arguments);
|
3882
4018
|
this.scope = RootConfig.config.i18n;
|
3883
|
-
this.isAdmin = false;
|
3884
4019
|
this.roleService = inject(AXMOrganizationManagementRoleEntityService);
|
3885
4020
|
this.sessionService = inject(AXPSessionService);
|
3886
4021
|
this.title = model('');
|
@@ -3888,6 +4023,7 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3888
4023
|
this.selectedRoleIds = model([]);
|
3889
4024
|
this.isDisabled = model(false);
|
3890
4025
|
this.isLocked = model(false);
|
4026
|
+
this.isAdmin = model(false);
|
3891
4027
|
this.roles = [];
|
3892
4028
|
}
|
3893
4029
|
get isValid() {
|
@@ -3897,14 +4033,20 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3897
4033
|
// Set initial values from input data
|
3898
4034
|
this.title.set(this.data?.title || '');
|
3899
4035
|
this.description.set(this.data?.description || '');
|
3900
|
-
this.selectedRoleIds.set(this.data?.roleIds || []);
|
3901
4036
|
this.isDisabled.set(this.data?.isDeleted || false);
|
3902
4037
|
this.isLocked.set(this.data?.locked || false);
|
4038
|
+
this.isAdmin.set(this.data?.isAdmin || false);
|
3903
4039
|
// Load roles if admin
|
3904
|
-
if (this.isAdmin) {
|
4040
|
+
if (this.isAdmin()) {
|
3905
4041
|
try {
|
3906
4042
|
const result = await this.roleService.query({ skip: 0, take: 100 });
|
3907
|
-
|
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));
|
3908
4050
|
}
|
3909
4051
|
catch (error) {
|
3910
4052
|
console.error('Error loading roles:', error);
|
@@ -3916,10 +4058,10 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3916
4058
|
this.close({
|
3917
4059
|
title: this.title()?.trim(),
|
3918
4060
|
description: this.description()?.trim(),
|
3919
|
-
roleIds: this.isAdmin ? this.selectedRoleIds() : undefined,
|
3920
|
-
isDeleted: this.isAdmin ? this.isDisabled() : undefined,
|
3921
|
-
locked: this.isAdmin ? this.isLocked() : undefined,
|
3922
|
-
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',
|
3923
4065
|
createdBy: this.sessionService.user?.id,
|
3924
4066
|
createdAt: new Date(),
|
3925
4067
|
updatedBy: this.sessionService.user?.id,
|
@@ -3928,7 +4070,7 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3928
4070
|
});
|
3929
4071
|
}
|
3930
4072
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMAddDashboardPopup, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
3931
|
-
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: `
|
3932
4074
|
<div class="ax-card-body ax-p-4">
|
3933
4075
|
<div class="ax-flex ax-flex-col ax-gap-2 ax-pb-4">
|
3934
4076
|
<p class="ax-font-semibold">{{ 'title' | translate | async }}</p>
|
@@ -3940,7 +4082,7 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3940
4082
|
</ax-text-box>
|
3941
4083
|
</div>
|
3942
4084
|
|
3943
|
-
@if (isAdmin) {
|
4085
|
+
@if (isAdmin()) {
|
3944
4086
|
<div class="ax-flex ax-flex-col ax-gap-2 ax-mt-4">
|
3945
4087
|
<p class="ax-font-semibold">{{ 'roles' | translate: { scope } | async }}</p>
|
3946
4088
|
<ax-select-box
|
@@ -3955,14 +4097,16 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3955
4097
|
</ax-select-box>
|
3956
4098
|
</div>
|
3957
4099
|
|
3958
|
-
<div class="ax-
|
3959
|
-
<
|
3960
|
-
|
3961
|
-
|
4100
|
+
<div class="ax-grid grid-cols-2 ax-grid-flow-col ax-gap-8 ax-mt-4">
|
4101
|
+
<div class="ax-flex ax-flex-row ax-items-center ax-gap-2">
|
4102
|
+
<p class="ax-font-semibold">{{ 'disable' | translate: { scope } | async }}</p>
|
4103
|
+
<ax-switch [(ngModel)]="isDisabled" name="isDisabled"></ax-switch>
|
4104
|
+
</div>
|
3962
4105
|
|
3963
|
-
|
3964
|
-
|
3965
|
-
|
4106
|
+
<div class="ax-flex ax-flex-row ax-items-center ax-gap-2">
|
4107
|
+
<p class="ax-font-semibold">{{ 'lock' | translate: { scope } | async }}</p>
|
4108
|
+
<ax-switch [(ngModel)]="isLocked" name="isLocked"></ax-switch>
|
4109
|
+
</div>
|
3966
4110
|
</div>
|
3967
4111
|
}
|
3968
4112
|
</div>
|
@@ -3982,7 +4126,7 @@ class AXMAddDashboardPopup extends AXBasePageComponent {
|
|
3982
4126
|
</ax-button>
|
3983
4127
|
</ax-suffix>
|
3984
4128
|
</ax-footer>
|
3985
|
-
`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i3$3.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "mask-options", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type:
|
4129
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i3$3.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "mask-options", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2$2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i2$2.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "pipe", type: i2$3.AXTranslatorPipe, name: "translate" }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i7.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed"] }, { kind: "ngmodule", type: AXSwitchModule }, { kind: "component", type: i8.AXSwitchComponent, selector: "ax-switch", inputs: ["disabled", "readonly", "color", "tabIndex", "value", "name", "isLoading"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged", "readonlyChange", "disabledChange"] }] }); }
|
3986
4130
|
}
|
3987
4131
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMAddDashboardPopup, decorators: [{
|
3988
4132
|
type: Component,
|
@@ -3999,7 +4143,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
3999
4143
|
</ax-text-box>
|
4000
4144
|
</div>
|
4001
4145
|
|
4002
|
-
@if (isAdmin) {
|
4146
|
+
@if (isAdmin()) {
|
4003
4147
|
<div class="ax-flex ax-flex-col ax-gap-2 ax-mt-4">
|
4004
4148
|
<p class="ax-font-semibold">{{ 'roles' | translate: { scope } | async }}</p>
|
4005
4149
|
<ax-select-box
|
@@ -4014,14 +4158,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
4014
4158
|
</ax-select-box>
|
4015
4159
|
</div>
|
4016
4160
|
|
4017
|
-
<div class="ax-
|
4018
|
-
<
|
4019
|
-
|
4020
|
-
|
4161
|
+
<div class="ax-grid grid-cols-2 ax-grid-flow-col ax-gap-8 ax-mt-4">
|
4162
|
+
<div class="ax-flex ax-flex-row ax-items-center ax-gap-2">
|
4163
|
+
<p class="ax-font-semibold">{{ 'disable' | translate: { scope } | async }}</p>
|
4164
|
+
<ax-switch [(ngModel)]="isDisabled" name="isDisabled"></ax-switch>
|
4165
|
+
</div>
|
4021
4166
|
|
4022
|
-
|
4023
|
-
|
4024
|
-
|
4167
|
+
<div class="ax-flex ax-flex-row ax-items-center ax-gap-2">
|
4168
|
+
<p class="ax-font-semibold">{{ 'lock' | translate: { scope } | async }}</p>
|
4169
|
+
<ax-switch [(ngModel)]="isLocked" name="isLocked"></ax-switch>
|
4170
|
+
</div>
|
4025
4171
|
</div>
|
4026
4172
|
}
|
4027
4173
|
</div>
|
@@ -4051,7 +4197,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
4051
4197
|
CommonModule,
|
4052
4198
|
AXTranslationModule,
|
4053
4199
|
AXSelectBoxModule,
|
4054
|
-
|
4200
|
+
AXSwitchModule,
|
4055
4201
|
],
|
4056
4202
|
standalone: true,
|
4057
4203
|
}]
|
@@ -4120,6 +4266,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
4120
4266
|
class AXMDashboardPopupService {
|
4121
4267
|
constructor() {
|
4122
4268
|
this.popupService = inject(AXPopupService);
|
4269
|
+
this.translateService = inject(AXTranslationService);
|
4123
4270
|
}
|
4124
4271
|
async generateDashboardLayout(data, isAdmin) {
|
4125
4272
|
// Add isAdmin to the data object
|
@@ -4129,8 +4276,8 @@ class AXMDashboardPopupService {
|
|
4129
4276
|
size: 'sm',
|
4130
4277
|
draggable: true,
|
4131
4278
|
hasBackdrop: true,
|
4132
|
-
title: '
|
4133
|
-
data: dashboardData,
|
4279
|
+
title: await this.translateService.translateAsync('dashboard-info', { scope: 'dashboard' }),
|
4280
|
+
data: { data: dashboardData },
|
4134
4281
|
});
|
4135
4282
|
if (!result.data) {
|
4136
4283
|
return;
|
@@ -4147,7 +4294,7 @@ class AXMDashboardPopupService {
|
|
4147
4294
|
size: 'sm',
|
4148
4295
|
draggable: true,
|
4149
4296
|
hasBackdrop: true,
|
4150
|
-
title: '
|
4297
|
+
title: await this.translateService.translateAsync('widget-configuration', { scope: 'dashboard' }),
|
4151
4298
|
data: { widget },
|
4152
4299
|
});
|
4153
4300
|
if (!result.data) {
|
@@ -4167,106 +4314,119 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
4167
4314
|
args: [{ providedIn: 'root' }]
|
4168
4315
|
}] });
|
4169
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
|
+
});
|
4170
4366
|
// Create the SignalStore
|
4171
4367
|
const AXMDashboardStore = signalStore({ providedIn: 'root' },
|
4172
4368
|
// Initial State Definition
|
4173
|
-
withState(() =>
|
4174
|
-
// Define initial empty state
|
4175
|
-
const state = {
|
4176
|
-
dashboards: [],
|
4177
|
-
allDashboards: [],
|
4178
|
-
currentDashboardId: null,
|
4179
|
-
isAdmin: false,
|
4180
|
-
dashboardsOption: {
|
4181
|
-
float: true,
|
4182
|
-
cellHeight: 75,
|
4183
|
-
gap: 5,
|
4184
|
-
minRow: 9,
|
4185
|
-
column: 12,
|
4186
|
-
responsiveLayout: [
|
4187
|
-
{ column: 12, width: 2048 },
|
4188
|
-
{ column: 6, width: 768 },
|
4189
|
-
{ column: 1, width: 480 },
|
4190
|
-
],
|
4191
|
-
},
|
4192
|
-
isLoading: false,
|
4193
|
-
};
|
4194
|
-
return state;
|
4195
|
-
}),
|
4369
|
+
withState(() => createInitialState()),
|
4196
4370
|
// Computed Properties
|
4197
|
-
withComputed((state, sessionService = inject(AXPSessionService)) => ({
|
4198
|
-
|
4199
|
-
|
4200
|
-
|
4201
|
-
|
4202
|
-
return state.isAdmin();
|
4203
|
-
}),
|
4204
|
-
allDashboards: computed(() => {
|
4205
|
-
return state.allDashboards();
|
4206
|
-
}),
|
4207
|
-
dashboardsOption: computed(() => {
|
4371
|
+
withComputed((state, sessionService = inject(AXPSessionService), layoutThemeService = inject(AXPLayoutThemeService)) => ({
|
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(() => {
|
4208
4376
|
const currentDashboard = state.dashboards().find((dashboard) => dashboard.id === state.currentDashboardId());
|
4209
4377
|
const baseOptions = state.dashboardsOption();
|
4210
|
-
|
4211
|
-
if (!currentDashboard) {
|
4378
|
+
if (!currentDashboard)
|
4212
4379
|
return baseOptions;
|
4380
|
+
if (!layoutThemeService.isDesktopDevice()) {
|
4381
|
+
return { ...baseOptions, disableDrag: true, disableResize: true };
|
4213
4382
|
}
|
4214
|
-
|
4215
|
-
if (state.isAdmin()) {
|
4383
|
+
if (baseOptions.disableDrag !== undefined && baseOptions.disableResize !== undefined) {
|
4216
4384
|
return baseOptions;
|
4217
4385
|
}
|
4218
|
-
// Check if dashboard is locked
|
4219
4386
|
if (currentDashboard.locked === true) {
|
4220
|
-
return {
|
4221
|
-
...baseOptions,
|
4222
|
-
disableDrag: true,
|
4223
|
-
disableResize: true,
|
4224
|
-
};
|
4387
|
+
return { ...baseOptions, disableDrag: true, disableResize: true };
|
4225
4388
|
}
|
4226
|
-
|
4389
|
+
if (state.isAdmin())
|
4390
|
+
return baseOptions;
|
4227
4391
|
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4228
|
-
// Check if user has role in dashboard
|
4229
4392
|
const hasRoleIds = currentDashboard.roleIds && Array.isArray(currentDashboard.roleIds) && currentDashboard.roleIds.length > 0;
|
4230
4393
|
const hasUserRole = userRole && hasRoleIds && currentDashboard.roleIds?.includes(userRole);
|
4231
|
-
// If user is not admin, has role in dashboard, and dashboard has scope 'T', disable drag and resize
|
4232
4394
|
if (!state.isAdmin() && hasUserRole && currentDashboard.scope === 'T') {
|
4233
|
-
return {
|
4234
|
-
...baseOptions,
|
4235
|
-
disableDrag: true,
|
4236
|
-
disableResize: true,
|
4237
|
-
};
|
4395
|
+
return { ...baseOptions, disableDrag: true, disableResize: true };
|
4238
4396
|
}
|
4239
|
-
// Otherwise, return base options
|
4240
4397
|
return baseOptions;
|
4241
4398
|
}),
|
4242
|
-
canConfigureWidget: computed(() => {
|
4243
|
-
|
4244
|
-
|
4245
|
-
|
4246
|
-
|
4247
|
-
// If admin, always allow configuration
|
4248
|
-
if (state.isAdmin())
|
4249
|
-
return widget.node?.options?.['hasConfiguration'] ?? true;
|
4250
|
-
// If dashboard is locked, no configuration allowed
|
4251
|
-
if (currentDashboard.locked === true) {
|
4252
|
-
return false;
|
4253
|
-
}
|
4254
|
-
// Get user role
|
4255
|
-
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4256
|
-
// Check if user has role in dashboard
|
4257
|
-
const hasRoleIds = currentDashboard.roleIds && Array.isArray(currentDashboard.roleIds) && currentDashboard.roleIds.length > 0;
|
4258
|
-
const hasUserRole = userRole && hasRoleIds && currentDashboard.roleIds?.includes(userRole);
|
4259
|
-
// If user is not admin, has role in dashboard, and dashboard has scope 'T', disable configuration
|
4260
|
-
if (hasUserRole && currentDashboard.scope === 'T') {
|
4261
|
-
return false;
|
4262
|
-
}
|
4263
|
-
// 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())
|
4264
4404
|
return widget.node?.options?.['hasConfiguration'] ?? true;
|
4265
|
-
|
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;
|
4413
|
+
}),
|
4414
|
+
isWidgetLocked: computed(() => (widget) => {
|
4415
|
+
const currentDashboard = state.dashboards().find((dashboard) => dashboard.id === state.currentDashboardId());
|
4416
|
+
if (!currentDashboard)
|
4417
|
+
return false;
|
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';
|
4266
4426
|
}),
|
4267
4427
|
})),
|
4268
4428
|
// Methods for State Management
|
4269
|
-
withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogService = inject(AXDialogService), translationService = inject(AXTranslationService), widgetPickerService = inject(AXPWidgetPickerService), dashboardService = inject(AXMDashboardService), settingService = inject(AXPSettingService), sessionService = inject(AXPSessionService)) => {
|
4429
|
+
withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogService = inject(AXDialogService), translationService = inject(AXTranslationService), widgetPickerService = inject(AXPWidgetPickerService), dashboardService = inject(AXMDashboardService), settingService = inject(AXPSettingService), sessionService = inject(AXPSessionService), layoutThemeService = inject(AXPLayoutThemeService)) => {
|
4270
4430
|
// Load dashboards from service - runs on init via effect
|
4271
4431
|
effect(() => {
|
4272
4432
|
loadDashboards();
|
@@ -4275,126 +4435,112 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4275
4435
|
async function loadDashboards() {
|
4276
4436
|
try {
|
4277
4437
|
patchState(store, { isLoading: true });
|
4278
|
-
// Get dashboards from service using query method
|
4279
4438
|
const result = await dashboardService.query({ skip: 0, take: 100 });
|
4280
4439
|
const dashboardModels = result.items || [];
|
4281
|
-
// Convert dashboard models to AXPDashboardLayout
|
4282
4440
|
const dashboards = dashboardModels.map(modelToDashboardLayout);
|
4283
|
-
// Get current dashboard from settings
|
4284
4441
|
const currentDashboardId = await settingService
|
4285
4442
|
.scope(AXPPlatformScope.User)
|
4286
4443
|
.get(AXPHomeDashboardSetting.CurrentDashboard);
|
4287
4444
|
let newCurrentDashboardId = null;
|
4288
4445
|
if (dashboards.length > 0) {
|
4289
|
-
// Check if currentDashboardId exists and is valid
|
4290
4446
|
const dashboardExists = currentDashboardId && dashboards.some((d) => d.id === currentDashboardId);
|
4291
|
-
|
4292
|
-
|
4293
|
-
}
|
4294
|
-
else {
|
4295
|
-
// If current dashboard is not valid or not set, use the first one
|
4296
|
-
newCurrentDashboardId = dashboards[0].id;
|
4297
|
-
// Save to user settings
|
4447
|
+
newCurrentDashboardId = dashboardExists ? currentDashboardId : dashboards[0].id;
|
4448
|
+
if (!dashboardExists) {
|
4298
4449
|
settingService
|
4299
4450
|
.scope(AXPPlatformScope.User)
|
4300
4451
|
.set(AXPHomeDashboardSetting.CurrentDashboard, newCurrentDashboardId);
|
4301
4452
|
}
|
4302
4453
|
}
|
4303
|
-
// First, update the state with all dashboards
|
4304
4454
|
patchState(store, {
|
4305
4455
|
allDashboards: dashboards,
|
4306
|
-
dashboards: dashboards,
|
4456
|
+
dashboards: dashboards,
|
4307
4457
|
isLoading: false,
|
4308
4458
|
currentDashboardId: newCurrentDashboardId,
|
4309
4459
|
});
|
4310
|
-
// After state is updated, apply filtering if needed
|
4311
|
-
if (store.isAdmin() !== undefined) {
|
4312
|
-
// We need to use the method from the return object, so we'll call it later
|
4313
|
-
}
|
4314
4460
|
}
|
4315
4461
|
catch (error) {
|
4316
4462
|
console.error('Error loading dashboards:', error);
|
4317
4463
|
patchState(store, { isLoading: false });
|
4318
4464
|
}
|
4319
4465
|
}
|
4320
|
-
// Convert entity model to dashboard layout
|
4321
|
-
function modelToDashboardLayout(model) {
|
4322
|
-
return {
|
4323
|
-
id: model.id || '',
|
4324
|
-
title: model.title,
|
4325
|
-
description: model.description,
|
4326
|
-
widgets: model.widgets || [],
|
4327
|
-
roleIds: model.roleIds,
|
4328
|
-
isDeleted: model.isDeleted,
|
4329
|
-
locked: model.locked,
|
4330
|
-
createdAt: model.createdAt,
|
4331
|
-
updatedAt: model.updatedAt,
|
4332
|
-
createdBy: model.createdBy,
|
4333
|
-
updatedBy: model.updatedBy,
|
4334
|
-
scope: model.scope,
|
4335
|
-
};
|
4336
|
-
}
|
4337
|
-
// Convert dashboard layout to entity model
|
4338
|
-
function dashboardLayoutToModel(layout) {
|
4339
|
-
return {
|
4340
|
-
id: layout.id,
|
4341
|
-
name: layout.title,
|
4342
|
-
title: layout.title,
|
4343
|
-
description: layout.description || '',
|
4344
|
-
widgets: layout.widgets,
|
4345
|
-
roleIds: layout.roleIds,
|
4346
|
-
isDeleted: layout.isDeleted,
|
4347
|
-
locked: layout.locked,
|
4348
|
-
createdAt: layout.createdAt,
|
4349
|
-
updatedAt: layout.updatedAt,
|
4350
|
-
createdBy: layout.createdBy,
|
4351
|
-
updatedBy: layout.updatedBy,
|
4352
|
-
scope: layout.scope,
|
4353
|
-
};
|
4354
|
-
}
|
4355
4466
|
return {
|
4356
|
-
// Set current dashboard
|
4357
4467
|
setCurrentDashboard(dashboardId) {
|
4358
4468
|
patchState(store, { currentDashboardId: dashboardId });
|
4359
4469
|
settingService.scope(AXPPlatformScope.User).set(AXPHomeDashboardSetting.CurrentDashboard, dashboardId);
|
4360
4470
|
},
|
4361
|
-
// Add a new dashboard
|
4362
4471
|
async addDashboard() {
|
4363
4472
|
try {
|
4364
|
-
const newDashboard = await dashboardPopup.generateDashboardLayout({}, store.
|
4473
|
+
const newDashboard = await dashboardPopup.generateDashboardLayout({}, store.isUserAdmin());
|
4365
4474
|
if (!newDashboard)
|
4366
4475
|
return;
|
4367
|
-
// Add creation and update metadata
|
4368
4476
|
const userId = sessionService.user?.id;
|
4369
4477
|
const now = new Date();
|
4370
|
-
|
4371
|
-
|
4372
|
-
|
4373
|
-
|
4374
|
-
|
4375
|
-
|
4376
|
-
|
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);
|
4377
4488
|
const createdDashboardId = await dashboardService.insertOne(dashboardModel);
|
4378
|
-
|
4379
|
-
|
4380
|
-
|
4381
|
-
const updatedAllDashboards = [...store.allDashboards(), newDashboard];
|
4382
|
-
const updatedDashboards = [...store.dashboards(), newDashboard];
|
4489
|
+
dashboardWithMetadata.id = createdDashboardId;
|
4490
|
+
const updatedAllDashboards = [...store.availableDashboards(), dashboardWithMetadata];
|
4491
|
+
const updatedDashboards = [...store.dashboards(), dashboardWithMetadata];
|
4383
4492
|
patchState(store, {
|
4384
4493
|
allDashboards: updatedAllDashboards,
|
4385
4494
|
dashboards: updatedDashboards,
|
4386
|
-
currentDashboardId:
|
4495
|
+
currentDashboardId: dashboardWithMetadata.id,
|
4387
4496
|
});
|
4388
|
-
|
4389
|
-
|
4497
|
+
settingService
|
4498
|
+
.scope(AXPPlatformScope.User)
|
4499
|
+
.set(AXPHomeDashboardSetting.CurrentDashboard, dashboardWithMetadata.id);
|
4390
4500
|
}
|
4391
4501
|
catch (error) {
|
4392
4502
|
console.error('Error adding dashboard:', error);
|
4393
4503
|
}
|
4394
4504
|
},
|
4395
|
-
|
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
|
+
},
|
4396
4542
|
async addWidget() {
|
4397
|
-
if (!store.
|
4543
|
+
if (!store.selectedDashboard()) {
|
4398
4544
|
console.warn('No current dashboard selected');
|
4399
4545
|
return;
|
4400
4546
|
}
|
@@ -4402,57 +4548,43 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4402
4548
|
const widgets = await widgetPickerService.showPicker({
|
4403
4549
|
groups: [AXPWidgetGroupEnum.DashboardWidget],
|
4404
4550
|
});
|
4405
|
-
|
4406
|
-
|
4407
|
-
|
4408
|
-
|
4409
|
-
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 };
|
4410
4555
|
}
|
4411
|
-
filteredWidgets[0].options.hasConfiguration = false;
|
4412
|
-
}
|
4413
|
-
filteredWidgets.forEach((widget) => {
|
4414
4556
|
const randomId = AXPDataGenerator.uuid();
|
4415
|
-
widget.name = widget
|
4416
|
-
widget.path = widget
|
4417
|
-
|
4418
|
-
// Step 2: Convert the selected widgets into AXPDashboardWidgetData format
|
4419
|
-
const convertedWidgets = filteredWidgets.map((widget) => {
|
4420
|
-
const id = AXPDataGenerator.uuid();
|
4421
|
-
return {
|
4422
|
-
config: {
|
4423
|
-
height: widget?.meta?.dimensions?.height ?? 2,
|
4424
|
-
width: widget?.meta?.dimensions?.width ?? 2,
|
4425
|
-
minHeight: widget?.meta?.dimensions?.minHeight,
|
4426
|
-
minWidth: widget?.meta?.dimensions?.minWidth,
|
4427
|
-
maxHeight: widget?.meta?.dimensions?.maxHeight,
|
4428
|
-
maxWidth: widget?.meta?.dimensions?.maxWidth,
|
4429
|
-
id,
|
4430
|
-
},
|
4431
|
-
node: { ...widget, name: id },
|
4432
|
-
};
|
4433
|
-
});
|
4434
|
-
// Step 3: Update the dashboards
|
4435
|
-
const updatedDashboards = store.dashboards().map((dashboard) => {
|
4436
|
-
if (dashboard.id === store.currentDashboardId()) {
|
4437
|
-
return {
|
4438
|
-
...dashboard,
|
4439
|
-
widgets: [...dashboard.widgets, ...convertedWidgets],
|
4440
|
-
};
|
4441
|
-
}
|
4442
|
-
return dashboard;
|
4557
|
+
widget.name = `${widget.type}-${randomId}`;
|
4558
|
+
widget.path = `${widget.type}-${randomId}`;
|
4559
|
+
return widget;
|
4443
4560
|
});
|
4444
|
-
|
4445
|
-
|
4446
|
-
|
4447
|
-
|
4448
|
-
|
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));
|
4449
4582
|
patchState(store, { dashboards: updatedDashboards });
|
4450
4583
|
}
|
4451
4584
|
catch (error) {
|
4452
4585
|
console.error('Error adding widget:', error);
|
4453
4586
|
}
|
4454
4587
|
},
|
4455
|
-
// Remove a dashboard
|
4456
4588
|
async removeDashboard(id) {
|
4457
4589
|
if (!id) {
|
4458
4590
|
console.warn('No dashboard ID provided for removal');
|
@@ -4461,17 +4593,13 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4461
4593
|
try {
|
4462
4594
|
const dialogResult = await dialogService.confirm(await translationService.translateAsync('workflow.warning'), await translationService.translateAsync('workflow.confirm-delete'), 'danger', 'horizontal');
|
4463
4595
|
if (dialogResult.result) {
|
4464
|
-
// Delete from service
|
4465
4596
|
await dashboardService.deleteOne(id);
|
4466
|
-
|
4467
|
-
const updatedAllDashboards = store.allDashboards().filter((dashboard) => dashboard.id !== id);
|
4597
|
+
const updatedAllDashboards = store.availableDashboards().filter((dashboard) => dashboard.id !== id);
|
4468
4598
|
const updatedDashboards = store.dashboards().filter((dashboard) => dashboard.id !== id);
|
4469
|
-
// Update state and select a new current dashboard if needed
|
4470
4599
|
let newCurrentDashboardId = store.currentDashboardId();
|
4471
4600
|
if (id === store.currentDashboardId()) {
|
4472
4601
|
newCurrentDashboardId =
|
4473
4602
|
updatedDashboards.length > 0 ? updatedDashboards[updatedDashboards.length - 1].id : null;
|
4474
|
-
// Save to settings if we changed the current dashboard
|
4475
4603
|
if (newCurrentDashboardId) {
|
4476
4604
|
settingService
|
4477
4605
|
.scope(AXPPlatformScope.User)
|
@@ -4489,7 +4617,6 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4489
4617
|
console.error('Error removing dashboard:', error);
|
4490
4618
|
}
|
4491
4619
|
},
|
4492
|
-
// Remove a widget from a dashboard
|
4493
4620
|
async removeWidget(dashboardId, widgetId) {
|
4494
4621
|
const currentDashboard = store.dashboards().find((d) => d.id === dashboardId);
|
4495
4622
|
if (!currentDashboard)
|
@@ -4498,88 +4625,56 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4498
4625
|
...currentDashboard,
|
4499
4626
|
widgets: currentDashboard.widgets.filter((widget) => widget.config.id !== widgetId),
|
4500
4627
|
};
|
4501
|
-
// Save to service
|
4502
4628
|
await dashboardService.updateOne(dashboardId, dashboardLayoutToModel(updatedDashboard));
|
4503
|
-
// Update local state
|
4504
4629
|
const updatedDashboards = store
|
4505
4630
|
.dashboards()
|
4506
4631
|
.map((dashboard) => (dashboard.id === dashboardId ? updatedDashboard : dashboard));
|
4507
4632
|
patchState(store, { dashboards: updatedDashboards });
|
4508
4633
|
},
|
4509
|
-
// Handle configuration changes
|
4510
4634
|
async handleConfigChange(dashboard) {
|
4511
|
-
// Save to service
|
4512
4635
|
await dashboardService.updateOne(dashboard.id, dashboardLayoutToModel(dashboard));
|
4513
|
-
// Update local state
|
4514
4636
|
const updatedDashboards = store.dashboards().map((d) => (d.id === dashboard.id ? dashboard : d));
|
4515
4637
|
patchState(store, {
|
4516
4638
|
dashboards: updatedDashboards,
|
4517
4639
|
currentDashboardId: dashboard.id,
|
4518
4640
|
});
|
4519
|
-
// Save current dashboard to settings
|
4520
4641
|
settingService.scope(AXPPlatformScope.User).set(AXPHomeDashboardSetting.CurrentDashboard, dashboard.id);
|
4521
4642
|
},
|
4522
|
-
// Handle grid layout changes
|
4523
4643
|
async onGridChange(event) {
|
4524
|
-
if (!store.
|
4525
|
-
console.warn('No current dashboard for grid change');
|
4644
|
+
if (!layoutThemeService.isDesktopDevice() || !store.selectedDashboard())
|
4526
4645
|
return;
|
4527
|
-
}
|
4528
|
-
// Extract nodes from the event and remove the `element` property
|
4529
4646
|
const nodes = event.nodes.map(({ element, ...rest }) => rest);
|
4530
|
-
|
4531
|
-
const currentDashboard = store.currentDashboard();
|
4647
|
+
const currentDashboard = store.selectedDashboard();
|
4532
4648
|
const updatedWidgets = currentDashboard.widgets.map((widget) => {
|
4533
4649
|
const updatedNode = nodes.find((node) => node.id === widget.config.id);
|
4534
|
-
|
4535
|
-
return {
|
4536
|
-
...widget,
|
4537
|
-
config: updatedNode,
|
4538
|
-
};
|
4539
|
-
}
|
4540
|
-
return widget;
|
4650
|
+
return updatedNode ? { ...widget, config: updatedNode } : widget;
|
4541
4651
|
});
|
4542
4652
|
const updatedDashboard = {
|
4543
4653
|
...currentDashboard,
|
4544
4654
|
widgets: updatedWidgets,
|
4545
4655
|
};
|
4546
|
-
// Save to service
|
4547
4656
|
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4548
|
-
// Update the dashboards
|
4549
4657
|
const updatedDashboards = store
|
4550
4658
|
.dashboards()
|
4551
4659
|
.map((dashboard) => (dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard));
|
4552
4660
|
patchState(store, { dashboards: updatedDashboards });
|
4553
4661
|
},
|
4554
|
-
// Handle widget configuration
|
4555
4662
|
async handlePopupConfiguration(widgetNode) {
|
4556
|
-
if (!store.
|
4557
|
-
console.warn('No current dashboard selected');
|
4663
|
+
if (!store.selectedDashboard())
|
4558
4664
|
return;
|
4559
|
-
}
|
4560
4665
|
try {
|
4561
4666
|
const updatedNode = await dashboardPopup.handlePopupConfiguration(widgetNode);
|
4562
|
-
if (!updatedNode)
|
4667
|
+
if (!updatedNode)
|
4563
4668
|
return;
|
4564
|
-
|
4565
|
-
|
4566
|
-
|
4567
|
-
|
4568
|
-
if (widget.node?.name === widgetNode.name && widget.node?.path === widgetNode.path) {
|
4569
|
-
return {
|
4570
|
-
...widget,
|
4571
|
-
node: updatedNode,
|
4572
|
-
};
|
4573
|
-
}
|
4574
|
-
return widget;
|
4575
|
-
});
|
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);
|
4576
4673
|
const updatedDashboard = {
|
4577
4674
|
...currentDashboard,
|
4578
4675
|
widgets: updatedWidgets,
|
4579
4676
|
};
|
4580
|
-
// Save to service
|
4581
4677
|
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4582
|
-
// Update the dashboards state
|
4583
4678
|
const updatedDashboards = store
|
4584
4679
|
.dashboards()
|
4585
4680
|
.map((dashboard) => (dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard));
|
@@ -4589,74 +4684,47 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4589
4684
|
console.error('Error handling widget configuration:', error);
|
4590
4685
|
}
|
4591
4686
|
},
|
4592
|
-
// Handle widget value changes
|
4593
4687
|
async handleValueChanged(widgetNode, data) {
|
4594
|
-
if (!store.
|
4595
|
-
console.warn('No current dashboard selected');
|
4688
|
+
if (!store.selectedDashboard())
|
4596
4689
|
return;
|
4597
|
-
}
|
4598
4690
|
try {
|
4599
|
-
|
4600
|
-
const
|
4601
|
-
|
4602
|
-
|
4603
|
-
return {
|
4604
|
-
...widget,
|
4605
|
-
node: {
|
4606
|
-
...widget.node,
|
4607
|
-
defaultValue: data,
|
4608
|
-
},
|
4609
|
-
};
|
4610
|
-
}
|
4611
|
-
return widget;
|
4612
|
-
});
|
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);
|
4613
4695
|
const updatedDashboard = {
|
4614
4696
|
...currentDashboard,
|
4615
4697
|
widgets: updatedWidgets,
|
4616
4698
|
};
|
4617
|
-
// Save to service
|
4618
4699
|
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4619
|
-
// Update the dashboards state
|
4620
4700
|
const updatedDashboards = store
|
4621
4701
|
.dashboards()
|
4622
4702
|
.map((dashboard) => (dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard));
|
4623
|
-
|
4703
|
+
patchState(store, { dashboards: updatedDashboards });
|
4624
4704
|
}
|
4625
4705
|
catch (error) {
|
4626
4706
|
console.error('Error handling widget value change:', error);
|
4627
4707
|
}
|
4628
4708
|
},
|
4629
|
-
// Handle widget options changes
|
4630
4709
|
async handleOptionsChanged(widgetNode, data) {
|
4631
|
-
if (!store.
|
4632
|
-
console.warn('No current dashboard selected');
|
4710
|
+
if (!store.selectedDashboard())
|
4633
4711
|
return;
|
4634
|
-
}
|
4635
4712
|
try {
|
4636
|
-
|
4637
|
-
const
|
4638
|
-
|
4639
|
-
|
4640
|
-
|
4641
|
-
...widget,
|
4642
|
-
|
4643
|
-
|
4644
|
-
options: {
|
4645
|
-
...(widget.node.options || {}),
|
4646
|
-
...data,
|
4647
|
-
},
|
4648
|
-
},
|
4649
|
-
};
|
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
|
+
},
|
4650
4721
|
}
|
4651
|
-
|
4652
|
-
});
|
4722
|
+
: widget);
|
4653
4723
|
const updatedDashboard = {
|
4654
4724
|
...currentDashboard,
|
4655
4725
|
widgets: updatedWidgets,
|
4656
4726
|
};
|
4657
|
-
// Save to service
|
4658
4727
|
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4659
|
-
// Update the dashboards state
|
4660
4728
|
const updatedDashboards = store
|
4661
4729
|
.dashboards()
|
4662
4730
|
.map((dashboard) => (dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard));
|
@@ -4666,112 +4734,70 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4666
4734
|
console.error('Error handling widget options change:', error);
|
4667
4735
|
}
|
4668
4736
|
},
|
4669
|
-
|
4670
|
-
|
4671
|
-
try {
|
4672
|
-
patchState(store, { isLoading: true });
|
4673
|
-
// Get dashboards from service using query method
|
4674
|
-
const result = await dashboardService.query({ skip: 0, take: 100 });
|
4675
|
-
const dashboardModels = result.items || [];
|
4676
|
-
// Convert dashboard models to AXPDashboardLayout
|
4677
|
-
const dashboards = dashboardModels.map(modelToDashboardLayout);
|
4678
|
-
// Update allDashboards state
|
4679
|
-
patchState(store, {
|
4680
|
-
allDashboards: dashboards,
|
4681
|
-
isLoading: false,
|
4682
|
-
});
|
4683
|
-
// Re-apply filtering based on current isAdmin state
|
4684
|
-
// This will update the dashboards state with filtered results
|
4685
|
-
const userId = sessionService.user?.id;
|
4686
|
-
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4687
|
-
if (userId) {
|
4688
|
-
this.filterDashboardsByScope(store.isAdmin());
|
4689
|
-
}
|
4690
|
-
else {
|
4691
|
-
// If no user, just show all dashboards
|
4692
|
-
patchState(store, { dashboards });
|
4693
|
-
}
|
4694
|
-
}
|
4695
|
-
catch (error) {
|
4696
|
-
console.error('Error refreshing dashboards:', error);
|
4697
|
-
patchState(store, { isLoading: false });
|
4698
|
-
}
|
4737
|
+
setIsAdmin(isAdmin) {
|
4738
|
+
patchState(store, { isAdmin });
|
4699
4739
|
},
|
4700
4740
|
filterDashboardsByScope(isAdmin) {
|
4701
|
-
|
4702
|
-
const allDashboards = store.allDashboards();
|
4703
|
-
// Get user ID and role from session service
|
4741
|
+
const allDashboards = store.availableDashboards();
|
4704
4742
|
const userId = sessionService.user?.id;
|
4705
4743
|
const userRole = sessionService.user ? sessionService.user['role'] : undefined;
|
4706
4744
|
if (!userId) {
|
4707
|
-
// If no user ID, don't filter
|
4708
4745
|
patchState(store, { dashboards: allDashboards });
|
4709
4746
|
return;
|
4710
4747
|
}
|
4711
|
-
|
4712
|
-
|
4713
|
-
|
4714
|
-
// Admin sees only tenant-level dashboards
|
4715
|
-
filteredDashboards = allDashboards.filter((dashboard) => dashboard.scope === 'T');
|
4716
|
-
}
|
4717
|
-
else {
|
4718
|
-
// Regular users see:
|
4719
|
-
// 1. User-level dashboards they created
|
4720
|
-
// 2. Tenant-level dashboards where their role is included AND isDeleted is false/undefined
|
4721
|
-
filteredDashboards = allDashboards.filter((dashboard) => {
|
4722
|
-
// 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) => {
|
4723
4751
|
const isUserDashboard = dashboard.scope === 'U' && dashboard.createdBy === userId;
|
4724
|
-
// Check if this is a tenant-level dashboard with user's role and is not deleted
|
4725
4752
|
const hasRoleIds = dashboard.roleIds && Array.isArray(dashboard.roleIds) && dashboard.roleIds.length > 0;
|
4726
4753
|
const isTenantDashboard = dashboard.scope === 'T';
|
4727
4754
|
const hasUserRole = userRole && hasRoleIds && dashboard.roleIds?.includes(userRole);
|
4728
|
-
const isNotDeleted = dashboard.isDeleted !== true;
|
4755
|
+
const isNotDeleted = dashboard.isDeleted !== true;
|
4729
4756
|
const isTenantDashboardWithRole = isTenantDashboard && hasUserRole && isNotDeleted;
|
4730
4757
|
return isUserDashboard || isTenantDashboardWithRole;
|
4731
4758
|
});
|
4732
|
-
}
|
4733
|
-
// Update dashboards state
|
4734
4759
|
patchState(store, { dashboards: filteredDashboards });
|
4735
|
-
// If current dashboard is not in filtered list, select the first one
|
4736
4760
|
if (filteredDashboards.length > 0 && !filteredDashboards.some((d) => d.id === store.currentDashboardId())) {
|
4737
4761
|
this.setCurrentDashboard(filteredDashboards[0].id);
|
4738
4762
|
}
|
4739
4763
|
},
|
4740
|
-
// Add method to set isAdmin state
|
4741
|
-
setIsAdmin(isAdmin) {
|
4742
|
-
patchState(store, { isAdmin });
|
4743
|
-
},
|
4744
|
-
// Toggle lock state for the current dashboard
|
4745
4764
|
async toggleLockDashboard() {
|
4746
|
-
const currentDashboard = store.
|
4747
|
-
if (!currentDashboard)
|
4748
|
-
console.warn('No current dashboard selected');
|
4765
|
+
const currentDashboard = store.selectedDashboard();
|
4766
|
+
if (!currentDashboard)
|
4749
4767
|
return;
|
4750
|
-
}
|
4751
4768
|
try {
|
4752
|
-
|
4769
|
+
const isAdmin = store.isUserAdmin();
|
4770
|
+
const userId = sessionService.user?.id;
|
4771
|
+
const canToggle = (!isAdmin && currentDashboard.scope === 'U' && currentDashboard.createdBy === userId) ||
|
4772
|
+
(isAdmin && currentDashboard.scope === 'T');
|
4773
|
+
if (!canToggle) {
|
4774
|
+
console.warn('User does not have permission to toggle lock for this dashboard');
|
4775
|
+
return;
|
4776
|
+
}
|
4753
4777
|
const newLockedState = !currentDashboard.locked;
|
4754
|
-
// Create an updated dashboard with toggled lock state
|
4755
4778
|
const updatedDashboard = {
|
4756
4779
|
...currentDashboard,
|
4757
4780
|
locked: newLockedState,
|
4758
4781
|
};
|
4759
|
-
// Save to service
|
4760
4782
|
await dashboardService.updateOne(updatedDashboard.id, dashboardLayoutToModel(updatedDashboard));
|
4761
|
-
// Update the dashboards in store
|
4762
4783
|
const updatedDashboards = store
|
4763
4784
|
.dashboards()
|
4764
4785
|
.map((dashboard) => (dashboard.id === updatedDashboard.id ? updatedDashboard : dashboard));
|
4786
|
+
const baseOptions = { ...store.dashboardsOption() };
|
4765
4787
|
patchState(store, { dashboards: updatedDashboards });
|
4766
|
-
|
4788
|
+
const updatedOptions = {
|
4789
|
+
...baseOptions,
|
4790
|
+
disableDrag: newLockedState,
|
4791
|
+
disableResize: newLockedState,
|
4792
|
+
};
|
4793
|
+
patchState(store, { dashboardsOption: updatedOptions });
|
4767
4794
|
}
|
4768
4795
|
catch (error) {
|
4769
4796
|
console.error('Error toggling dashboard lock state:', error);
|
4770
4797
|
}
|
4771
4798
|
},
|
4772
|
-
// Check if dashboard is locked
|
4773
4799
|
isDashboardLocked() {
|
4774
|
-
const currentDashboard = store.
|
4800
|
+
const currentDashboard = store.selectedDashboard();
|
4775
4801
|
return currentDashboard?.locked === true;
|
4776
4802
|
},
|
4777
4803
|
};
|
@@ -4780,61 +4806,40 @@ withMethods((store, dashboardPopup = inject(AXMDashboardPopupService), dialogSer
|
|
4780
4806
|
class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
4781
4807
|
constructor() {
|
4782
4808
|
super(...arguments);
|
4783
|
-
|
4809
|
+
// Dependencies
|
4784
4810
|
this.rootConfig = RootConfig;
|
4785
|
-
this.
|
4811
|
+
this.activatedRoute = inject(ActivatedRoute);
|
4786
4812
|
this.dialogService = inject(AXDialogService);
|
4787
|
-
this.
|
4813
|
+
this.popupService = inject(AXPopupService);
|
4788
4814
|
this.router = inject(Router);
|
4789
|
-
this.
|
4790
|
-
this.
|
4791
|
-
|
4792
|
-
// Track if dashboards have been loaded
|
4793
|
-
this.dashboardsLoaded = signal(false);
|
4794
|
-
//#endregion
|
4795
|
-
//#region ---------------- View Properties ----------------
|
4796
|
-
this.isEdited = signal(false);
|
4815
|
+
this.store = inject(AXMDashboardStore);
|
4816
|
+
this.themeService = inject(AXPLayoutThemeService);
|
4817
|
+
// Component State
|
4797
4818
|
this.context = signal({});
|
4798
|
-
|
4799
|
-
|
4800
|
-
|
4801
|
-
|
4802
|
-
const allDashboards = this.store.allDashboards();
|
4819
|
+
this.dashboardsLoaded = signal(false);
|
4820
|
+
// Effects
|
4821
|
+
this.#initEffect = effect(() => {
|
4822
|
+
const allDashboards = this.store.availableDashboards();
|
4803
4823
|
if (allDashboards.length > 0 && !this.dashboardsLoaded()) {
|
4804
4824
|
this.dashboardsLoaded.set(true);
|
4805
|
-
// Apply dashboard filtering now that dashboards are loaded
|
4806
4825
|
this.applyDashboardFiltering();
|
4826
|
+
this.recompute();
|
4807
4827
|
}
|
4808
4828
|
});
|
4809
|
-
this.#loadingEffect = effect(() => {
|
4810
|
-
const isLoading = false; // Since store doesn't have isLoading, we'll default to false
|
4811
|
-
this.layoutService.setNavigationLoading(isLoading);
|
4812
|
-
});
|
4813
4829
|
}
|
4814
|
-
|
4815
|
-
//#region ---------------- Lifecycle Methods ----------------
|
4830
|
+
// Lifecycle Hooks
|
4816
4831
|
async ngOnInit() {
|
4817
|
-
// Get the child route if it exists
|
4818
4832
|
const childRoute = this.activatedRoute.firstChild || this.activatedRoute;
|
4819
4833
|
childRoute.data.subscribe((data) => {
|
4820
4834
|
const isAdmin = data['isAdmin'] ?? false;
|
4821
|
-
// Set isAdmin state in the store
|
4822
4835
|
this.store.setIsAdmin(isAdmin);
|
4823
4836
|
});
|
4824
4837
|
}
|
4838
|
+
// Effects
|
4839
|
+
#initEffect;
|
4840
|
+
// Private Methods
|
4825
4841
|
applyDashboardFiltering() {
|
4826
|
-
|
4827
|
-
this.store.filterDashboardsByScope(this.store.isAdmin());
|
4828
|
-
}
|
4829
|
-
//#endregion
|
4830
|
-
//#region ---------------- Effects ----------------
|
4831
|
-
// Create an effect to watch for dashboards loading
|
4832
|
-
#dashboardsEffect;
|
4833
|
-
#loadingEffect;
|
4834
|
-
//#endregion
|
4835
|
-
//#region ---------------- Event Handlers ----------------
|
4836
|
-
toggleEdit() {
|
4837
|
-
this.isEdited.update((value) => !value);
|
4842
|
+
this.store.filterDashboardsByScope(this.store.isUserAdmin());
|
4838
4843
|
}
|
4839
4844
|
async confirmWidgetDelete(dashboardId, widgetId) {
|
4840
4845
|
try {
|
@@ -4847,24 +4852,21 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4847
4852
|
console.error('Error confirming widget deletion:', error);
|
4848
4853
|
}
|
4849
4854
|
}
|
4850
|
-
|
4855
|
+
// Page Interface Implementation
|
4851
4856
|
getPageTitle() {
|
4852
|
-
return this.store.
|
4857
|
+
return this.store.selectedDashboard()?.title || 'Dashboard';
|
4853
4858
|
}
|
4854
4859
|
async getPageDescription() {
|
4855
|
-
return this.store.
|
4860
|
+
return this.store.selectedDashboard()?.description || '';
|
4856
4861
|
}
|
4857
4862
|
getTitleActions() {
|
4858
|
-
return
|
4859
|
-
|
4860
|
-
|
4861
|
-
|
4862
|
-
|
4863
|
-
})),
|
4864
|
-
];
|
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
|
+
}));
|
4865
4868
|
}
|
4866
4869
|
async getPrimaryMenuItems() {
|
4867
|
-
const scope = this.rootConfig.config.i18n;
|
4868
4870
|
return [
|
4869
4871
|
{
|
4870
4872
|
title: 't("add-item")',
|
@@ -4875,74 +4877,78 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4875
4877
|
title: await this.translateService.translateAsync('dashboard', { scope: 'dashboard' }),
|
4876
4878
|
icon: 'fa-light fa-gauge-high',
|
4877
4879
|
break: true,
|
4878
|
-
command: {
|
4879
|
-
name: 'new-dashboard',
|
4880
|
-
},
|
4880
|
+
command: { name: 'new-dashboard' },
|
4881
4881
|
},
|
4882
4882
|
{
|
4883
4883
|
title: await this.translateService.translateAsync('widget', { scope: 'dashboard' }),
|
4884
4884
|
icon: 'fa-light fa-window-restore',
|
4885
|
-
command: {
|
4886
|
-
|
4887
|
-
},
|
4885
|
+
command: { name: 'new-widget' },
|
4886
|
+
disabled: this.store.dashboards().length < 1,
|
4888
4887
|
},
|
4889
4888
|
],
|
4890
4889
|
},
|
4891
4890
|
];
|
4892
4891
|
}
|
4893
4892
|
async getSecondaryMenuItems() {
|
4894
|
-
const scope = this.rootConfig.config.i18n;
|
4895
4893
|
const items = [
|
4896
4894
|
{
|
4897
|
-
title: await this.translateService.translateAsync('
|
4898
|
-
icon: 'fa-light fa-
|
4899
|
-
color: '
|
4895
|
+
title: await this.translateService.translateAsync('edit'),
|
4896
|
+
icon: 'fa-light fa-pen',
|
4897
|
+
color: 'primary',
|
4900
4898
|
disabled: this.store.dashboards().length < 1,
|
4901
|
-
command: {
|
4902
|
-
name: 'delete',
|
4903
|
-
},
|
4899
|
+
command: { name: 'edit' },
|
4904
4900
|
},
|
4905
4901
|
];
|
4906
|
-
|
4907
|
-
if (!this.store.isAdmin()) {
|
4902
|
+
if (!this.store.isUserAdmin() && this.themeService.isDesktopDevice()) {
|
4908
4903
|
items.push({
|
4909
|
-
title: await this.translateService.translateAsync(this.store.isDashboardLocked() ? 'unlock
|
4904
|
+
title: await this.translateService.translateAsync(this.store.isDashboardLocked() ? 'unlock' : 'lock', {
|
4905
|
+
scope: 'dashboard',
|
4906
|
+
}),
|
4910
4907
|
icon: this.store.isDashboardLocked() ? 'fa-light fa-lock-open' : 'fa-light fa-lock',
|
4911
4908
|
color: 'accent3',
|
4912
4909
|
disabled: this.store.dashboards().length < 1,
|
4913
|
-
command: {
|
4914
|
-
name: 'toggle-lock',
|
4915
|
-
},
|
4910
|
+
command: { name: 'toggle-lock' },
|
4916
4911
|
});
|
4917
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
|
+
});
|
4918
4920
|
return items;
|
4919
4921
|
}
|
4920
4922
|
async execute(command) {
|
4921
4923
|
if (command.metadata?.['isDashboard']) {
|
4922
4924
|
this.store.handleConfigChange(command.metadata?.['dashboard']);
|
4923
4925
|
this.recompute();
|
4926
|
+
return;
|
4924
4927
|
}
|
4925
|
-
|
4926
|
-
|
4927
|
-
|
4928
|
-
|
4929
|
-
|
4930
|
-
|
4931
|
-
|
4932
|
-
|
4933
|
-
|
4934
|
-
|
4935
|
-
|
4936
|
-
|
4937
|
-
|
4938
|
-
|
4939
|
-
|
4940
|
-
|
4941
|
-
|
4942
|
-
|
4943
|
-
|
4944
|
-
|
4945
|
-
|
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;
|
4946
4952
|
}
|
4947
4953
|
}
|
4948
4954
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMDashboardHomeComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
@@ -4953,7 +4959,7 @@ class AXMDashboardHomeComponent extends AXPBasePageComponent {
|
|
4953
4959
|
provide: AXPBasePage,
|
4954
4960
|
useExisting: AXMDashboardHomeComponent,
|
4955
4961
|
},
|
4956
|
-
], usesInheritance: true, ngImport: i0, template: "<axp-page-layout *translate=\"let t\">\n <!-- Content Section -->\n\n <axp-page-content class=\"ax-relative\">\n @if(store.isLoading()) {\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-w-full ax-absolute ax-z-10 ax-bg-white/80\"\n >\n <ax-loading></ax-loading>\n <p class=\"ax-mt-3 ax-text-gray-600\">{{ t('loading', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else {\n <axp-widgets-container [context]=\"context()\">\n <ax-grid-layout-container [options]=\"store.
|
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 }); }
|
4957
4963
|
}
|
4958
4964
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: AXMDashboardHomeComponent, decorators: [{
|
4959
4965
|
type: Component,
|
@@ -4979,7 +4985,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImpo
|
|
4979
4985
|
provide: AXPBasePage,
|
4980
4986
|
useExisting: AXMDashboardHomeComponent,
|
4981
4987
|
},
|
4982
|
-
], template: "<axp-page-layout *translate=\"let t\">\n <!-- Content Section -->\n\n <axp-page-content class=\"ax-relative\">\n @if(store.isLoading()) {\n <div\n class=\"ax-flex ax-flex-col ax-items-center ax-justify-center ax-h-full ax-w-full ax-absolute ax-z-10 ax-bg-white/80\"\n >\n <ax-loading></ax-loading>\n <p class=\"ax-mt-3 ax-text-gray-600\">{{ t('loading', { scope: 'dashboard' }) | async }}</p>\n </div>\n } @else {\n <axp-widgets-container [context]=\"context()\">\n <ax-grid-layout-container [options]=\"store.
|
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"] }]
|
4983
4989
|
}] });
|
4984
4990
|
|
4985
4991
|
var homeDashboard = /*#__PURE__*/Object.freeze({
|