@fidurcode/dashboard-widgets-skeleton 1.0.4 → 1.0.5

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.
@@ -0,0 +1,199 @@
1
+ import * as i0 from '@angular/core';
2
+ import { signal, computed, effect, Injectable, input, model, inject, Component, viewChild, NgModule } from '@angular/core';
3
+ import * as i1$1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import * as i2 from '@angular/material/button';
6
+ import { MatButtonModule } from '@angular/material/button';
7
+ import * as i3 from '@angular/material/icon';
8
+ import { MatIconModule } from '@angular/material/icon';
9
+ import * as i1 from '@angular/material/button-toggle';
10
+ import { MatButtonToggleModule } from '@angular/material/button-toggle';
11
+ import { wrapGrid } from 'animate-css-grid';
12
+ import * as i1$2 from '@angular/material/menu';
13
+ import { MatMenuModule } from '@angular/material/menu';
14
+
15
+ class WidgetService {
16
+ widgets = signal([], ...(ngDevMode ? [{ debugName: "widgets" }] : []));
17
+ addedWidgets = signal([], ...(ngDevMode ? [{ debugName: "addedWidgets" }] : []));
18
+ widgetsToAdd = computed(() => {
19
+ const addedIds = this.addedWidgets().map((widget) => widget.id);
20
+ return this.widgets().filter((w) => !addedIds.includes(w.id));
21
+ }, ...(ngDevMode ? [{ debugName: "widgetsToAdd" }] : []));
22
+ constructor() {
23
+ this.fetchWidgets();
24
+ }
25
+ fetchWidgets() {
26
+ const widgetsAsString = localStorage.getItem('dashboardWidgets');
27
+ if (widgetsAsString) {
28
+ const widgets = JSON.parse(widgetsAsString);
29
+ widgets.forEach((widget) => {
30
+ const content = this.widgets().find((w) => w.id === widget.id)?.content;
31
+ if (content) {
32
+ widget.content = content;
33
+ }
34
+ });
35
+ this.addedWidgets.set(widgets);
36
+ }
37
+ }
38
+ setAvailableWidgets(widgets) {
39
+ this.widgets.set(widgets);
40
+ }
41
+ addWidget(widget) {
42
+ this.addedWidgets.set([...this.addedWidgets(), { ...widget }]);
43
+ }
44
+ updateWidget(id, widget) {
45
+ const index = this.addedWidgets().findIndex((w) => w.id === id);
46
+ if (index !== -1) {
47
+ const newWidgets = [...this.addedWidgets()];
48
+ newWidgets[index] = { ...newWidgets[index], ...widget };
49
+ this.addedWidgets.set(newWidgets);
50
+ }
51
+ }
52
+ moveWidgetToLeft(id) {
53
+ const index = this.addedWidgets().findIndex((w) => w.id === id);
54
+ if (index == 0)
55
+ return;
56
+ const newWidgets = [...this.addedWidgets()];
57
+ [newWidgets[index], newWidgets[index - 1]] = [
58
+ { ...newWidgets[index - 1] },
59
+ { ...newWidgets[index] },
60
+ ];
61
+ this.addedWidgets.set(newWidgets);
62
+ }
63
+ moveWidgetToRight(id) {
64
+ const index = this.addedWidgets().findIndex((w) => w.id === id);
65
+ if (index == this.addedWidgets().length - 1)
66
+ return;
67
+ const newWidgets = [...this.addedWidgets()];
68
+ [newWidgets[index], newWidgets[index + 1]] = [
69
+ { ...newWidgets[index + 1] },
70
+ { ...newWidgets[index] },
71
+ ];
72
+ this.addedWidgets.set(newWidgets);
73
+ }
74
+ deleteWidget(id) {
75
+ this.addedWidgets.set(this.addedWidgets().filter((w) => w.id !== id));
76
+ }
77
+ saveWidgets = effect(() => {
78
+ const widgetsWithoutContent = this.addedWidgets().map(w => ({ ...w }));
79
+ widgetsWithoutContent.forEach(widget => {
80
+ delete widget.content;
81
+ });
82
+ localStorage.setItem('dashboardWidgets', JSON.stringify(widgetsWithoutContent));
83
+ }, ...(ngDevMode ? [{ debugName: "saveWidgets" }] : []));
84
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: WidgetService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
85
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: WidgetService });
86
+ }
87
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: WidgetService, decorators: [{
88
+ type: Injectable
89
+ }], ctorParameters: () => [] });
90
+
91
+ class WidgetOptionsComponent {
92
+ widget = input.required(...(ngDevMode ? [{ debugName: "widget" }] : []));
93
+ showOptions = model(false, ...(ngDevMode ? [{ debugName: "showOptions" }] : []));
94
+ store = inject(WidgetService);
95
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: WidgetOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
96
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.2", type: WidgetOptionsComponent, isStandalone: false, selector: "app-widget-options", inputs: { widget: { classPropertyName: "widget", publicName: "widget", isSignal: true, isRequired: true, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { showOptions: "showOptionsChange" }, ngImport: i0, template: "<button (click)=\"showOptions.set(false)\" class=\"close-button\" mat-icon-button>\n <mat-icon>close</mat-icon>\n</button>\n\n<div (click)=\"store.moveWidgetToRight(widget().id)\" class=\"move-forward-button\">\n <mat-icon>chevron_right</mat-icon>\n</div>\n\n<div (click)=\"store.moveWidgetToLeft(widget().id)\" class=\"move-backward-button\">\n <mat-icon>chevron_left</mat-icon>\n</div>\n\n<div (click)=\"store.deleteWidget(widget().id)\" class=\"remove-widget-button\">\n <mat-icon>delete</mat-icon>\n</div>\n\n<div>\n Width\n <mat-button-toggle-group\n (change)=\"store.updateWidget(widget().id, { columns: +$event.value })\"\n [hideSingleSelectionIndicator]=\"true\"\n [value]=\"widget().columns ?? 1\">\n <mat-button-toggle [value]=\"1\">1</mat-button-toggle>\n <mat-button-toggle [value]=\"2\">2</mat-button-toggle>\n <mat-button-toggle [value]=\"3\">3</mat-button-toggle>\n <mat-button-toggle [value]=\"4\">4</mat-button-toggle>\n </mat-button-toggle-group>\n</div>\n\n<div>\n Height\n <mat-button-toggle-group\n (change)=\"store.updateWidget(widget().id, { rows: +$event.value })\"\n [hideSingleSelectionIndicator]=\"true\"\n [value]=\"widget().rows ?? 1\">\n <mat-button-toggle [value]=\"1\">1</mat-button-toggle>\n <mat-button-toggle [value]=\"2\">2</mat-button-toggle>\n <mat-button-toggle [value]=\"3\">3</mat-button-toggle>\n <mat-button-toggle [value]=\"4\">4</mat-button-toggle>\n </mat-button-toggle-group>\n</div>", styles: [":host{position:absolute;z-index:2;background:inherit;color:inherit;top:0;left:0;border-radius:inherit;width:100%;height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;box-sizing:border-box;--mat-standard-button-toggle-height: 9px}:host>div{display:flex;gap:8px;align-items:center;margin-left:8px}.close-button{position:absolute;top:0;right:0}.move-forward-button{position:absolute;top:50%;transform:translateY(-50%);right:-5px}.move-backward-button{position:absolute;top:50%;transform:translateY(-50%);left:-5px}.remove-widget-button{position:absolute;top:0;left:0;padding:5px}\n"], dependencies: [{ kind: "directive", type: i1.MatButtonToggleGroup, selector: "mat-button-toggle-group", inputs: ["appearance", "name", "vertical", "value", "multiple", "disabled", "disabledInteractive", "hideSingleSelectionIndicator", "hideMultipleSelectionIndicator"], outputs: ["valueChange", "change"], exportAs: ["matButtonToggleGroup"] }, { kind: "component", type: i1.MatButtonToggle, selector: "mat-button-toggle", inputs: ["aria-label", "aria-labelledby", "id", "name", "value", "tabIndex", "disableRipple", "appearance", "checked", "disabled", "disabledInteractive"], outputs: ["change"], exportAs: ["matButtonToggle"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
97
+ }
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: WidgetOptionsComponent, decorators: [{
99
+ type: Component,
100
+ args: [{ selector: 'app-widget-options', standalone: false, template: "<button (click)=\"showOptions.set(false)\" class=\"close-button\" mat-icon-button>\n <mat-icon>close</mat-icon>\n</button>\n\n<div (click)=\"store.moveWidgetToRight(widget().id)\" class=\"move-forward-button\">\n <mat-icon>chevron_right</mat-icon>\n</div>\n\n<div (click)=\"store.moveWidgetToLeft(widget().id)\" class=\"move-backward-button\">\n <mat-icon>chevron_left</mat-icon>\n</div>\n\n<div (click)=\"store.deleteWidget(widget().id)\" class=\"remove-widget-button\">\n <mat-icon>delete</mat-icon>\n</div>\n\n<div>\n Width\n <mat-button-toggle-group\n (change)=\"store.updateWidget(widget().id, { columns: +$event.value })\"\n [hideSingleSelectionIndicator]=\"true\"\n [value]=\"widget().columns ?? 1\">\n <mat-button-toggle [value]=\"1\">1</mat-button-toggle>\n <mat-button-toggle [value]=\"2\">2</mat-button-toggle>\n <mat-button-toggle [value]=\"3\">3</mat-button-toggle>\n <mat-button-toggle [value]=\"4\">4</mat-button-toggle>\n </mat-button-toggle-group>\n</div>\n\n<div>\n Height\n <mat-button-toggle-group\n (change)=\"store.updateWidget(widget().id, { rows: +$event.value })\"\n [hideSingleSelectionIndicator]=\"true\"\n [value]=\"widget().rows ?? 1\">\n <mat-button-toggle [value]=\"1\">1</mat-button-toggle>\n <mat-button-toggle [value]=\"2\">2</mat-button-toggle>\n <mat-button-toggle [value]=\"3\">3</mat-button-toggle>\n <mat-button-toggle [value]=\"4\">4</mat-button-toggle>\n </mat-button-toggle-group>\n</div>", styles: [":host{position:absolute;z-index:2;background:inherit;color:inherit;top:0;left:0;border-radius:inherit;width:100%;height:100%;display:flex;flex-direction:column;justify-content:center;align-items:center;box-sizing:border-box;--mat-standard-button-toggle-height: 9px}:host>div{display:flex;gap:8px;align-items:center;margin-left:8px}.close-button{position:absolute;top:0;right:0}.move-forward-button{position:absolute;top:50%;transform:translateY(-50%);right:-5px}.move-backward-button{position:absolute;top:50%;transform:translateY(-50%);left:-5px}.remove-widget-button{position:absolute;top:0;left:0;padding:5px}\n"] }]
101
+ }] });
102
+
103
+ class WidgetComponent {
104
+ data = input.required(...(ngDevMode ? [{ debugName: "data" }] : []));
105
+ showWidgetOptions = signal(false, ...(ngDevMode ? [{ debugName: "showWidgetOptions" }] : []));
106
+ get gridArea() {
107
+ const widget = this.data();
108
+ return `span ${widget.rows ?? 1} / span ${widget.columns ?? 1}`;
109
+ }
110
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: WidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
111
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.2", type: WidgetComponent, isStandalone: false, selector: "app-widget", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "style.grid-area": "gridArea" } }, ngImport: i0, template: "<div\n class=\"widget-container mat-elevation-z3\"\n>\n <h3 class=\"m-0\">{{ data().label }}</h3>\n <button (click)=\"showWidgetOptions.set(true)\" class=\"settings-button\" mat-icon-button>\n <mat-icon>settings</mat-icon>\n </button>\n\n <ng-container [ngComponentOutlet]=\"data().content\"/>\n\n @if (showWidgetOptions()) {\n <app-widget-options [(showOptions)]=\"showWidgetOptions\" [widget]=\"data()\"/>\n }\n</div>", styles: [":host{display:block;border-radius:16px}.widget-container{position:relative;height:100%;width:100%;padding:32px;box-sizing:border-box;border-radius:inherit;overflow:hidden;background-color:var(--mat-sys-background);cursor:pointer}.settings-button{position:absolute;top:20px;right:20px}\n"], dependencies: [{ kind: "directive", type: i1$1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: WidgetOptionsComponent, selector: "app-widget-options", inputs: ["widget", "showOptions"], outputs: ["showOptionsChange"] }] });
112
+ }
113
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: WidgetComponent, decorators: [{
114
+ type: Component,
115
+ args: [{ selector: 'app-widget', standalone: false, host: {
116
+ '[style.grid-area]': 'gridArea',
117
+ }, template: "<div\n class=\"widget-container mat-elevation-z3\"\n>\n <h3 class=\"m-0\">{{ data().label }}</h3>\n <button (click)=\"showWidgetOptions.set(true)\" class=\"settings-button\" mat-icon-button>\n <mat-icon>settings</mat-icon>\n </button>\n\n <ng-container [ngComponentOutlet]=\"data().content\"/>\n\n @if (showWidgetOptions()) {\n <app-widget-options [(showOptions)]=\"showWidgetOptions\" [widget]=\"data()\"/>\n }\n</div>", styles: [":host{display:block;border-radius:16px}.widget-container{position:relative;height:100%;width:100%;padding:32px;box-sizing:border-box;border-radius:inherit;overflow:hidden;background-color:var(--mat-sys-background);cursor:pointer}.settings-button{position:absolute;top:20px;right:20px}\n"] }]
118
+ }] });
119
+
120
+ class DashboardWidgetsComponent {
121
+ widgets = input.required(...(ngDevMode ? [{ debugName: "widgets" }] : []));
122
+ store = inject(WidgetService);
123
+ dashboard = viewChild.required('dashboard');
124
+ ngOnInit() {
125
+ wrapGrid(this.dashboard().nativeElement, { duration: 300 });
126
+ if (this.widgets()?.length > 0) {
127
+ this.store.setAvailableWidgets(this.widgets());
128
+ }
129
+ }
130
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: DashboardWidgetsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
131
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.2", type: DashboardWidgetsComponent, isStandalone: false, selector: "fidurcode-dashboard-widgets", inputs: { widgets: { classPropertyName: "widgets", publicName: "widgets", isSignal: true, isRequired: true, transformFunction: null } }, providers: [WidgetService], viewQueries: [{ propertyName: "dashboard", first: true, predicate: ["dashboard"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"dashboard-widgets-header\">\n <h2>Dashboard</h2>\n <button [matMenuTriggerFor]=\"menu\" mat-raised-button>\n <mat-icon>add_circle</mat-icon>\n Add widget\n </button>\n <mat-menu #menu=\"matMenu\">\n @for (widget of store.widgetsToAdd(); track widget.id) {\n <button mat-menu-item (click)=\"store.addWidget(widget)\">{{ widget.label }}</button>\n } @empty {\n <button mat-menu-item>No widget to add</button>\n }\n </mat-menu>\n</div>\n<div #dashboard class=\"dashboard-widgets\">\n @for (w of store.addedWidgets(); track w.id) {\n <app-widget [data]=\"w\"/>\n }\n</div>", styles: [".dashboard-widgets-header{display:flex;justify-content:space-between;align-items:center}.dashboard-widgets{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));grid-auto-rows:150px;gap:16px}\n"], dependencies: [{ kind: "component", type: i1$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: WidgetComponent, selector: "app-widget", inputs: ["data"] }] });
132
+ }
133
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: DashboardWidgetsComponent, decorators: [{
134
+ type: Component,
135
+ args: [{ selector: 'fidurcode-dashboard-widgets', standalone: false, providers: [WidgetService], template: "<div class=\"dashboard-widgets-header\">\n <h2>Dashboard</h2>\n <button [matMenuTriggerFor]=\"menu\" mat-raised-button>\n <mat-icon>add_circle</mat-icon>\n Add widget\n </button>\n <mat-menu #menu=\"matMenu\">\n @for (widget of store.widgetsToAdd(); track widget.id) {\n <button mat-menu-item (click)=\"store.addWidget(widget)\">{{ widget.label }}</button>\n } @empty {\n <button mat-menu-item>No widget to add</button>\n }\n </mat-menu>\n</div>\n<div #dashboard class=\"dashboard-widgets\">\n @for (w of store.addedWidgets(); track w.id) {\n <app-widget [data]=\"w\"/>\n }\n</div>", styles: [".dashboard-widgets-header{display:flex;justify-content:space-between;align-items:center}.dashboard-widgets{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));grid-auto-rows:150px;gap:16px}\n"] }]
136
+ }] });
137
+
138
+ class DashboardWidgetsSkeletonModule {
139
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: DashboardWidgetsSkeletonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
140
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.2", ngImport: i0, type: DashboardWidgetsSkeletonModule, declarations: [WidgetComponent,
141
+ WidgetOptionsComponent,
142
+ DashboardWidgetsComponent], imports: [CommonModule,
143
+ MatMenuModule,
144
+ MatButtonToggleModule,
145
+ MatButtonModule,
146
+ MatIconModule], exports: [WidgetComponent,
147
+ WidgetOptionsComponent,
148
+ DashboardWidgetsComponent,
149
+ MatMenuModule,
150
+ MatButtonToggleModule,
151
+ MatButtonModule,
152
+ MatIconModule] });
153
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: DashboardWidgetsSkeletonModule, providers: [WidgetService], imports: [CommonModule,
154
+ MatMenuModule,
155
+ MatButtonToggleModule,
156
+ MatButtonModule,
157
+ MatIconModule, MatMenuModule,
158
+ MatButtonToggleModule,
159
+ MatButtonModule,
160
+ MatIconModule] });
161
+ }
162
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.2", ngImport: i0, type: DashboardWidgetsSkeletonModule, decorators: [{
163
+ type: NgModule,
164
+ args: [{
165
+ declarations: [
166
+ WidgetComponent,
167
+ WidgetOptionsComponent,
168
+ DashboardWidgetsComponent,
169
+ ],
170
+ imports: [
171
+ CommonModule,
172
+ MatMenuModule,
173
+ MatButtonToggleModule,
174
+ MatButtonModule,
175
+ MatIconModule,
176
+ ],
177
+ exports: [
178
+ WidgetComponent,
179
+ WidgetOptionsComponent,
180
+ DashboardWidgetsComponent,
181
+ MatMenuModule,
182
+ MatButtonToggleModule,
183
+ MatButtonModule,
184
+ MatIconModule,
185
+ ],
186
+ providers: [WidgetService]
187
+ }]
188
+ }] });
189
+
190
+ /*
191
+ * Public API Surface of dashboard-widgets-skeleton
192
+ */
193
+
194
+ /**
195
+ * Generated bundle index. Do not edit.
196
+ */
197
+
198
+ export { DashboardWidgetsComponent, DashboardWidgetsSkeletonModule, WidgetComponent, WidgetOptionsComponent, WidgetService };
199
+ //# sourceMappingURL=fidurcode-dashboard-widgets-skeleton.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fidurcode-dashboard-widgets-skeleton.mjs","sources":["../../../projects/dashboard-widgets-skeleton/src/lib/services/widget.service.ts","../../../projects/dashboard-widgets-skeleton/src/lib/components/widget-options/widget-options.component.ts","../../../projects/dashboard-widgets-skeleton/src/lib/components/widget-options/widget-options.component.html","../../../projects/dashboard-widgets-skeleton/src/lib/components/widget/widget.component.ts","../../../projects/dashboard-widgets-skeleton/src/lib/components/widget/widget.component.html","../../../projects/dashboard-widgets-skeleton/src/lib/components/dashboard-widgets/dashboard-widgets.component.ts","../../../projects/dashboard-widgets-skeleton/src/lib/components/dashboard-widgets/dashboard-widgets.component.html","../../../projects/dashboard-widgets-skeleton/src/lib/dashboard-widgets-skeleton.module.ts","../../../projects/dashboard-widgets-skeleton/src/public-api.ts","../../../projects/dashboard-widgets-skeleton/src/fidurcode-dashboard-widgets-skeleton.ts"],"sourcesContent":["import {\n computed, effect, EffectRef,\n Injectable,\n Signal,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport { Widget } from '../components/widget/widget';\n\n@Injectable()\nexport class WidgetService {\n public widgets: WritableSignal<Widget[]> = signal<Widget[]>([]);\n addedWidgets: WritableSignal<Widget[]> = signal<Widget[]>([]);\n\n widgetsToAdd: Signal<Widget[]> = computed((): Widget[] => {\n const addedIds: number[] = this.addedWidgets().map(\n (widget: Widget): number => widget.id,\n );\n return this.widgets().filter((w): boolean => !addedIds.includes(w.id));\n });\n\n constructor() {\n this.fetchWidgets();\n }\n\n fetchWidgets(): void {\n const widgetsAsString = localStorage.getItem('dashboardWidgets');\n if (widgetsAsString) {\n const widgets = JSON.parse(widgetsAsString);\n widgets.forEach((widget: Widget): void => {\n const content = this.widgets().find((w: Widget): boolean => w.id === widget.id)?.content;\n if (content) {\n widget.content = content;\n }\n });\n\n this.addedWidgets.set(widgets);\n }\n }\n\n setAvailableWidgets(widgets: Widget[]): void {\n this.widgets.set(widgets);\n }\n\n addWidget(widget: Widget): void {\n this.addedWidgets.set([...this.addedWidgets(), { ...widget }]);\n }\n\n updateWidget(id: number, widget: Partial<Widget>): void {\n const index = this.addedWidgets().findIndex((w) => w.id === id);\n if (index !== -1) {\n const newWidgets = [...this.addedWidgets()];\n newWidgets[index] = { ...newWidgets[index], ...widget };\n this.addedWidgets.set(newWidgets);\n }\n }\n\n moveWidgetToLeft(id: number): void {\n const index = this.addedWidgets().findIndex((w) => w.id === id);\n if (index == 0) return;\n const newWidgets = [...this.addedWidgets()];\n [newWidgets[index], newWidgets[index - 1]] = [\n { ...newWidgets[index - 1] },\n { ...newWidgets[index] },\n ];\n\n this.addedWidgets.set(newWidgets);\n }\n\n moveWidgetToRight(id: number): void {\n const index = this.addedWidgets().findIndex((w) => w.id === id);\n if (index == this.addedWidgets().length - 1) return;\n const newWidgets = [...this.addedWidgets()];\n [newWidgets[index], newWidgets[index + 1]] = [\n { ...newWidgets[index + 1] },\n { ...newWidgets[index] },\n ];\n\n this.addedWidgets.set(newWidgets);\n }\n\n deleteWidget(id: number): void {\n this.addedWidgets.set(this.addedWidgets().filter((w) => w.id !== id));\n }\n\n saveWidgets = effect((): void => {\n const widgetsWithoutContent: Partial<Widget>[] = this.addedWidgets().map(w => ({...w}));\n widgetsWithoutContent.forEach(widget => {\n delete widget.content;\n });\n\n localStorage.setItem('dashboardWidgets', JSON.stringify(widgetsWithoutContent));\n });\n}\n","import {\n Component,\n inject,\n input,\n InputSignal,\n model,\n ModelSignal,\n} from '@angular/core';\nimport { Widget } from '../widget/widget';\nimport { WidgetService } from '../../services/widget.service';\n\n@Component({\n selector: 'app-widget-options',\n standalone: false,\n templateUrl: './widget-options.component.html',\n styleUrl: './widget-options.component.scss',\n})\nexport class WidgetOptionsComponent {\n widget: InputSignal<Widget> = input.required<Widget>();\n showOptions: ModelSignal<boolean> = model<boolean>(false);\n\n store = inject(WidgetService);\n}\n","<button (click)=\"showOptions.set(false)\" class=\"close-button\" mat-icon-button>\n <mat-icon>close</mat-icon>\n</button>\n\n<div (click)=\"store.moveWidgetToRight(widget().id)\" class=\"move-forward-button\">\n <mat-icon>chevron_right</mat-icon>\n</div>\n\n<div (click)=\"store.moveWidgetToLeft(widget().id)\" class=\"move-backward-button\">\n <mat-icon>chevron_left</mat-icon>\n</div>\n\n<div (click)=\"store.deleteWidget(widget().id)\" class=\"remove-widget-button\">\n <mat-icon>delete</mat-icon>\n</div>\n\n<div>\n Width\n <mat-button-toggle-group\n (change)=\"store.updateWidget(widget().id, { columns: +$event.value })\"\n [hideSingleSelectionIndicator]=\"true\"\n [value]=\"widget().columns ?? 1\">\n <mat-button-toggle [value]=\"1\">1</mat-button-toggle>\n <mat-button-toggle [value]=\"2\">2</mat-button-toggle>\n <mat-button-toggle [value]=\"3\">3</mat-button-toggle>\n <mat-button-toggle [value]=\"4\">4</mat-button-toggle>\n </mat-button-toggle-group>\n</div>\n\n<div>\n Height\n <mat-button-toggle-group\n (change)=\"store.updateWidget(widget().id, { rows: +$event.value })\"\n [hideSingleSelectionIndicator]=\"true\"\n [value]=\"widget().rows ?? 1\">\n <mat-button-toggle [value]=\"1\">1</mat-button-toggle>\n <mat-button-toggle [value]=\"2\">2</mat-button-toggle>\n <mat-button-toggle [value]=\"3\">3</mat-button-toggle>\n <mat-button-toggle [value]=\"4\">4</mat-button-toggle>\n </mat-button-toggle-group>\n</div>","import {\n Component,\n input,\n InputSignal,\n signal,\n WritableSignal,\n} from '@angular/core';\nimport { Widget } from './widget';\n\n@Component({\n selector: 'app-widget',\n standalone: false,\n templateUrl: './widget.component.html',\n styleUrl: './widget.component.scss',\n host: {\n '[style.grid-area]': 'gridArea',\n },\n})\nexport class WidgetComponent {\n data: InputSignal<Widget> = input.required<Widget>();\n\n showWidgetOptions: WritableSignal<boolean> = signal<boolean>(false);\n\n get gridArea(): string {\n const widget: Widget = this.data();\n return `span ${widget.rows ?? 1} / span ${widget.columns ?? 1}`;\n }\n}\n","<div\n class=\"widget-container mat-elevation-z3\"\n>\n <h3 class=\"m-0\">{{ data().label }}</h3>\n <button (click)=\"showWidgetOptions.set(true)\" class=\"settings-button\" mat-icon-button>\n <mat-icon>settings</mat-icon>\n </button>\n\n <ng-container [ngComponentOutlet]=\"data().content\"/>\n\n @if (showWidgetOptions()) {\n <app-widget-options [(showOptions)]=\"showWidgetOptions\" [widget]=\"data()\"/>\n }\n</div>","import {\n Component,\n ElementRef,\n inject, input, Input, InputSignal,\n OnInit,\n viewChild,\n} from '@angular/core';\nimport { WidgetService } from '../../services/widget.service';\nimport { wrapGrid } from 'animate-css-grid';\nimport {Widget} from '../widget/widget';\n\n@Component({\n selector: 'fidurcode-dashboard-widgets',\n standalone: false,\n templateUrl: './dashboard-widgets.component.html',\n styleUrl: './dashboard-widgets.component.scss',\n providers: [WidgetService],\n})\nexport class DashboardWidgetsComponent implements OnInit {\n widgets: InputSignal<Widget[]> = input.required<Widget[]>();\n\n store = inject(WidgetService);\n\n dashboard = viewChild.required<ElementRef>('dashboard');\n\n ngOnInit(): void {\n wrapGrid(this.dashboard().nativeElement, { duration: 300 });\n\n if (this.widgets()?.length > 0) {\n this.store.setAvailableWidgets(this.widgets());\n }\n }\n}\n","<div class=\"dashboard-widgets-header\">\n <h2>Dashboard</h2>\n <button [matMenuTriggerFor]=\"menu\" mat-raised-button>\n <mat-icon>add_circle</mat-icon>\n Add widget\n </button>\n <mat-menu #menu=\"matMenu\">\n @for (widget of store.widgetsToAdd(); track widget.id) {\n <button mat-menu-item (click)=\"store.addWidget(widget)\">{{ widget.label }}</button>\n } @empty {\n <button mat-menu-item>No widget to add</button>\n }\n </mat-menu>\n</div>\n<div #dashboard class=\"dashboard-widgets\">\n @for (w of store.addedWidgets(); track w.id) {\n <app-widget [data]=\"w\"/>\n }\n</div>","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { WidgetComponent } from './components/widget/widget.component';\nimport { WidgetOptionsComponent } from './components/widget-options/widget-options.component';\nimport { DashboardWidgetsComponent } from './components/dashboard-widgets/dashboard-widgets.component';\nimport { WidgetService } from './services/widget.service';\n\nimport { MatMenuModule } from '@angular/material/menu';\nimport { MatButtonToggleModule } from '@angular/material/button-toggle';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\n\n@NgModule({\n declarations: [\n WidgetComponent,\n WidgetOptionsComponent,\n DashboardWidgetsComponent,\n ],\n imports: [\n CommonModule,\n MatMenuModule,\n MatButtonToggleModule,\n MatButtonModule,\n MatIconModule,\n ],\n exports: [\n WidgetComponent,\n WidgetOptionsComponent,\n DashboardWidgetsComponent,\n MatMenuModule,\n MatButtonToggleModule,\n MatButtonModule,\n MatIconModule,\n ],\n providers: [WidgetService]\n})\nexport class DashboardWidgetsSkeletonModule {}\n","/*\n * Public API Surface of dashboard-widgets-skeleton\n */\n\nexport * from './lib/components/widget/widget.component';\nexport * from './lib/components/widget-options/widget-options.component';\nexport * from './lib/components/dashboard-widgets/dashboard-widgets.component';\nexport * from './lib/services/widget.service';\nexport * from './lib/dashboard-widgets-skeleton.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i4.WidgetOptionsComponent","i4.WidgetComponent"],"mappings":";;;;;;;;;;;;;;MAUa,aAAa,CAAA;AACjB,IAAA,OAAO,GAA6B,MAAM,CAAW,EAAE,mDAAC;AAC/D,IAAA,YAAY,GAA6B,MAAM,CAAW,EAAE,wDAAC;AAE7D,IAAA,YAAY,GAAqB,QAAQ,CAAC,MAAe;AACvD,QAAA,MAAM,QAAQ,GAAa,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,CAChD,CAAC,MAAc,KAAa,MAAM,CAAC,EAAE,CACtC;QACD,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACxE,IAAA,CAAC,wDAAC;AAEF,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,YAAY,EAAE;IACrB;IAEA,YAAY,GAAA;QACV,MAAM,eAAe,GAAG,YAAY,CAAC,OAAO,CAAC,kBAAkB,CAAC;QAChE,IAAI,eAAe,EAAE;YACnB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;AAC3C,YAAA,OAAO,CAAC,OAAO,CAAC,CAAC,MAAc,KAAU;gBACvC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAS,KAAc,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO;gBACxF,IAAI,OAAO,EAAE;AACX,oBAAA,MAAM,CAAC,OAAO,GAAG,OAAO;gBAC1B;AACF,YAAA,CAAC,CAAC;AAEF,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC;QAChC;IACF;AAEA,IAAA,mBAAmB,CAAC,OAAiB,EAAA;AACnC,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;IAC3B;AAEA,IAAA,SAAS,CAAC,MAAc,EAAA;AACtB,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IAChE;IAEA,YAAY,CAAC,EAAU,EAAE,MAAuB,EAAA;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;AAC/D,QAAA,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE;YAChB,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;AAC3C,YAAA,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,EAAE;AACvD,YAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC;QACnC;IACF;AAEA,IAAA,gBAAgB,CAAC,EAAU,EAAA;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QAC/D,IAAI,KAAK,IAAI,CAAC;YAAE;QAChB,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;AAC3C,QAAA,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG;AAC3C,YAAA,EAAE,GAAG,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE;AAC5B,YAAA,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE;SACzB;AAED,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC;IACnC;AAEA,IAAA,iBAAiB,CAAC,EAAU,EAAA;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QAC/D,IAAI,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,GAAG,CAAC;YAAE;QAC7C,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;AAC3C,QAAA,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG;AAC3C,YAAA,EAAE,GAAG,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE;AAC5B,YAAA,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE;SACzB;AAED,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC;IACnC;AAEA,IAAA,YAAY,CAAC,EAAU,EAAA;QACrB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACvE;AAEA,IAAA,WAAW,GAAG,MAAM,CAAC,MAAW;QAC9B,MAAM,qBAAqB,GAAsB,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAC,GAAG,CAAC,EAAC,CAAC,CAAC;AACvF,QAAA,qBAAqB,CAAC,OAAO,CAAC,MAAM,IAAG;YACrC,OAAO,MAAM,CAAC,OAAO;AACvB,QAAA,CAAC,CAAC;AAEF,QAAA,YAAY,CAAC,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;AACjF,IAAA,CAAC,uDAAC;uGAlFS,aAAa,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;2GAAb,aAAa,EAAA,CAAA;;2FAAb,aAAa,EAAA,UAAA,EAAA,CAAA;kBADzB;;;MCQY,sBAAsB,CAAA;AACjC,IAAA,MAAM,GAAwB,KAAK,CAAC,QAAQ,iDAAU;AACtD,IAAA,WAAW,GAAyB,KAAK,CAAU,KAAK,uDAAC;AAEzD,IAAA,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;uGAJlB,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,sBAAsB,8YCjBnC,48CAwCM,EAAA,MAAA,EAAA,CAAA,wmBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,yBAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,MAAA,EAAA,UAAA,EAAA,OAAA,EAAA,UAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,8BAAA,EAAA,gCAAA,CAAA,EAAA,OAAA,EAAA,CAAA,aAAA,EAAA,QAAA,CAAA,EAAA,QAAA,EAAA,CAAA,sBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,YAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,UAAA,EAAA,eAAA,EAAA,YAAA,EAAA,SAAA,EAAA,UAAA,EAAA,qBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,CAAA,EAAA,QAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,sFAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FDvBO,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBANlC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,oBAAoB,cAClB,KAAK,EAAA,QAAA,EAAA,48CAAA,EAAA,MAAA,EAAA,CAAA,wmBAAA,CAAA,EAAA;;;MEKN,eAAe,CAAA;AAC1B,IAAA,IAAI,GAAwB,KAAK,CAAC,QAAQ,+CAAU;AAEpD,IAAA,iBAAiB,GAA4B,MAAM,CAAU,KAAK,6DAAC;AAEnE,IAAA,IAAI,QAAQ,GAAA;AACV,QAAA,MAAM,MAAM,GAAW,IAAI,CAAC,IAAI,EAAE;AAClC,QAAA,OAAO,CAAA,KAAA,EAAQ,MAAM,CAAC,IAAI,IAAI,CAAC,CAAA,QAAA,EAAW,MAAM,CAAC,OAAO,IAAI,CAAC,EAAE;IACjE;uGARW,eAAe,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAf,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,eAAe,gQClB5B,kbAaM,EAAA,MAAA,EAAA,CAAA,gSAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,iBAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,CAAA,mBAAA,EAAA,yBAAA,EAAA,2BAAA,EAAA,sCAAA,EAAA,0BAAA,EAAA,2BAAA,EAAA,kCAAA,CAAA,EAAA,QAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,sFAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAC,sBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,CAAA,EAAA,OAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FDKO,eAAe,EAAA,UAAA,EAAA,CAAA;kBAT3B,SAAS;+BACE,YAAY,EAAA,UAAA,EACV,KAAK,EAAA,IAAA,EAGX;AACJ,wBAAA,mBAAmB,EAAE,UAAU;AAChC,qBAAA,EAAA,QAAA,EAAA,kbAAA,EAAA,MAAA,EAAA,CAAA,gSAAA,CAAA,EAAA;;;MEEU,yBAAyB,CAAA;AACpC,IAAA,OAAO,GAA0B,KAAK,CAAC,QAAQ,kDAAY;AAE3D,IAAA,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;AAE7B,IAAA,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAa,WAAW,CAAC;IAEvD,QAAQ,GAAA;AACN,QAAA,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAE3D,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,GAAG,CAAC,EAAE;YAC9B,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAChD;IACF;uGAbW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAzB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,yBAAyB,EAAA,YAAA,EAAA,KAAA,EAAA,QAAA,EAAA,6BAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,SAAA,EAFzB,CAAC,aAAa,CAAC,kJChB5B,0mBAkBM,EAAA,MAAA,EAAA,CAAA,mNAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAD,IAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,eAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,WAAA,EAAA,WAAA,EAAA,gBAAA,EAAA,aAAA,EAAA,OAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,EAAA,OAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,WAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAA,IAAA,CAAA,cAAA,EAAA,QAAA,EAAA,6CAAA,EAAA,MAAA,EAAA,CAAA,sBAAA,EAAA,mBAAA,EAAA,oBAAA,EAAA,4BAAA,CAAA,EAAA,OAAA,EAAA,CAAA,YAAA,EAAA,YAAA,EAAA,YAAA,EAAA,aAAA,CAAA,EAAA,QAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,QAAA,EAAA,iOAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,EAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,SAAA,EAAA,SAAA,EAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAAE,eAAA,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FDAO,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAPrC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,6BAA6B,EAAA,UAAA,EAC3B,KAAK,EAAA,SAAA,EAGN,CAAC,aAAa,CAAC,EAAA,QAAA,EAAA,0mBAAA,EAAA,MAAA,EAAA,CAAA,mNAAA,CAAA,EAAA;;;MEoBf,8BAA8B,CAAA;uGAA9B,8BAA8B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA;AAA9B,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,8BAA8B,iBAtBvC,eAAe;YACf,sBAAsB;AACtB,YAAA,yBAAyB,aAGzB,YAAY;YACZ,aAAa;YACb,qBAAqB;YACrB,eAAe;AACf,YAAA,aAAa,aAGb,eAAe;YACf,sBAAsB;YACtB,yBAAyB;YACzB,aAAa;YACb,qBAAqB;YACrB,eAAe;YACf,aAAa,CAAA,EAAA,CAAA;AAIJ,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,8BAA8B,EAAA,SAAA,EAF9B,CAAC,aAAa,CAAC,YAfxB,YAAY;YACZ,aAAa;YACb,qBAAqB;YACrB,eAAe;AACf,YAAA,aAAa,EAMb,aAAa;YACb,qBAAqB;YACrB,eAAe;YACf,aAAa,CAAA,EAAA,CAAA;;2FAIJ,8BAA8B,EAAA,UAAA,EAAA,CAAA;kBAxB1C,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,YAAY,EAAE;wBACZ,eAAe;wBACf,sBAAsB;wBACtB,yBAAyB;AAC1B,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,YAAY;wBACZ,aAAa;wBACb,qBAAqB;wBACrB,eAAe;wBACf,aAAa;AACd,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,eAAe;wBACf,sBAAsB;wBACtB,yBAAyB;wBACzB,aAAa;wBACb,qBAAqB;wBACrB,eAAe;wBACf,aAAa;AACd,qBAAA;oBACD,SAAS,EAAE,CAAC,aAAa;AAC1B,iBAAA;;;ACnCD;;AAEG;;ACFH;;AAEG;;;;"}
package/index.d.ts ADDED
@@ -0,0 +1,67 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Type, InputSignal, WritableSignal, Signal, EffectRef, ModelSignal, OnInit, ElementRef } from '@angular/core';
3
+ import * as i4 from '@angular/common';
4
+ import * as i5 from '@angular/material/menu';
5
+ import * as i6 from '@angular/material/button-toggle';
6
+ import * as i7 from '@angular/material/button';
7
+ import * as i8 from '@angular/material/icon';
8
+
9
+ interface Widget {
10
+ widget: Widget;
11
+ id: number;
12
+ label: string;
13
+ content: Type<unknown>;
14
+ rows?: number;
15
+ columns?: number;
16
+ }
17
+
18
+ declare class WidgetComponent {
19
+ data: InputSignal<Widget>;
20
+ showWidgetOptions: WritableSignal<boolean>;
21
+ get gridArea(): string;
22
+ static ɵfac: i0.ɵɵFactoryDeclaration<WidgetComponent, never>;
23
+ static ɵcmp: i0.ɵɵComponentDeclaration<WidgetComponent, "app-widget", never, { "data": { "alias": "data"; "required": true; "isSignal": true; }; }, {}, never, never, false, never>;
24
+ }
25
+
26
+ declare class WidgetService {
27
+ widgets: WritableSignal<Widget[]>;
28
+ addedWidgets: WritableSignal<Widget[]>;
29
+ widgetsToAdd: Signal<Widget[]>;
30
+ constructor();
31
+ fetchWidgets(): void;
32
+ setAvailableWidgets(widgets: Widget[]): void;
33
+ addWidget(widget: Widget): void;
34
+ updateWidget(id: number, widget: Partial<Widget>): void;
35
+ moveWidgetToLeft(id: number): void;
36
+ moveWidgetToRight(id: number): void;
37
+ deleteWidget(id: number): void;
38
+ saveWidgets: EffectRef;
39
+ static ɵfac: i0.ɵɵFactoryDeclaration<WidgetService, never>;
40
+ static ɵprov: i0.ɵɵInjectableDeclaration<WidgetService>;
41
+ }
42
+
43
+ declare class WidgetOptionsComponent {
44
+ widget: InputSignal<Widget>;
45
+ showOptions: ModelSignal<boolean>;
46
+ store: WidgetService;
47
+ static ɵfac: i0.ɵɵFactoryDeclaration<WidgetOptionsComponent, never>;
48
+ static ɵcmp: i0.ɵɵComponentDeclaration<WidgetOptionsComponent, "app-widget-options", never, { "widget": { "alias": "widget"; "required": true; "isSignal": true; }; "showOptions": { "alias": "showOptions"; "required": false; "isSignal": true; }; }, { "showOptions": "showOptionsChange"; }, never, never, false, never>;
49
+ }
50
+
51
+ declare class DashboardWidgetsComponent implements OnInit {
52
+ widgets: InputSignal<Widget[]>;
53
+ store: WidgetService;
54
+ dashboard: i0.Signal<ElementRef<any>>;
55
+ ngOnInit(): void;
56
+ static ɵfac: i0.ɵɵFactoryDeclaration<DashboardWidgetsComponent, never>;
57
+ static ɵcmp: i0.ɵɵComponentDeclaration<DashboardWidgetsComponent, "fidurcode-dashboard-widgets", never, { "widgets": { "alias": "widgets"; "required": true; "isSignal": true; }; }, {}, never, never, false, never>;
58
+ }
59
+
60
+ declare class DashboardWidgetsSkeletonModule {
61
+ static ɵfac: i0.ɵɵFactoryDeclaration<DashboardWidgetsSkeletonModule, never>;
62
+ static ɵmod: i0.ɵɵNgModuleDeclaration<DashboardWidgetsSkeletonModule, [typeof WidgetComponent, typeof WidgetOptionsComponent, typeof DashboardWidgetsComponent], [typeof i4.CommonModule, typeof i5.MatMenuModule, typeof i6.MatButtonToggleModule, typeof i7.MatButtonModule, typeof i8.MatIconModule], [typeof WidgetComponent, typeof WidgetOptionsComponent, typeof DashboardWidgetsComponent, typeof i5.MatMenuModule, typeof i6.MatButtonToggleModule, typeof i7.MatButtonModule, typeof i8.MatIconModule]>;
63
+ static ɵinj: i0.ɵɵInjectorDeclaration<DashboardWidgetsSkeletonModule>;
64
+ }
65
+
66
+ export { DashboardWidgetsComponent, DashboardWidgetsSkeletonModule, WidgetComponent, WidgetOptionsComponent, WidgetService };
67
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sources":["../../projects/dashboard-widgets-skeleton/src/lib/components/widget/widget.ts","../../projects/dashboard-widgets-skeleton/src/lib/components/widget/widget.component.ts","../../projects/dashboard-widgets-skeleton/src/lib/services/widget.service.ts","../../projects/dashboard-widgets-skeleton/src/lib/components/widget-options/widget-options.component.ts","../../projects/dashboard-widgets-skeleton/src/lib/components/dashboard-widgets/dashboard-widgets.component.ts","../../projects/dashboard-widgets-skeleton/src/lib/dashboard-widgets-skeleton.module.ts"],"sourcesContent":[null,null,null,null,null,null],"names":[],"mappings":";;;;;;;;;;;;AAME;;;AAGD;;ACAD;AAUE;AAEA;;;;AAMD;;AClBD;AAES;AACP;AAEA;;AAWA;AAeA;AAIA;AAIA;AASA;AAYA;AAYA;AAIA;;;AAQD;;AClFD;AAOE;AACA;AAEA;;;AACD;;ACXD;AAQE;AAEA;AAEA;AAEA;;;AAOD;;ACpBD;;;;AAwB8C;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fidurcode/dashboard-widgets-skeleton",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "peerDependencies": {
@@ -13,11 +13,21 @@
13
13
  "@angular/material": "20.1.2",
