@adminforth/dashboard 1.5.0 → 1.7.0
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/custom/api/dashboardApi.ts +137 -1
- package/custom/model/dashboard.types.ts +32 -22
- package/custom/package.json +1 -0
- package/custom/pnpm-lock.yaml +31 -0
- package/custom/runtime/DashboardRuntime.vue +9 -15
- package/custom/runtime/YamlConfigEditor.vue +109 -0
- package/custom/skills/adminforth-dashboard/SKILL.md +66 -10
- package/custom/widgets/KpiCardWidget.vue +172 -9
- package/custom/widgets/chart/ChartWidget.vue +5 -5
- package/custom/widgets/registry.ts +4 -4
- package/dist/custom/api/dashboardApi.d.ts +46 -1
- package/dist/custom/api/dashboardApi.js +90 -0
- package/dist/custom/api/dashboardApi.ts +137 -1
- package/dist/custom/model/dashboard.types.d.ts +30 -14
- package/dist/custom/model/dashboard.types.js +2 -2
- package/dist/custom/model/dashboard.types.ts +32 -22
- package/dist/custom/package.json +1 -0
- package/dist/custom/pnpm-lock.yaml +31 -0
- package/dist/custom/queries/useDashboardConfig.d.ts +106 -104
- package/dist/custom/queries/useWidgetData.d.ts +106 -104
- package/dist/custom/runtime/DashboardRuntime.vue +9 -15
- package/dist/custom/runtime/YamlConfigEditor.vue +109 -0
- package/dist/custom/skills/adminforth-dashboard/SKILL.md +66 -10
- package/dist/custom/widgets/KpiCardWidget.vue +172 -9
- package/dist/custom/widgets/chart/ChartWidget.vue +5 -5
- package/dist/custom/widgets/registry.js +4 -4
- package/dist/custom/widgets/registry.ts +4 -4
- package/dist/endpoint/widgets.js +99 -14
- package/dist/schema/api.d.ts +11426 -1634
- package/dist/schema/api.js +118 -21
- package/dist/schema/widget.d.ts +425 -1980
- package/dist/schema/widget.js +13 -374
- package/dist/schema/widgets/charts.d.ts +1689 -0
- package/dist/schema/widgets/charts.js +92 -0
- package/dist/schema/widgets/common.d.ts +275 -0
- package/dist/schema/widgets/common.js +171 -0
- package/dist/schema/widgets/gauge-card.d.ts +172 -0
- package/dist/schema/widgets/gauge-card.js +28 -0
- package/dist/schema/widgets/kpi-card.d.ts +212 -0
- package/dist/schema/widgets/kpi-card.js +43 -0
- package/dist/schema/widgets/pivot-table.d.ts +196 -0
- package/dist/schema/widgets/pivot-table.js +17 -0
- package/dist/schema/widgets/table.d.ts +130 -0
- package/dist/schema/widgets/table.js +12 -0
- package/dist/services/widgetDataService.js +96 -2
- package/endpoint/widgets.ts +173 -26
- package/package.json +1 -1
- package/schema/api.ts +148 -22
- package/schema/widget.ts +43 -425
- package/schema/widgets/charts.ts +113 -0
- package/schema/widgets/common.ts +194 -0
- package/schema/widgets/gauge-card.ts +34 -0
- package/schema/widgets/kpi-card.ts +49 -0
- package/schema/widgets/pivot-table.ts +24 -0
- package/schema/widgets/table.ts +18 -0
- package/services/widgetDataService.ts +129 -3
- package/shims-vue.d.ts +11 -0
- package/tsconfig.json +3 -1
|
@@ -50,6 +50,12 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
50
50
|
calc: string;
|
|
51
51
|
as: string;
|
|
52
52
|
})[] | undefined;
|
|
53
|
+
sparkline?: {
|
|
54
|
+
field: string;
|
|
55
|
+
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
56
|
+
as: string;
|
|
57
|
+
fill_missing?: Record<string, import("../model/dashboard.types.js").JsonValue> | undefined;
|
|
58
|
+
} | undefined;
|
|
53
59
|
filters?: any;
|
|
54
60
|
group_by?: (string | {
|
|
55
61
|
field: string;
|
|
@@ -63,16 +69,6 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
63
69
|
}[] | undefined;
|
|
64
70
|
limit?: number | undefined;
|
|
65
71
|
offset?: number | undefined;
|
|
66
|
-
time_series?: {
|
|
67
|
-
field: string;
|
|
68
|
-
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
69
|
-
timezone?: string | undefined;
|
|
70
|
-
} | undefined;
|
|
71
|
-
period?: {
|
|
72
|
-
field: string;
|
|
73
|
-
gte?: any;
|
|
74
|
-
lt?: any;
|
|
75
|
-
} | undefined;
|
|
76
72
|
bucket?: {
|
|
77
73
|
field: string;
|
|
78
74
|
buckets: {
|
|
@@ -154,6 +150,12 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
154
150
|
calc: string;
|
|
155
151
|
as: string;
|
|
156
152
|
})[] | undefined;
|
|
153
|
+
sparkline?: {
|
|
154
|
+
field: string;
|
|
155
|
+
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
156
|
+
as: string;
|
|
157
|
+
fill_missing?: Record<string, import("../model/dashboard.types.js").JsonValue> | undefined;
|
|
158
|
+
} | undefined;
|
|
157
159
|
filters?: any;
|
|
158
160
|
group_by?: (string | {
|
|
159
161
|
field: string;
|
|
@@ -167,16 +169,6 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
167
169
|
}[] | undefined;
|
|
168
170
|
limit?: number | undefined;
|
|
169
171
|
offset?: number | undefined;
|
|
170
|
-
time_series?: {
|
|
171
|
-
field: string;
|
|
172
|
-
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
173
|
-
timezone?: string | undefined;
|
|
174
|
-
} | undefined;
|
|
175
|
-
period?: {
|
|
176
|
-
field: string;
|
|
177
|
-
gte?: any;
|
|
178
|
-
lt?: any;
|
|
179
|
-
} | undefined;
|
|
180
172
|
bucket?: {
|
|
181
173
|
field: string;
|
|
182
174
|
buckets: {
|
|
@@ -231,8 +223,29 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
231
223
|
text?: string | undefined;
|
|
232
224
|
field?: string | undefined;
|
|
233
225
|
} | undefined;
|
|
234
|
-
comparison?:
|
|
235
|
-
|
|
226
|
+
comparison?: {
|
|
227
|
+
field: string;
|
|
228
|
+
format?: import("../model/dashboard.types.js").ValueFormat | undefined;
|
|
229
|
+
positive_is_good?: boolean | undefined;
|
|
230
|
+
compact?: {
|
|
231
|
+
show?: boolean | undefined;
|
|
232
|
+
template?: string | undefined;
|
|
233
|
+
} | undefined;
|
|
234
|
+
tooltip?: {
|
|
235
|
+
label?: string | undefined;
|
|
236
|
+
template?: string | undefined;
|
|
237
|
+
} | undefined;
|
|
238
|
+
} | undefined;
|
|
239
|
+
sparkline?: {
|
|
240
|
+
type?: "line" | undefined;
|
|
241
|
+
field: string;
|
|
242
|
+
x: string;
|
|
243
|
+
show_axes?: boolean | undefined;
|
|
244
|
+
show_labels?: boolean | undefined;
|
|
245
|
+
fill?: {
|
|
246
|
+
type?: "gradient" | "solid" | undefined;
|
|
247
|
+
} | undefined;
|
|
248
|
+
} | undefined;
|
|
236
249
|
};
|
|
237
250
|
query: {
|
|
238
251
|
resource: string;
|
|
@@ -249,6 +262,12 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
249
262
|
calc: string;
|
|
250
263
|
as: string;
|
|
251
264
|
})[] | undefined;
|
|
265
|
+
sparkline?: {
|
|
266
|
+
field: string;
|
|
267
|
+
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
268
|
+
as: string;
|
|
269
|
+
fill_missing?: Record<string, import("../model/dashboard.types.js").JsonValue> | undefined;
|
|
270
|
+
} | undefined;
|
|
252
271
|
filters?: any;
|
|
253
272
|
group_by?: (string | {
|
|
254
273
|
field: string;
|
|
@@ -262,16 +281,6 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
262
281
|
}[] | undefined;
|
|
263
282
|
limit?: number | undefined;
|
|
264
283
|
offset?: number | undefined;
|
|
265
|
-
time_series?: {
|
|
266
|
-
field: string;
|
|
267
|
-
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
268
|
-
timezone?: string | undefined;
|
|
269
|
-
} | undefined;
|
|
270
|
-
period?: {
|
|
271
|
-
field: string;
|
|
272
|
-
gte?: any;
|
|
273
|
-
lt?: any;
|
|
274
|
-
} | undefined;
|
|
275
284
|
bucket?: {
|
|
276
285
|
field: string;
|
|
277
286
|
buckets: {
|
|
@@ -334,6 +343,12 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
334
343
|
calc: string;
|
|
335
344
|
as: string;
|
|
336
345
|
})[] | undefined;
|
|
346
|
+
sparkline?: {
|
|
347
|
+
field: string;
|
|
348
|
+
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
349
|
+
as: string;
|
|
350
|
+
fill_missing?: Record<string, import("../model/dashboard.types.js").JsonValue> | undefined;
|
|
351
|
+
} | undefined;
|
|
337
352
|
filters?: any;
|
|
338
353
|
group_by?: (string | {
|
|
339
354
|
field: string;
|
|
@@ -347,16 +362,6 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
347
362
|
}[] | undefined;
|
|
348
363
|
limit?: number | undefined;
|
|
349
364
|
offset?: number | undefined;
|
|
350
|
-
time_series?: {
|
|
351
|
-
field: string;
|
|
352
|
-
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
353
|
-
timezone?: string | undefined;
|
|
354
|
-
} | undefined;
|
|
355
|
-
period?: {
|
|
356
|
-
field: string;
|
|
357
|
-
gte?: any;
|
|
358
|
-
lt?: any;
|
|
359
|
-
} | undefined;
|
|
360
365
|
bucket?: {
|
|
361
366
|
field: string;
|
|
362
367
|
buckets: {
|
|
@@ -416,6 +421,12 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
416
421
|
calc: string;
|
|
417
422
|
as: string;
|
|
418
423
|
})[] | undefined;
|
|
424
|
+
sparkline?: {
|
|
425
|
+
field: string;
|
|
426
|
+
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
427
|
+
as: string;
|
|
428
|
+
fill_missing?: Record<string, import("../model/dashboard.types.js").JsonValue> | undefined;
|
|
429
|
+
} | undefined;
|
|
419
430
|
filters?: any;
|
|
420
431
|
group_by?: (string | {
|
|
421
432
|
field: string;
|
|
@@ -429,16 +440,6 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
429
440
|
}[] | undefined;
|
|
430
441
|
limit?: number | undefined;
|
|
431
442
|
offset?: number | undefined;
|
|
432
|
-
time_series?: {
|
|
433
|
-
field: string;
|
|
434
|
-
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
435
|
-
timezone?: string | undefined;
|
|
436
|
-
} | undefined;
|
|
437
|
-
period?: {
|
|
438
|
-
field: string;
|
|
439
|
-
gte?: any;
|
|
440
|
-
lt?: any;
|
|
441
|
-
} | undefined;
|
|
442
443
|
bucket?: {
|
|
443
444
|
field: string;
|
|
444
445
|
buckets: {
|
|
@@ -504,6 +505,12 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
504
505
|
calc: string;
|
|
505
506
|
as: string;
|
|
506
507
|
})[] | undefined;
|
|
508
|
+
sparkline?: {
|
|
509
|
+
field: string;
|
|
510
|
+
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
511
|
+
as: string;
|
|
512
|
+
fill_missing?: Record<string, import("../model/dashboard.types.js").JsonValue> | undefined;
|
|
513
|
+
} | undefined;
|
|
507
514
|
filters?: any;
|
|
508
515
|
group_by?: (string | {
|
|
509
516
|
field: string;
|
|
@@ -517,16 +524,6 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
517
524
|
}[] | undefined;
|
|
518
525
|
limit?: number | undefined;
|
|
519
526
|
offset?: number | undefined;
|
|
520
|
-
time_series?: {
|
|
521
|
-
field: string;
|
|
522
|
-
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
523
|
-
timezone?: string | undefined;
|
|
524
|
-
} | undefined;
|
|
525
|
-
period?: {
|
|
526
|
-
field: string;
|
|
527
|
-
gte?: any;
|
|
528
|
-
lt?: any;
|
|
529
|
-
} | undefined;
|
|
530
527
|
bucket?: {
|
|
531
528
|
field: string;
|
|
532
529
|
buckets: {
|
|
@@ -608,6 +605,12 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
608
605
|
calc: string;
|
|
609
606
|
as: string;
|
|
610
607
|
})[] | undefined;
|
|
608
|
+
sparkline?: {
|
|
609
|
+
field: string;
|
|
610
|
+
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
611
|
+
as: string;
|
|
612
|
+
fill_missing?: Record<string, import("../model/dashboard.types.js").JsonValue> | undefined;
|
|
613
|
+
} | undefined;
|
|
611
614
|
filters?: any;
|
|
612
615
|
group_by?: (string | {
|
|
613
616
|
field: string;
|
|
@@ -621,16 +624,6 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
621
624
|
}[] | undefined;
|
|
622
625
|
limit?: number | undefined;
|
|
623
626
|
offset?: number | undefined;
|
|
624
|
-
time_series?: {
|
|
625
|
-
field: string;
|
|
626
|
-
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
627
|
-
timezone?: string | undefined;
|
|
628
|
-
} | undefined;
|
|
629
|
-
period?: {
|
|
630
|
-
field: string;
|
|
631
|
-
gte?: any;
|
|
632
|
-
lt?: any;
|
|
633
|
-
} | undefined;
|
|
634
627
|
bucket?: {
|
|
635
628
|
field: string;
|
|
636
629
|
buckets: {
|
|
@@ -685,8 +678,29 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
685
678
|
text?: string | undefined;
|
|
686
679
|
field?: string | undefined;
|
|
687
680
|
} | undefined;
|
|
688
|
-
comparison?:
|
|
689
|
-
|
|
681
|
+
comparison?: {
|
|
682
|
+
field: string;
|
|
683
|
+
format?: import("../model/dashboard.types.js").ValueFormat | undefined;
|
|
684
|
+
positive_is_good?: boolean | undefined;
|
|
685
|
+
compact?: {
|
|
686
|
+
show?: boolean | undefined;
|
|
687
|
+
template?: string | undefined;
|
|
688
|
+
} | undefined;
|
|
689
|
+
tooltip?: {
|
|
690
|
+
label?: string | undefined;
|
|
691
|
+
template?: string | undefined;
|
|
692
|
+
} | undefined;
|
|
693
|
+
} | undefined;
|
|
694
|
+
sparkline?: {
|
|
695
|
+
type?: "line" | undefined;
|
|
696
|
+
field: string;
|
|
697
|
+
x: string;
|
|
698
|
+
show_axes?: boolean | undefined;
|
|
699
|
+
show_labels?: boolean | undefined;
|
|
700
|
+
fill?: {
|
|
701
|
+
type?: "gradient" | "solid" | undefined;
|
|
702
|
+
} | undefined;
|
|
703
|
+
} | undefined;
|
|
690
704
|
};
|
|
691
705
|
query: {
|
|
692
706
|
resource: string;
|
|
@@ -703,6 +717,12 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
703
717
|
calc: string;
|
|
704
718
|
as: string;
|
|
705
719
|
})[] | undefined;
|
|
720
|
+
sparkline?: {
|
|
721
|
+
field: string;
|
|
722
|
+
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
723
|
+
as: string;
|
|
724
|
+
fill_missing?: Record<string, import("../model/dashboard.types.js").JsonValue> | undefined;
|
|
725
|
+
} | undefined;
|
|
706
726
|
filters?: any;
|
|
707
727
|
group_by?: (string | {
|
|
708
728
|
field: string;
|
|
@@ -716,16 +736,6 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
716
736
|
}[] | undefined;
|
|
717
737
|
limit?: number | undefined;
|
|
718
738
|
offset?: number | undefined;
|
|
719
|
-
time_series?: {
|
|
720
|
-
field: string;
|
|
721
|
-
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
722
|
-
timezone?: string | undefined;
|
|
723
|
-
} | undefined;
|
|
724
|
-
period?: {
|
|
725
|
-
field: string;
|
|
726
|
-
gte?: any;
|
|
727
|
-
lt?: any;
|
|
728
|
-
} | undefined;
|
|
729
739
|
bucket?: {
|
|
730
740
|
field: string;
|
|
731
741
|
buckets: {
|
|
@@ -788,6 +798,12 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
788
798
|
calc: string;
|
|
789
799
|
as: string;
|
|
790
800
|
})[] | undefined;
|
|
801
|
+
sparkline?: {
|
|
802
|
+
field: string;
|
|
803
|
+
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
804
|
+
as: string;
|
|
805
|
+
fill_missing?: Record<string, import("../model/dashboard.types.js").JsonValue> | undefined;
|
|
806
|
+
} | undefined;
|
|
791
807
|
filters?: any;
|
|
792
808
|
group_by?: (string | {
|
|
793
809
|
field: string;
|
|
@@ -801,16 +817,6 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
801
817
|
}[] | undefined;
|
|
802
818
|
limit?: number | undefined;
|
|
803
819
|
offset?: number | undefined;
|
|
804
|
-
time_series?: {
|
|
805
|
-
field: string;
|
|
806
|
-
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
807
|
-
timezone?: string | undefined;
|
|
808
|
-
} | undefined;
|
|
809
|
-
period?: {
|
|
810
|
-
field: string;
|
|
811
|
-
gte?: any;
|
|
812
|
-
lt?: any;
|
|
813
|
-
} | undefined;
|
|
814
820
|
bucket?: {
|
|
815
821
|
field: string;
|
|
816
822
|
buckets: {
|
|
@@ -870,6 +876,12 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
870
876
|
calc: string;
|
|
871
877
|
as: string;
|
|
872
878
|
})[] | undefined;
|
|
879
|
+
sparkline?: {
|
|
880
|
+
field: string;
|
|
881
|
+
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
882
|
+
as: string;
|
|
883
|
+
fill_missing?: Record<string, import("../model/dashboard.types.js").JsonValue> | undefined;
|
|
884
|
+
} | undefined;
|
|
873
885
|
filters?: any;
|
|
874
886
|
group_by?: (string | {
|
|
875
887
|
field: string;
|
|
@@ -883,16 +895,6 @@ export declare function useWidgetData(slug: Ref<string>, widgetId: Ref<string>,
|
|
|
883
895
|
}[] | undefined;
|
|
884
896
|
limit?: number | undefined;
|
|
885
897
|
offset?: number | undefined;
|
|
886
|
-
time_series?: {
|
|
887
|
-
field: string;
|
|
888
|
-
grain: import("../model/dashboard.types.js").TimeGrain;
|
|
889
|
-
timezone?: string | undefined;
|
|
890
|
-
} | undefined;
|
|
891
|
-
period?: {
|
|
892
|
-
field: string;
|
|
893
|
-
gte?: any;
|
|
894
|
-
lt?: any;
|
|
895
|
-
} | undefined;
|
|
896
898
|
bucket?: {
|
|
897
899
|
field: string;
|
|
898
900
|
buckets: {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
class="fixed inset-0 z-50 flex items-center justify-center bg-black/35 p-4"
|
|
55
55
|
@click.self="closeGroupConfigEditor"
|
|
56
56
|
>
|
|
57
|
-
<section class="w-full max-w-
|
|
57
|
+
<section class="w-full max-w-5xl rounded-lg border border-lightListBorder bg-lightDropdownOptionsBackground p-4 shadow-xl dark:border-darkListBorder dark:bg-darkDropdownOptionsBackground">
|
|
58
58
|
<header class="mb-3 flex items-center justify-between gap-3">
|
|
59
59
|
<h2 class="m-0 text-base font-bold text-lightNavbarText dark:text-darkNavbarText">
|
|
60
60
|
Group JSON
|
|
@@ -81,12 +81,9 @@
|
|
|
81
81
|
</button>
|
|
82
82
|
</header>
|
|
83
83
|
|
|
84
|
-
<
|
|
84
|
+
<YamlConfigEditor
|
|
85
85
|
v-model="groupConfigCode"
|
|
86
|
-
|
|
87
|
-
spellcheck="false"
|
|
88
|
-
@keydown.ctrl.enter.prevent="saveGroupConfig"
|
|
89
|
-
@keydown.meta.enter.prevent="saveGroupConfig"
|
|
86
|
+
@save="saveGroupConfig"
|
|
90
87
|
/>
|
|
91
88
|
|
|
92
89
|
<div
|
|
@@ -120,7 +117,7 @@
|
|
|
120
117
|
class="fixed inset-0 z-50 flex items-center justify-center bg-black/35 p-4"
|
|
121
118
|
@click.self="closeWidgetConfigEditor"
|
|
122
119
|
>
|
|
123
|
-
<section class="w-full max-w-
|
|
120
|
+
<section class="w-full max-w-5xl rounded-lg border border-lightListBorder bg-lightDropdownOptionsBackground p-4 shadow-xl dark:border-darkListBorder dark:bg-darkDropdownOptionsBackground">
|
|
124
121
|
<header class="mb-3 flex items-center justify-between gap-3">
|
|
125
122
|
<h2 class="m-0 text-base font-bold text-lightNavbarText dark:text-darkNavbarText">
|
|
126
123
|
Widget JSON
|
|
@@ -147,12 +144,9 @@
|
|
|
147
144
|
</button>
|
|
148
145
|
</header>
|
|
149
146
|
|
|
150
|
-
<
|
|
147
|
+
<YamlConfigEditor
|
|
151
148
|
v-model="widgetConfigCode"
|
|
152
|
-
|
|
153
|
-
spellcheck="false"
|
|
154
|
-
@keydown.ctrl.enter.prevent="saveWidgetConfig"
|
|
155
|
-
@keydown.meta.enter.prevent="saveWidgetConfig"
|
|
149
|
+
@save="saveWidgetConfig"
|
|
156
150
|
/>
|
|
157
151
|
|
|
158
152
|
<div
|
|
@@ -203,12 +197,12 @@ import { computed, ref, watch } from 'vue'
|
|
|
203
197
|
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml'
|
|
204
198
|
import { Button } from '@/afcl'
|
|
205
199
|
import DashboardGroup from './DashboardGroup.vue'
|
|
200
|
+
import YamlConfigEditor from './YamlConfigEditor.vue'
|
|
206
201
|
import { DashboardApiError, dashboardApi, type DashboardResponse } from '../api/dashboardApi.js'
|
|
207
202
|
import type {
|
|
208
203
|
DashboardConfig,
|
|
209
204
|
DashboardGroupConfig,
|
|
210
205
|
EditableDashboardGroupConfig,
|
|
211
|
-
EditableDashboardWidgetConfig,
|
|
212
206
|
DashboardGroupMoveDirection,
|
|
213
207
|
DashboardWidgetConfig,
|
|
214
208
|
DashboardWidgetMoveDirection,
|
|
@@ -414,13 +408,13 @@ async function saveWidgetConfig() {
|
|
|
414
408
|
try {
|
|
415
409
|
widgetConfigError.value = ''
|
|
416
410
|
widgetConfigFieldErrors.value = []
|
|
417
|
-
const widgetConfig = parseYaml(widgetConfigCode.value) as
|
|
411
|
+
const widgetConfig = parseYaml(widgetConfigCode.value) as DashboardWidgetConfig
|
|
418
412
|
|
|
419
413
|
applyDashboardResponse(
|
|
420
414
|
await dashboardApi.setWidgetConfig(
|
|
421
415
|
props.dashboardSlug,
|
|
422
416
|
editingWidgetId.value,
|
|
423
|
-
widgetConfig,
|
|
417
|
+
serializeDashboardWidgetConfigForEditor(widgetConfig),
|
|
424
418
|
),
|
|
425
419
|
)
|
|
426
420
|
closeWidgetConfigEditor()
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
ref="editorEl"
|
|
4
|
+
class="min-h-[500px] w-full overflow-hidden rounded-lg border border-lightListBorder bg-lightListTable text-sm dark:border-darkListBorder dark:bg-darkListTable"
|
|
5
|
+
/>
|
|
6
|
+
</template>
|
|
7
|
+
|
|
8
|
+
<script setup lang="ts">
|
|
9
|
+
import 'monaco-editor/min/vs/editor/editor.main.css'
|
|
10
|
+
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
|
|
11
|
+
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
|
12
|
+
import type * as Monaco from 'monaco-editor'
|
|
13
|
+
|
|
14
|
+
declare global {
|
|
15
|
+
interface Window {
|
|
16
|
+
MonacoEnvironment?: {
|
|
17
|
+
getWorker: () => Worker
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (typeof window !== 'undefined' && !window.MonacoEnvironment) {
|
|
23
|
+
window.MonacoEnvironment = {
|
|
24
|
+
getWorker: () => new EditorWorker(),
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const props = defineProps<{
|
|
29
|
+
modelValue: string
|
|
30
|
+
}>()
|
|
31
|
+
|
|
32
|
+
const emit = defineEmits<{
|
|
33
|
+
'update:modelValue': [value: string]
|
|
34
|
+
save: []
|
|
35
|
+
}>()
|
|
36
|
+
|
|
37
|
+
const editorEl = ref<HTMLElement | null>(null)
|
|
38
|
+
let monaco: typeof Monaco | null = null
|
|
39
|
+
let editor: Monaco.editor.IStandaloneCodeEditor | null = null
|
|
40
|
+
let resizeObserver: ResizeObserver | null = null
|
|
41
|
+
let applyingExternalValue = false
|
|
42
|
+
|
|
43
|
+
watch(
|
|
44
|
+
() => props.modelValue,
|
|
45
|
+
(value) => {
|
|
46
|
+
if (!editor || value === editor.getValue()) {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
applyingExternalValue = true
|
|
51
|
+
editor.setValue(value)
|
|
52
|
+
applyingExternalValue = false
|
|
53
|
+
},
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
onMounted(async () => {
|
|
57
|
+
const [loadedMonaco] = await Promise.all([
|
|
58
|
+
import('monaco-editor'),
|
|
59
|
+
import('monaco-editor/esm/vs/basic-languages/yaml/yaml.contribution'),
|
|
60
|
+
])
|
|
61
|
+
|
|
62
|
+
monaco = loadedMonaco
|
|
63
|
+
await nextTick()
|
|
64
|
+
|
|
65
|
+
if (!editorEl.value) {
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
editor = monaco.editor.create(editorEl.value, {
|
|
70
|
+
value: props.modelValue,
|
|
71
|
+
language: 'yaml',
|
|
72
|
+
automaticLayout: true,
|
|
73
|
+
minimap: { enabled: false },
|
|
74
|
+
fontSize: 13,
|
|
75
|
+
lineNumbersMinChars: 3,
|
|
76
|
+
padding: { top: 12, bottom: 12 },
|
|
77
|
+
scrollBeyondLastLine: false,
|
|
78
|
+
tabSize: 2,
|
|
79
|
+
insertSpaces: true,
|
|
80
|
+
wordWrap: 'on',
|
|
81
|
+
wrappingIndent: 'same',
|
|
82
|
+
theme: document.documentElement.classList.contains('dark') ? 'vs-dark' : 'vs',
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
editor.onDidChangeModelContent(() => {
|
|
86
|
+
if (!editor || applyingExternalValue) {
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
emit('update:modelValue', editor.getValue())
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => {
|
|
94
|
+
emit('save')
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
resizeObserver = new ResizeObserver(() => {
|
|
98
|
+
editor?.layout()
|
|
99
|
+
})
|
|
100
|
+
resizeObserver.observe(editorEl.value)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
onBeforeUnmount(() => {
|
|
104
|
+
resizeObserver?.disconnect()
|
|
105
|
+
resizeObserver = null
|
|
106
|
+
editor?.dispose()
|
|
107
|
+
editor = null
|
|
108
|
+
})
|
|
109
|
+
</script>
|