14
14
  "@angular/platform-browser": "20.1.2",
15
15
  "@angular/router": "20.1.2",
16
- "rxjs": "~7.8.0",
17
- "tslib": "^2.3.0"
16
+ "rxjs": "~7.8.0"
18
17
  },
19
18
  "dependencies": {
20
19
  "tslib": "^2.3.0"
21
20
  },
22
- "sideEffects": false
23
- }
21
+ "sideEffects": false,
22
+ "module": "fesm2022/fidurcode-dashboard-widgets-skeleton.mjs",
23
+ "typings": "index.d.ts",
24
+ "exports": {
25
+ "./package.json": {
26
+ "default": "./package.json"
27
+ },
28
+ ".": {
29
+ "types": "./index.d.ts",
30
+ "default": "./fesm2022/fidurcode-dashboard-widgets-skeleton.mjs"
31
+ }
32
+ }
33
+ }
package/ng-package.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3
- "dest": "../../dist/dashboard-widgets-skeleton",
4
- "lib": {
5
- "entryFile": "src/public-api.ts"
6
- }
7
- }
@@ -1,19 +0,0 @@
1
- <div class="dashboard-widgets-header">
2
- <h2>Dashboard</h2>
3
- <button [matMenuTriggerFor]="menu" mat-raised-button>
4
- <mat-icon>add_circle</mat-icon>
5
- Add widget
6
- </button>
7
- <mat-menu #menu="matMenu">
8
- @for (widget of store.widgetsToAdd(); track widget.id) {
9
- <button mat-menu-item (click)="store.addWidget(widget)">{{ widget.label }}</button>
10
- } @empty {
11
- <button mat-menu-item>No widget to add</button>
12
- }
13
- </mat-menu>
14
- </div>
15
- <div #dashboard class="dashboard-widgets">
16
- @for (w of store.addedWidgets(); track w.id) {
17
- <app-widget [data]="w"/>
18
- }
19
- </div>
@@ -1,12 +0,0 @@
1
- .dashboard-widgets-header {
2
- display: flex;
3
- justify-content: space-between;
4
- align-items: center;
5
- }
6
-
7
- .dashboard-widgets {
8
- display: grid;
9
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
10
- grid-auto-rows: 150px;
11
- gap: 16px;
12
- }
@@ -1,22 +0,0 @@
1
- import { ComponentFixture, TestBed } from '@angular/core/testing';
2
-
3
- import { DashboardWidgetsComponent } from './dashboard-widgets.component';
4
-
5
- describe('DashboardWidgets', () => {
6
- let component: DashboardWidgetsComponent;
7
- let fixture: ComponentFixture<DashboardWidgetsComponent>;
8
-
9
- beforeEach(async () => {
10
- await TestBed.configureTestingModule({
11
- imports: [DashboardWidgetsComponent],
12
- }).compileComponents();
13
-
14
- fixture = TestBed.createComponent(DashboardWidgetsComponent);
15
- component = fixture.componentInstance;
16
- fixture.detectChanges();
17
- });
18
-
19
- it('should create', () => {
20
- expect(component).toBeTruthy();
21
- });
22
- });
@@ -1,33 +0,0 @@
1
- import {
2
- Component,
3
- ElementRef,
4
- inject, input, Input, InputSignal,
5
- OnInit,
6
- viewChild,
7
- } from '@angular/core';
8
- import { WidgetService } from '../../services/widget.service';
9
- import { wrapGrid } from 'animate-css-grid';
10
- import {Widget} from '../widget/widget';
11
-
12
- @Component({
13
- selector: 'fidurcode-dashboard-widgets',
14
- standalone: false,
15
- templateUrl: './dashboard-widgets.component.html',
16
- styleUrl: './dashboard-widgets.component.scss',
17
- providers: [WidgetService],
18
- })
19
- export class DashboardWidgetsComponent implements OnInit {
20
- widgets: InputSignal<Widget[]> = input.required<Widget[]>();
21
-
22
- store = inject(WidgetService);
23
-
24
- dashboard = viewChild.required<ElementRef>('dashboard');
25
-
26
- ngOnInit(): void {
27
- wrapGrid(this.dashboard().nativeElement, { duration: 300 });
28
-
29
- if (this.widgets()?.length > 0) {
30
- this.store.setAvailableWidgets(this.widgets());
31
- }
32
- }
33
- }
@@ -1,14 +0,0 @@
1
- <div
2
- class="widget-container mat-elevation-z3"
3
- >
4
- <h3 class="m-0">{{ data().label }}</h3>
5
- <button (click)="showWidgetOptions.set(true)" class="settings-button" mat-icon-button>
6
- <mat-icon>settings</mat-icon>
7
- </button>
8
-
9
- <ng-container [ngComponentOutlet]="data().content"/>
10
-
11
- @if (showWidgetOptions()) {
12
- <app-widget-options [(showOptions)]="showWidgetOptions" [widget]="data()"/>
13
- }
14
- </div>
@@ -1,22 +0,0 @@
1
- :host {
2
- display: block;
3
- border-radius: 16px;
4
- }
5
-
6
- .widget-container {
7
- position: relative;
8
- height: 100%;
9
- width: 100%;
10
- padding: 32px;
11
- box-sizing: border-box;
12
- border-radius: inherit;
13
- overflow: hidden;
14
- background-color: var(--mat-sys-background);
15
- cursor: pointer;
16
- }
17
-
18
- .settings-button {
19
- position: absolute;
20
- top: 20px;
21
- right: 20px;
22
- }
@@ -1,22 +0,0 @@
1
- import { ComponentFixture, TestBed } from '@angular/core/testing';
2
-
3
- import { WidgetComponent } from './widget.component';
4
-
5
- describe('Widget', () => {
6
- let component: WidgetComponent;
7
- let fixture: ComponentFixture<WidgetComponent>;
8
-
9
- beforeEach(async () => {
10
- await TestBed.configureTestingModule({
11
- imports: [WidgetComponent],
12
- }).compileComponents();
13
-
14
- fixture = TestBed.createComponent(WidgetComponent);
15
- component = fixture.componentInstance;
16
- fixture.detectChanges();
17
- });
18
-
19
- it('should create', () => {
20
- expect(component).toBeTruthy();
21
- });
22
- });
@@ -1,28 +0,0 @@
1
- import {
2
- Component,
3
- input,
4
- InputSignal,
5
- signal,
6
- WritableSignal,
7
- } from '@angular/core';
8
- import { Widget } from './widget';
9
-
10
- @Component({
11
- selector: 'app-widget',
12
- standalone: false,
13
- templateUrl: './widget.component.html',
14
- styleUrl: './widget.component.scss',
15
- host: {
16
- '[style.grid-area]': 'gridArea',
17
- },
18
- })
19
- export class WidgetComponent {
20
- data: InputSignal<Widget> = input.required<Widget>();
21
-
22
- showWidgetOptions: WritableSignal<boolean> = signal<boolean>(false);
23
-
24
- get gridArea(): string {
25
- const widget: Widget = this.data();
26
- return `span ${widget.rows ?? 1} / span ${widget.columns ?? 1}`;
27
- }
28
- }
@@ -1,10 +0,0 @@
1
- import { Type } from '@angular/core';
2
-
3
- export interface Widget {
4
- widget: Widget;
5
- id: number;
6
- label: string;
7
- content: Type<unknown>;
8
- rows?: number;
9
- columns?: number;
10
- }
@@ -1,41 +0,0 @@
1
- <button (click)="showOptions.set(false)" class="close-button" mat-icon-button>
2
- <mat-icon>close</mat-icon>
3
- </button>
4
-
5
- <div (click)="store.moveWidgetToRight(widget().id)" class="move-forward-button">
6
- <mat-icon>chevron_right</mat-icon>
7
- </div>
8
-
9
- <div (click)="store.moveWidgetToLeft(widget().id)" class="move-backward-button">
10
- <mat-icon>chevron_left</mat-icon>
11
- </div>
12
-
13
- <div (click)="store.deleteWidget(widget().id)" class="remove-widget-button">
14
- <mat-icon>delete</mat-icon>
15
- </div>
16
-
17
- <div>
18
- Width
19
- <mat-button-toggle-group
20
- (change)="store.updateWidget(widget().id, { columns: +$event.value })"
21
- [hideSingleSelectionIndicator]="true"
22
- [value]="widget().columns ?? 1">
23
- <mat-button-toggle [value]="1">1</mat-button-toggle>
24
- <mat-button-toggle [value]="2">2</mat-button-toggle>
25
- <mat-button-toggle [value]="3">3</mat-button-toggle>
26
- <mat-button-toggle [value]="4">4</mat-button-toggle>
27
- </mat-button-toggle-group>
28
- </div>
29
-
30
- <div>
31
- Height
32
- <mat-button-toggle-group
33
- (change)="store.updateWidget(widget().id, { rows: +$event.value })"
34
- [hideSingleSelectionIndicator]="true"
35
- [value]="widget().rows ?? 1">
36
- <mat-button-toggle [value]="1">1</mat-button-toggle>
37
- <mat-button-toggle [value]="2">2</mat-button-toggle>
38
- <mat-button-toggle [value]="3">3</mat-button-toggle>
39
- <mat-button-toggle [value]="4">4</mat-button-toggle>
40
- </mat-button-toggle-group>
41
- </div>
@@ -1,53 +0,0 @@
1
- :host {
2
- position: absolute;
3
- z-index: 2;
4
- background: inherit;
5
- color: inherit;
6
- top: 0;
7
- left: 0;
8
- border-radius: inherit;
9
- width: 100%;
10
- height: 100%;
11
-
12
- display: flex;
13
- flex-direction: column;
14
- justify-content: center;
15
- align-items: center;
16
- box-sizing: border-box;
17
- --mat-standard-button-toggle-height: 9px;
18
-
19
- > div {
20
- display: flex;
21
- gap: 8px;
22
- align-items: center;
23
- margin-left: 8px;
24
- }
25
- }
26
-
27
- .close-button {
28
- position: absolute;
29
- top: 0;
30
- right: 0;
31
- }
32
-
33
- .move-forward-button {
34
- position: absolute;
35
- top: 50%;
36
- transform: translateY(-50%);
37
- right: -5px;
38
- }
39
-
40
- .move-backward-button {
41
- position: absolute;
42
- top: 50%;
43
- transform: translateY(-50%);
44
- left: -5px;
45
- }
46
-
47
-
48
- .remove-widget-button {
49
- position: absolute;
50
- top: 0;
51
- left: 0;
52
- padding: 5px;
53
- }
@@ -1,22 +0,0 @@
1
- import { ComponentFixture, TestBed } from '@angular/core/testing';
2
-
3
- import { WidgetOptionsComponent } from './widget-options.component';
4
-
5
- describe('WidgetOptions', () => {
6
- let component: WidgetOptionsComponent;
7
- let fixture: ComponentFixture<WidgetOptionsComponent>;
8
-
9
- beforeEach(async () => {
10
- await TestBed.configureTestingModule({
11
- imports: [WidgetOptionsComponent],
12
- }).compileComponents();
13
-
14
- fixture = TestBed.createComponent(WidgetOptionsComponent);
15
- component = fixture.componentInstance;
16
- fixture.detectChanges();
17
- });
18
-
19
- it('should create', () => {
20
- expect(component).toBeTruthy();
21
- });
22
- });
@@ -1,23 +0,0 @@
1
- import {
2
- Component,
3
- inject,
4
- input,
5
- InputSignal,
6
- model,
7
- ModelSignal,
8
- } from '@angular/core';
9
- import { Widget } from '../widget/widget';
10
- import { WidgetService } from '../../services/widget.service';
11
-
12
- @Component({
13
- selector: 'app-widget-options',
14
- standalone: false,
15
- templateUrl: './widget-options.component.html',
16
- styleUrl: './widget-options.component.scss',
17
- })
18
- export class WidgetOptionsComponent {
19
- widget: InputSignal<Widget> = input.required<Widget>();
20
- showOptions: ModelSignal<boolean> = model<boolean>(false);
21
-
22
- store = inject(WidgetService);
23
- }
@@ -1,37 +0,0 @@
1
- import { NgModule } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { WidgetComponent } from './components/widget/widget.component';
4
- import { WidgetOptionsComponent } from './components/widget-options/widget-options.component';
5
- import { DashboardWidgetsComponent } from './components/dashboard-widgets/dashboard-widgets.component';
6
- import { WidgetService } from './services/widget.service';
7
-
8
- import { MatMenuModule } from '@angular/material/menu';
9
- import { MatButtonToggleModule } from '@angular/material/button-toggle';
10
- import { MatButtonModule } from '@angular/material/button';
11
- import { MatIconModule } from '@angular/material/icon';
12
-
13
- @NgModule({
14
- declarations: [
15
- WidgetComponent,
16
- WidgetOptionsComponent,
17
- DashboardWidgetsComponent,
18
- ],
19
- imports: [
20
- CommonModule,
21
- MatMenuModule,
22
- MatButtonToggleModule,
23
- MatButtonModule,
24
- MatIconModule,
25
- ],
26
- exports: [
27
- WidgetComponent,
28
- WidgetOptionsComponent,
29
- DashboardWidgetsComponent,
30
- MatMenuModule,
31
- MatButtonToggleModule,
32
- MatButtonModule,
33
- MatIconModule,
34
- ],
35
- providers: [WidgetService]
36
- })
37
- export class DashboardWidgetsSkeletonModule {}
@@ -1,95 +0,0 @@
1
- import {
2
- computed, effect, EffectRef,
3
- Injectable,
4
- Signal,
5
- signal,
6
- WritableSignal,
7
- } from '@angular/core';
8
- import { Widget } from '../components/widget/widget';
9
-
10
- @Injectable()
11
- export class WidgetService {
12
- public widgets: WritableSignal<Widget[]> = signal<Widget[]>([]);
13
-
14
- addedWidgets: WritableSignal<Widget[]> = signal<Widget[]>([]);
15
-
16
- widgetsToAdd: Signal<Widget[]> = computed((): Widget[] => {
17
- const addedIds: number[] = this.addedWidgets().map(
18
- (widget: Widget): number => widget.id,
19
- );
20
- return this.widgets().filter((w): boolean => !addedIds.includes(w.id));
21
- });
22
-
23
- constructor() {
24
- this.fetchWidgets();
25
- }
26
-
27
- fetchWidgets(): void {
28
- const widgetsAsString = localStorage.getItem('dashboardWidgets');
29
- if (widgetsAsString) {
30
- const widgets = JSON.parse(widgetsAsString);
31
- widgets.forEach((widget: Widget): void => {
32
- const content = this.widgets().find((w: Widget): boolean => w.id === widget.id)?.content;
33
- if (content) {
34
- widget.content = content;
35
- }
36
- });
37
-
38
- this.addedWidgets.set(widgets);
39
- }
40
- }
41
-
42
- setAvailableWidgets(widgets: Widget[]): void {
43
- this.widgets.set(widgets);
44
- }
45
-
46
- addWidget(widget: Widget): void {
47
- this.addedWidgets.set([...this.addedWidgets(), { ...widget }]);
48
- }
49
-
50
- updateWidget(id: number, widget: Partial<Widget>): void {
51
- const index = this.addedWidgets().findIndex((w) => w.id === id);
52
- if (index !== -1) {
53
- const newWidgets = [...this.addedWidgets()];
54
- newWidgets[index] = { ...newWidgets[index], ...widget };
55
- this.addedWidgets.set(newWidgets);
56
- }
57
- }
58
-
59
- moveWidgetToLeft(id: number): void {
60
- const index = this.addedWidgets().findIndex((w) => w.id === id);
61
- if (index == 0) return;
62
- const newWidgets = [...this.addedWidgets()];
63
- [newWidgets[index], newWidgets[index - 1]] = [
64
- { ...newWidgets[index - 1] },
65
- { ...newWidgets[index] },
66
- ];
67
-
68
- this.addedWidgets.set(newWidgets);
69
- }
70
-
71
- moveWidgetToRight(id: number): void {
72
- const index = this.addedWidgets().findIndex((w) => w.id === id);
73
- if (index == this.addedWidgets().length - 1) return;
74
- const newWidgets = [...this.addedWidgets()];
75
- [newWidgets[index], newWidgets[index + 1]] = [
76
- { ...newWidgets[index + 1] },
77
- { ...newWidgets[index] },
78
- ];
79
-
80
- this.addedWidgets.set(newWidgets);
81
- }
82
-
83
- deleteWidget(id: number): void {
84
- this.addedWidgets.set(this.addedWidgets().filter((w) => w.id !== id));
85
- }
86
-
87
- saveWidgets: EffectRef = effect((): void => {
88
- const widgetsWithoutContent: Partial<Widget>[] = this.addedWidgets().map(w => ({...w}));
89
- widgetsWithoutContent.forEach(widget => {
90
- delete widget.content;
91
- });
92
-
93
- localStorage.setItem('dashboardWidgets', JSON.stringify(widgetsWithoutContent));
94
- });
95
- }
package/src/public-api.ts DELETED
@@ -1,9 +0,0 @@
1
- /*
2
- * Public API Surface of dashboard-widgets-skeleton
3
- */
4
-
5
- export * from './lib/components/widget/widget.component';
6
- export * from './lib/components/widget-options/widget-options.component';
7
- export * from './lib/components/dashboard-widgets/dashboard-widgets.component';
8
- export * from './lib/services/widget.service';
9
- export * from './lib/dashboard-widgets-skeleton.module';
package/tsconfig.lib.json DELETED
@@ -1,22 +0,0 @@
1
- /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2
- /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3
- {
4
- "extends": "../../tsconfig.json",
5
- "compilerOptions": {
6
- "outDir": "../../out-tsc/lib",
7
- "declaration": true,
8
- "declarationMap": true,
9
- "inlineSources": true,
10
- "target": "ES2020",
11
- "module": "ES2020",
12
- "types": []
13
- },
14
- "angularCompilerOptions": {
15
- "enableIvy": true,
16
- "compilationMode": "partial"
17
- },
18
- "exclude": [
19
- "src/test.ts",
20
- "**/*.spec.ts"
21
- ]
22
- }
@@ -1,11 +0,0 @@
1
- /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2
- /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3
- {
4
- "extends": "./tsconfig.lib.json",
5
- "compilerOptions": {
6
- "declarationMap": false
7
- },
8
- "angularCompilerOptions": {
9
- "compilationMode": "partial"
10
- }
11
- }
@@ -1,14 +0,0 @@
1
- /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2
- /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3
- {
4
- "extends": "../../tsconfig.json",
5
- "compilerOptions": {
6
- "outDir": "../../out-tsc/spec",
7
- "types": [
8
- "jasmine"
9
- ]
10
- },
11
- "include": [
12
- "src/**/*.ts"
13
- ]
14
- }