@yuuvis/client-framework 3.0.0-beta.20.2 → 3.0.0-beta.21.1

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.
Files changed (129) hide show
  1. package/autocomplete/README.md +1 -1
  2. package/common/README.md +1 -1
  3. package/fesm2022/yuuvis-client-framework-actions.mjs +25 -25
  4. package/fesm2022/yuuvis-client-framework-actions.mjs.map +1 -1
  5. package/fesm2022/yuuvis-client-framework-app-bar.mjs +6 -6
  6. package/fesm2022/yuuvis-client-framework-app-bar.mjs.map +1 -1
  7. package/fesm2022/yuuvis-client-framework-autocomplete.mjs +5 -236
  8. package/fesm2022/yuuvis-client-framework-autocomplete.mjs.map +1 -1
  9. package/fesm2022/yuuvis-client-framework-breadcrumb.mjs +4 -4
  10. package/fesm2022/yuuvis-client-framework-breadcrumb.mjs.map +1 -1
  11. package/fesm2022/yuuvis-client-framework-clipboard.mjs +7 -6
  12. package/fesm2022/yuuvis-client-framework-clipboard.mjs.map +1 -1
  13. package/fesm2022/yuuvis-client-framework-common.mjs +3 -1793
  14. package/fesm2022/yuuvis-client-framework-common.mjs.map +1 -1
  15. package/fesm2022/yuuvis-client-framework-datepicker.mjs +51 -51
  16. package/fesm2022/yuuvis-client-framework-datepicker.mjs.map +1 -1
  17. package/fesm2022/yuuvis-client-framework-forms.mjs +154 -167
  18. package/fesm2022/yuuvis-client-framework-forms.mjs.map +1 -1
  19. package/fesm2022/yuuvis-client-framework-icons.mjs +14 -14
  20. package/fesm2022/yuuvis-client-framework-icons.mjs.map +1 -1
  21. package/fesm2022/yuuvis-client-framework-list.mjs +3 -679
  22. package/fesm2022/yuuvis-client-framework-list.mjs.map +1 -1
  23. package/fesm2022/yuuvis-client-framework-master-details.mjs +3 -136
  24. package/fesm2022/yuuvis-client-framework-master-details.mjs.map +1 -1
  25. package/fesm2022/yuuvis-client-framework-metadata-form-defaults.mjs +7 -7
  26. package/fesm2022/yuuvis-client-framework-metadata-form-defaults.mjs.map +1 -1
  27. package/fesm2022/yuuvis-client-framework-metadata-form.mjs +28 -28
  28. package/fesm2022/yuuvis-client-framework-metadata-form.mjs.map +1 -1
  29. package/fesm2022/yuuvis-client-framework-object-details.mjs +92 -95
  30. package/fesm2022/yuuvis-client-framework-object-details.mjs.map +1 -1
  31. package/fesm2022/yuuvis-client-framework-object-flavor.mjs +46 -44
  32. package/fesm2022/yuuvis-client-framework-object-flavor.mjs.map +1 -1
  33. package/fesm2022/yuuvis-client-framework-object-form.mjs +47 -47
  34. package/fesm2022/yuuvis-client-framework-object-form.mjs.map +1 -1
  35. package/fesm2022/yuuvis-client-framework-object-preview.mjs +37 -58
  36. package/fesm2022/yuuvis-client-framework-object-preview.mjs.map +1 -1
  37. package/fesm2022/yuuvis-client-framework-object-relationship.mjs +80 -80
  38. package/fesm2022/yuuvis-client-framework-object-relationship.mjs.map +1 -1
  39. package/fesm2022/yuuvis-client-framework-object-summary.mjs +37 -38
  40. package/fesm2022/yuuvis-client-framework-object-summary.mjs.map +1 -1
  41. package/fesm2022/yuuvis-client-framework-object-versions.mjs +20 -20
  42. package/fesm2022/yuuvis-client-framework-object-versions.mjs.map +1 -1
  43. package/fesm2022/yuuvis-client-framework-overflow-hidden.mjs +3 -62
  44. package/fesm2022/yuuvis-client-framework-overflow-hidden.mjs.map +1 -1
  45. package/fesm2022/yuuvis-client-framework-overflow-menu.mjs +3 -129
  46. package/fesm2022/yuuvis-client-framework-overflow-menu.mjs.map +1 -1
  47. package/fesm2022/yuuvis-client-framework-pagination.mjs +5 -5
  48. package/fesm2022/yuuvis-client-framework-pagination.mjs.map +1 -1
  49. package/fesm2022/yuuvis-client-framework-popout.mjs +3 -239
  50. package/fesm2022/yuuvis-client-framework-popout.mjs.map +1 -1
  51. package/fesm2022/yuuvis-client-framework-query-list.mjs +26 -28
  52. package/fesm2022/yuuvis-client-framework-query-list.mjs.map +1 -1
  53. package/fesm2022/yuuvis-client-framework-renderer.mjs +51 -51
  54. package/fesm2022/yuuvis-client-framework-renderer.mjs.map +1 -1
  55. package/fesm2022/yuuvis-client-framework-sequence-list.mjs +7 -7
  56. package/fesm2022/yuuvis-client-framework-sequence-list.mjs.map +1 -1
  57. package/fesm2022/yuuvis-client-framework-simple-search.mjs +4 -4
  58. package/fesm2022/yuuvis-client-framework-simple-search.mjs.map +1 -1
  59. package/fesm2022/yuuvis-client-framework-sort.mjs +34 -55
  60. package/fesm2022/yuuvis-client-framework-sort.mjs.map +1 -1
  61. package/fesm2022/yuuvis-client-framework-split-view.mjs +3 -321
  62. package/fesm2022/yuuvis-client-framework-split-view.mjs.map +1 -1
  63. package/fesm2022/yuuvis-client-framework-tile-list.mjs +88 -90
  64. package/fesm2022/yuuvis-client-framework-tile-list.mjs.map +1 -1
  65. package/fesm2022/yuuvis-client-framework-token-search.mjs +21 -21
  66. package/fesm2022/yuuvis-client-framework-token-search.mjs.map +1 -1
  67. package/fesm2022/yuuvis-client-framework-tree.mjs +16 -16
  68. package/fesm2022/yuuvis-client-framework-tree.mjs.map +1 -1
  69. package/fesm2022/yuuvis-client-framework-upload-progress.mjs +15 -15
  70. package/fesm2022/yuuvis-client-framework-upload-progress.mjs.map +1 -1
  71. package/fesm2022/yuuvis-client-framework-widget-grid.mjs +3 -946
  72. package/fesm2022/yuuvis-client-framework-widget-grid.mjs.map +1 -1
  73. package/fesm2022/yuuvis-client-framework.mjs +22 -22
  74. package/fesm2022/yuuvis-client-framework.mjs.map +1 -1
  75. package/lib/assets/i18n/de.json +1 -55
  76. package/lib/assets/i18n/en.json +1 -55
  77. package/list/README.md +1 -1
  78. package/master-details/README.md +1 -1
  79. package/overflow-hidden/README.md +1 -1
  80. package/overflow-menu/README.md +1 -1
  81. package/package.json +50 -48
  82. package/popout/README.md +1 -1
  83. package/split-view/README.md +1 -1
  84. package/types/yuuvis-client-framework-autocomplete.d.ts +1 -0
  85. package/{clipboard/index.d.ts → types/yuuvis-client-framework-clipboard.d.ts} +1 -1
  86. package/types/yuuvis-client-framework-common.d.ts +1 -0
  87. package/types/yuuvis-client-framework-list.d.ts +1 -0
  88. package/types/yuuvis-client-framework-master-details.d.ts +1 -0
  89. package/{object-flavor/index.d.ts → types/yuuvis-client-framework-object-flavor.d.ts} +1 -0
  90. package/types/yuuvis-client-framework-overflow-hidden.d.ts +1 -0
  91. package/types/yuuvis-client-framework-overflow-menu.d.ts +1 -0
  92. package/types/yuuvis-client-framework-popout.d.ts +1 -0
  93. package/{renderer/index.d.ts → types/yuuvis-client-framework-renderer.d.ts} +2 -2
  94. package/types/yuuvis-client-framework-split-view.d.ts +1 -0
  95. package/types/yuuvis-client-framework-widget-grid.d.ts +1 -0
  96. package/widget-grid/README.md +1 -46
  97. package/autocomplete/index.d.ts +0 -89
  98. package/common/index.d.ts +0 -536
  99. package/list/index.d.ts +0 -380
  100. package/master-details/index.d.ts +0 -69
  101. package/overflow-hidden/index.d.ts +0 -28
  102. package/overflow-menu/index.d.ts +0 -52
  103. package/popout/index.d.ts +0 -106
  104. package/split-view/index.d.ts +0 -197
  105. package/widget-grid/index.d.ts +0 -299
  106. /package/{actions/index.d.ts → types/yuuvis-client-framework-actions.d.ts} +0 -0
  107. /package/{app-bar/index.d.ts → types/yuuvis-client-framework-app-bar.d.ts} +0 -0
  108. /package/{breadcrumb/index.d.ts → types/yuuvis-client-framework-breadcrumb.d.ts} +0 -0
  109. /package/{datepicker/index.d.ts → types/yuuvis-client-framework-datepicker.d.ts} +0 -0
  110. /package/{forms/index.d.ts → types/yuuvis-client-framework-forms.d.ts} +0 -0
  111. /package/{icons/index.d.ts → types/yuuvis-client-framework-icons.d.ts} +0 -0
  112. /package/{metadata-form-defaults/index.d.ts → types/yuuvis-client-framework-metadata-form-defaults.d.ts} +0 -0
  113. /package/{metadata-form/index.d.ts → types/yuuvis-client-framework-metadata-form.d.ts} +0 -0
  114. /package/{object-details/index.d.ts → types/yuuvis-client-framework-object-details.d.ts} +0 -0
  115. /package/{object-form/index.d.ts → types/yuuvis-client-framework-object-form.d.ts} +0 -0
  116. /package/{object-preview/index.d.ts → types/yuuvis-client-framework-object-preview.d.ts} +0 -0
  117. /package/{object-relationship/index.d.ts → types/yuuvis-client-framework-object-relationship.d.ts} +0 -0
  118. /package/{object-summary/index.d.ts → types/yuuvis-client-framework-object-summary.d.ts} +0 -0
  119. /package/{object-versions/index.d.ts → types/yuuvis-client-framework-object-versions.d.ts} +0 -0
  120. /package/{pagination/index.d.ts → types/yuuvis-client-framework-pagination.d.ts} +0 -0
  121. /package/{query-list/index.d.ts → types/yuuvis-client-framework-query-list.d.ts} +0 -0
  122. /package/{sequence-list/index.d.ts → types/yuuvis-client-framework-sequence-list.d.ts} +0 -0
  123. /package/{simple-search/index.d.ts → types/yuuvis-client-framework-simple-search.d.ts} +0 -0
  124. /package/{sort/index.d.ts → types/yuuvis-client-framework-sort.d.ts} +0 -0
  125. /package/{tile-list/index.d.ts → types/yuuvis-client-framework-tile-list.d.ts} +0 -0
  126. /package/{token-search/index.d.ts → types/yuuvis-client-framework-token-search.d.ts} +0 -0
  127. /package/{tree/index.d.ts → types/yuuvis-client-framework-tree.d.ts} +0 -0
  128. /package/{upload-progress/index.d.ts → types/yuuvis-client-framework-upload-progress.d.ts} +0 -0
  129. /package/{index.d.ts → types/yuuvis-client-framework.d.ts} +0 -0
@@ -1,954 +1,11 @@
1
- import * as i1 from '@angular/common';
2
- import { CommonModule } from '@angular/common';
3
- import * as i0 from '@angular/core';
4
- import { Injectable, Input, Component, inject, input, effect, output, viewChild, TemplateRef, signal, computed, untracked, NgModule } from '@angular/core';
5
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
- import { MAT_DIALOG_DATA, MatDialogRef, MatDialog } from '@angular/material/dialog';
7
- import * as i3$2 from '@angular/material/icon';
8
- import { MatIconModule } from '@angular/material/icon';
9
- import { TranslateService, TranslatePipe } from '@yuuvis/client-core';
10
- import { GridsterItemComponent, DisplayGrid, GridType, GridsterComponent } from 'angular-gridster2';
11
- import * as i3 from 'ng-dynamic-component';
12
- import { DynamicIoModule } from 'ng-dynamic-component';
13
- import { ReplaySubject, Subject } from 'rxjs';
14
- import * as i3$1 from '@angular/forms';
15
- import { FormControl, ReactiveFormsModule, FormBuilder, Validators } from '@angular/forms';
16
- import * as i5 from '@angular/material/button';
17
- import { MatButtonModule } from '@angular/material/button';
18
- import * as i2 from '@angular/material/list';
19
- import { MatListModule } from '@angular/material/list';
20
- import { DialogComponent, ConfirmService } from '@yuuvis/client-framework/common';
21
- import { YmtButtonDirective, YmtIconButtonDirective } from '@yuuvis/material';
22
- import { SignalComponentIoModule } from 'ng-dynamic-component/signal-component-io';
23
- import * as i4 from '@angular/material/tooltip';
24
- import { MatTooltipModule, MatTooltip } from '@angular/material/tooltip';
25
- import { MatDividerModule } from '@angular/material/divider';
26
- import * as i1$1 from '@angular/material/form-field';
27
- import { MatFormFieldModule } from '@angular/material/form-field';
28
- import * as i2$1 from '@angular/material/input';
29
- import { MatInputModule } from '@angular/material/input';
30
- import * as i4$1 from '@angular/material/menu';
31
- import { MatMenuModule } from '@angular/material/menu';
32
- import { TranslatePipe as TranslatePipe$1 } from '@ngx-translate/core';
33
-
34
- class WidgetGridEventService {
35
- constructor() {
36
- this.widgetGridEventSource = new ReplaySubject();
37
- this.widgetEvents$ = this.widgetGridEventSource.asObservable();
38
- }
39
- trigger(evt) {
40
- this.widgetGridEventSource.next(evt);
41
- }
42
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetGridEventService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
43
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetGridEventService, providedIn: 'root' }); }
44
- }
45
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetGridEventService, decorators: [{
46
- type: Injectable,
47
- args: [{
48
- providedIn: 'root',
49
- }]
50
- }] });
51
-
52
- class NoopComponent {
53
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NoopComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
54
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: NoopComponent, isStandalone: true, selector: "yuv-noop", inputs: { widgetConfig: "widgetConfig" }, ngImport: i0, template: "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"#000000\"><path d=\"M0 0h24v24H0V0z\" fill=\"none\"/><circle cx=\"15.5\" cy=\"9.5\" r=\"1.5\"/><circle cx=\"8.5\" cy=\"9.5\" r=\"1.5\"/><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm0-6c-2.33 0-4.32 1.45-5.12 3.5h1.67c.69-1.19 1.97-2 3.45-2s2.75.81 3.45 2h1.67c-.8-2.05-2.79-3.5-5.12-3.5z\"/></svg>", styles: [":host{height:100%;display:flex;flex-flow:column;align-items:center;justify-content:center;padding:var(--ymt-spacing-m);background-color:var(--panel-background);opacity:.7}:host svg{width:48px;height:48px;fill:var(--text-color-caption)}:host span{margin-top:var(--ymt-spacing-m)}\n"] }); }
55
- }
56
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: NoopComponent, decorators: [{
57
- type: Component,
58
- args: [{ selector: 'yuv-noop', template: "<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"#000000\"><path d=\"M0 0h24v24H0V0z\" fill=\"none\"/><circle cx=\"15.5\" cy=\"9.5\" r=\"1.5\"/><circle cx=\"8.5\" cy=\"9.5\" r=\"1.5\"/><path d=\"M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm0-6c-2.33 0-4.32 1.45-5.12 3.5h1.67c.69-1.19 1.97-2 3.45-2s2.75.81 3.45 2h1.67c-.8-2.05-2.79-3.5-5.12-3.5z\"/></svg>", styles: [":host{height:100%;display:flex;flex-flow:column;align-items:center;justify-content:center;padding:var(--ymt-spacing-m);background-color:var(--panel-background);opacity:.7}:host svg{width:48px;height:48px;fill:var(--text-color-caption)}:host span{margin-top:var(--ymt-spacing-m)}\n"] }]
59
- }], propDecorators: { widgetConfig: [{
60
- type: Input
61
- }] } });
62
-
63
- /**
64
- * This service provides the list of widgets that could be added
65
- * to a widget grid. You could use it to register your own
66
- * widgets.
67
- */
68
- class WidgetGridRegistry {
69
- constructor() {
70
- this.translate = inject(TranslateService);
71
- /**
72
- * List of pre-registered widgets provided out-of-the-box
73
- * by the widget grid module
74
- */
75
- this.registeredWidgets = [];
76
- /**
77
- * Buckets are collection of widget references.
78
- * You can put any widget registered gloabally into a bucket. Later on you can grab
79
- * widgets from a certain bucket. This enables apps to structure their widgets when e.g.
80
- * using multiple widget grids with their own set of available widgets.
81
- */
82
- this.widgetBuckets = {};
83
- }
84
- /**
85
- * Get the noop component. This component will be rendered in
86
- * the grid tile if not matching widget could be found in the
87
- * list of registered widgets. It will show some kind of 'not
88
- * found' message and provide the controls to remove that none
89
- * existing component from the widget grid.
90
- * @returns NoopComponent
91
- */
92
- getNoopWidget() {
93
- return {
94
- id: 'noop',
95
- label: this.translate.instant('yuv.widget-grid.widget.noop.label'),
96
- widgetComponent: NoopComponent
97
- };
98
- }
99
- /**
100
- * Setup components are the administrative part of a widget. They
101
- * are used to set up a widget. Not all the widgets will have a setup
102
- * component.
103
- * @param widgetName The widgets name
104
- * @returns The setup component of a widget. Throws error if there
105
- * is not widget registered with the given name
106
- */
107
- getWidgetSetupComponent(widgetName) {
108
- const widget = this.registeredWidgets.find((w) => w.id === widgetName);
109
- if (!widget)
110
- throw Error('Widget setup component not found');
111
- return widget.setupComponent;
112
- }
113
- /**
114
- * Get the component for a widget. This is the component that will
115
- * be rendered in a grid tile.
116
- * @param widgetName The widgets name
117
- * @returns The widget component or noop component if there is
118
- * no component registered with the given name
119
- */
120
- getWidgetComponent(widgetName) {
121
- const widget = this.registeredWidgets.find((w) => w.id === widgetName);
122
- if (!widget)
123
- console.error('Widget component not found');
124
- return widget?.widgetComponent || NoopComponent;
125
- }
126
- /**
127
- * Adds a new widget to the list of registered widgets. That way
128
- * you can create custom widgets that are then available to be
129
- * added to a users widget grid.
130
- * @param widget The widget to be registered
131
- * @param bucket List of buckets to register to. If a bucket does
132
- * not exist it'll be created.
133
- */
134
- registerGridWidget(widget, buckets) {
135
- const existingWidget = this.registeredWidgets.find((w) => w.id === widget.id);
136
- if (!existingWidget)
137
- this.registeredWidgets.push(widget);
138
- if (buckets?.length) {
139
- buckets.forEach((b) => {
140
- this._addToBucket(b, widget.id);
141
- });
142
- }
143
- }
144
- /**
145
- * Register a collection of widgets
146
- * @param widgets The widgets to be registered
147
- * @param bucket List of buckets to register to. If a bucket does
148
- * not exist it'll be created.
149
- */
150
- registerGridWidgets(widgets, buckets) {
151
- const alreadyRegisteredWidgetNames = this.registeredWidgets.map((w) => w.id);
152
- const widgetsToRegister = widgets.filter((w) => !alreadyRegisteredWidgetNames.includes(w.id));
153
- this.registeredWidgets = [...this.registeredWidgets, ...widgetsToRegister.map((w) => this.#translateLabel(w))];
154
- if (buckets?.length) {
155
- buckets.forEach((b) => widgets.forEach((w) => this._addToBucket(b, w.id)));
156
- }
157
- }
158
- #translateLabel(widget) {
159
- const translatedLabel = this.translate.instant(widget.label);
160
- return { ...widget, label: translatedLabel && !translatedLabel.startsWith('!missing') ? translatedLabel : widget.label };
161
- }
162
- _addToBucket(bucket, widgetName) {
163
- if (!this.widgetBuckets[bucket])
164
- this.widgetBuckets[bucket] = [];
165
- this.widgetBuckets[bucket].push(widgetName);
166
- }
167
- removeRegisteredWidget(id) {
168
- this.registeredWidgets = this.registeredWidgets.filter((w) => w.id !== id);
169
- }
170
- clearRegisteredWidget() {
171
- this.registeredWidgets = [];
172
- }
173
- /**
174
- * Get registered widgets. This list could be narrowed down by a list
175
- * of buckets. Buckets are lists of registered widgets registered for
176
- * a certain key (the buckets name).
177
- * @param buckets name of buckets to restrict the widgets to
178
- * @returns Array of grid widgets
179
- */
180
- getRegisteredWidgets(buckets) {
181
- if (buckets?.length) {
182
- // buckets may contain wildcards ...
183
- // grab all buckets matching the wildcards
184
- const matchedBuckets = {};
185
- buckets.forEach((b) => {
186
- if (b.match(/[*?]/)) {
187
- // bucket has a pattern
188
- Object.keys(this.widgetBuckets).forEach((wb) => {
189
- if (this._wildcardMatch(wb, b))
190
- matchedBuckets[wb] = 0;
191
- });
192
- }
193
- else
194
- matchedBuckets[b] = 0;
195
- });
196
- const bucketWidgetNames = {};
197
- Object.keys(matchedBuckets).forEach((b) => this.widgetBuckets[b].forEach((widgetName) => {
198
- bucketWidgetNames[widgetName] = 0;
199
- }));
200
- const widgetNames = Object.keys(bucketWidgetNames);
201
- return this.registeredWidgets.filter((w) => widgetNames.includes(w.id)).map((w) => this.#translateLabel(w));
202
- }
203
- else
204
- return this.registeredWidgets.map((w) => this.#translateLabel(w));
205
- }
206
- _wildcardMatch(text, pattern) {
207
- const regexPattern = new RegExp('^' + pattern.replace(/\?/g, '.').replace(/\*/g, '.*') + '$');
208
- return regexPattern.test(text);
209
- }
210
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetGridRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
211
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetGridRegistry, providedIn: 'root' }); }
212
- }
213
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetGridRegistry, decorators: [{
214
- type: Injectable,
215
- args: [{
216
- providedIn: 'root'
217
- }]
218
- }] });
219
-
220
- class WidgetGridUtils {
221
- static { this.PREF_FUNCTION = 'Function'; }
222
- static { this.PREF_RANGEVALUE = 'RangeValue'; }
223
- /**
224
- * Takes a `WidgetGridItemConfig` and stringifies it. The challenge
225
- * here is that callback functions should also be stringified.
226
- * @param gridItemConfig the config object
227
- */
228
- static gridConfigStringify(o) {
229
- return JSON.stringify(o, (key, value) => {
230
- if (typeof value === 'function') {
231
- return `/${WidgetGridUtils.PREF_FUNCTION}(${value.toString()})/`;
232
- }
233
- return value;
234
- });
235
- }
236
- /**
237
- * Takes a string stringified with `gridConfigStringify()` and parses it
238
- * to output a proper WidgetGridItemConfig.
239
- * @param stringifiedConfig stringified widget grid config
240
- */
241
- static gridConfigParse(stringifiedConfig) {
242
- return JSON.parse(stringifiedConfig, function (key, value) {
243
- if (typeof value === 'string' &&
244
- value.startsWith(`/${WidgetGridUtils.PREF_FUNCTION}(`) &&
245
- // value.startsWith('/Function(') &&
246
- value.endsWith(')/')) {
247
- value = value.substring(WidgetGridUtils.PREF_FUNCTION.length + 2, value.length - 2);
248
- return (0, eval)('(' + value + ')');
249
- }
250
- return value;
251
- });
252
- }
253
- static uuid() {
254
- return WidgetGridUtils._p8() + WidgetGridUtils._p8(true) + WidgetGridUtils._p8(true) + WidgetGridUtils._p8();
255
- }
256
- static _p8(s) {
257
- const p = (Math.random().toString(16) + '000000000').substr(2, 8);
258
- return s ? `-${p.substr(0, 4)}-${p.substr(4, 4)}` : p;
259
- }
260
- }
261
-
262
- /**
263
- * Service managing a widget grid. Also includes a set of labels that will be
264
- * used by the grid and its widgets. Default labels are provided out of the
265
- * box. But if you want to use custom ones or add i18n you could overwrite
266
- * them. The grid as well as the widgets will use those labels or fall back
267
- * to their default ones. If you are developing own widgets you should
268
- * consider using those labels as well.
269
- */
270
- class WidgetGridService {
271
- constructor(widgetGridRegistry) {
272
- this.widgetGridRegistry = widgetGridRegistry;
273
- this.widgetGrid = [];
274
- this.widgetGridSource = new ReplaySubject();
275
- this.widgetGrid$ = this.widgetGridSource.asObservable();
276
- this.widgetGridUpdateSource = new Subject();
277
- /**
278
- * Emitted when the widget grid has been updated
279
- */
280
- this.widgetGridUpdate$ = this.widgetGridUpdateSource.asObservable();
281
- this.addItemSize = {
282
- rows: 2,
283
- cols: 3,
284
- };
285
- }
286
- setWidgetGrid(gridItemConfig) {
287
- if (gridItemConfig) {
288
- // create actual widget grid from widget grid config
289
- this.widgetGrid = [...gridItemConfig].map((gic) => {
290
- const cmp = this.widgetGridRegistry.getWidgetComponent(gic.widgetName);
291
- const gc = {
292
- ...gic,
293
- widget: cmp,
294
- widgetConfigMap: {
295
- widgetConfig: cmp === NoopComponent
296
- ? {
297
- widgetName: gic.widgetName,
298
- }
299
- : gic.widgetConfig,
300
- },
301
- };
302
- return gc;
303
- });
304
- }
305
- else {
306
- this.widgetGrid = [];
307
- }
308
- this.widgetGridSource.next(this.widgetGrid);
309
- }
310
- /**
311
- * Update config of an existing widget
312
- * @param widgetId ID of the widget to be updated
313
- * @param setupWidgetConfig The updated configuration for that widget
314
- */
315
- updateWidget(widgetId, setupWidgetConfig) {
316
- const gridWidget = this.widgetGrid.find((w) => w.id === widgetId);
317
- if (gridWidget && setupWidgetConfig) {
318
- gridWidget.widgetConfig = setupWidgetConfig;
319
- gridWidget.widgetConfigMap = { widgetConfig: setupWidgetConfig };
320
- }
321
- this.widgetGridSource.next(this.widgetGrid);
322
- this.widgetGridUpdateSource.next(widgetId);
323
- }
324
- replaceWidget(widgetId, widgetName, setupWidgetConfig) {
325
- const gridWidgetIndex = this.widgetGrid.findIndex((w) => w.id === widgetId);
326
- if (gridWidgetIndex !== -1) {
327
- const w = {
328
- ...this.widgetGrid[gridWidgetIndex],
329
- ...{
330
- widgetName,
331
- widgetConfig: setupWidgetConfig || {},
332
- widget: this.widgetGridRegistry.getWidgetComponent(widgetName),
333
- widgetConfigMap: { widgetConfig: setupWidgetConfig || {} },
334
- },
335
- };
336
- this.widgetGrid[gridWidgetIndex] = w;
337
- this.widgetGridSource.next(this.widgetGrid);
338
- this.widgetGridUpdateSource.next(widgetId);
339
- }
340
- }
341
- /**
342
- * Add a new grid item to the widget grid.
343
- * @param widgetName The name of the grid item to be added
344
- * @param setupWidgetConfig
345
- */
346
- addWidget(widgetName, setupWidgetConfig) {
347
- const gridWidget = {
348
- id: WidgetGridUtils.uuid(),
349
- widgetName,
350
- widgetConfig: setupWidgetConfig,
351
- widget: this.widgetGridRegistry.getWidgetComponent(widgetName),
352
- widgetConfigMap: { widgetConfig: setupWidgetConfig },
353
- x: 0,
354
- y: 0,
355
- rows: this.addItemSize.rows,
356
- cols: this.addItemSize.cols,
357
- };
358
- this.widgetGrid.push(gridWidget);
359
- this.widgetGridSource.next(this.widgetGrid);
360
- this.widgetGridUpdateSource.next(gridWidget.id);
361
- }
362
- removeWidget(gridItemId) {
363
- const idx = this.widgetGrid.findIndex((w) => w.id === gridItemId);
364
- this.widgetGrid.splice(idx, 1);
365
- this.widgetGridSource.next(this.widgetGrid);
366
- this.widgetGridUpdateSource.next(gridItemId);
367
- }
368
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetGridService, deps: [{ token: WidgetGridRegistry }], target: i0.ɵɵFactoryTarget.Injectable }); }
369
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetGridService }); }
370
- }
371
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetGridService, decorators: [{
372
- type: Injectable
373
- }], ctorParameters: () => [{ type: WidgetGridRegistry }] });
374
-
375
- class WidgetPickerComponent {
376
- #widgetGridRegistry;
377
- #widgetGridService;
378
- #dialogData;
379
- #dialogRef;
380
- #pickerDataEffect;
381
- constructor() {
382
- this.#widgetGridRegistry = inject(WidgetGridRegistry);
383
- this.#widgetGridService = inject(WidgetGridService);
384
- this.#dialogData = inject(MAT_DIALOG_DATA);
385
- this.#dialogRef = inject((MatDialogRef));
386
- this.pickerFormControl = new FormControl();
387
- this.widgetConfigMap = {};
388
- this.widgetConfigDirty = false;
389
- this.registeredWidgets = [];
390
- this.setupWidgetDynamicOutputs = {
391
- widgetConfigChange: (widgetConfig) => {
392
- this.onSetupConfigChange(widgetConfig);
393
- },
394
- widgetConfigStateChange: (s) => {
395
- this.widgetConfigState = s || undefined;
396
- }
397
- };
398
- this.pickerData = input(this.#dialogData.pickerData, ...(ngDevMode ? [{ debugName: "pickerData" }] : []));
399
- this.#pickerDataEffect = effect(() => {
400
- const pd = this.pickerData();
401
- if (pd) {
402
- const gridWidget = this.#widgetGridRegistry
403
- .getRegisteredWidgets()
404
- .find((w) => w.id === pd.widgetName);
405
- this.selectedWidget = gridWidget?.setupComponent ? gridWidget : undefined;
406
- this.widgetConfigMap = pd.widgetConfigMap || {};
407
- this.widgetId = pd.widgetId;
408
- }
409
- }, ...(ngDevMode ? [{ debugName: "#pickerDataEffect" }] : []));
410
- /**
411
- * Collection of buckets to load available widgets from. Wildcards are also posssible:
412
- * `[buckets]="['app.default', '*.public.*', 'app.no?.widgets']"`
413
- *
414
- * `*` represents any character 0-n times
415
- * `?` represents exactly one character
416
- */
417
- this.buckets = input(this.#dialogData.buckets, ...(ngDevMode ? [{ debugName: "buckets" }] : []));
418
- this.picked = output();
419
- this.canceled = output();
420
- this.pickerFormControl.valueChanges.pipe(takeUntilDestroyed()).subscribe((widgets) => {
421
- if (widgets.length)
422
- this.pick(widgets[0]);
423
- });
424
- }
425
- pick(widget) {
426
- if (widget?.setupComponent) {
427
- // if the selected widget has a setup component, we'll continue ...
428
- this.selectedWidget = widget?.setupComponent ? widget : undefined;
429
- }
430
- else {
431
- if (this.widgetId) {
432
- // update existing widget
433
- this.#widgetGridService.replaceWidget(this.widgetId, widget.id);
434
- }
435
- else {
436
- this.#widgetGridService.addWidget(widget.id);
437
- }
438
- this.picked.emit();
439
- this.#dialogRef.close();
440
- }
441
- }
442
- onSetupConfigChange(setupConfig) {
443
- this.widgetConfigDirty = !!setupConfig;
444
- this.setupWidgetConfig = setupConfig;
445
- }
446
- setupComponentSave() {
447
- // TODO: save/emit config
448
- if (this.widgetId && this.selectedWidget) {
449
- if (this.pickerData()?.widgetName !== this.selectedWidget.id) {
450
- this.#widgetGridService.replaceWidget(this.widgetId, this.selectedWidget.id, this.setupWidgetConfig);
451
- }
452
- else {
453
- this.#widgetGridService.updateWidget(this.widgetId, this.setupWidgetConfig);
454
- }
455
- }
456
- else {
457
- this.#widgetGridService.addWidget(this.selectedWidget.id, this.setupWidgetConfig);
458
- }
459
- this.picked.emit();
460
- this.#dialogRef.close();
461
- }
462
- setupComponentCancel() {
463
- this.reset();
464
- }
465
- cancel() {
466
- this.canceled.emit();
467
- this.#dialogRef.close();
468
- }
469
- reset() {
470
- this.selectedWidget = undefined;
471
- this.setupWidgetConfig = undefined;
472
- }
473
- ngOnInit() {
474
- this.registeredWidgets = this.#widgetGridRegistry.getRegisteredWidgets(this.buckets());
475
- }
476
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
477
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: WidgetPickerComponent, isStandalone: true, selector: "yuv-widget-picker", inputs: { pickerData: { classPropertyName: "pickerData", publicName: "pickerData", isSignal: true, isRequired: false, transformFunction: null }, buckets: { classPropertyName: "buckets", publicName: "buckets", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { picked: "picked", canceled: "canceled" }, ngImport: i0, template: "<yuv-dialog [headertitel]=\"selectedWidget ? selectedWidget.label : ('yuv.widget-grid.widget-picker.title' | translate)\">\n <!-- <header class=\"dark\" [ngClass]=\"{ listing: !selectedWidget }\">\n @if (selectedWidget) {\n <button mat-icon-button (click)=\"reset()\"><mat-icon>back</mat-icon></button>\n }\n <div class=\"title\">{{ selectedWidget ? selectedWidget.label : ('yuv.widget-grid.widget-picker.title' | translate) }}</div>\n <button mat-icon-button (click)=\"cancel()\"><mat-icon>clear</mat-icon></button>\n </header> -->\n\n <main class=\"{{ !selectedWidget ? 'widget-listing' : 'widget-setup' }}\">\n @if (!selectedWidget) {\n <mat-selection-list role=\"list\" [formControl]=\"pickerFormControl\" [multiple]=\"false\" [hideSingleSelectionIndicator]=\"true\">\n <!-- list of avalable widgets -->\n @for (w of registeredWidgets; track $index) {\n <mat-list-option [value]=\"w\">\n {{ w.label }}\n </mat-list-option>\n } @empty {\n <div class=\"empty\">\n {{ 'yuv.widget-grid.widget-picker.empty' | translate }}\n </div>\n }\n </mat-selection-list>\n } @else {\n <div class=\"component\">\n <ng-container\n *ngComponentOutlet=\"selectedWidget!.setupComponent!; ndcDynamicInputs: widgetConfigMap; ndcDynamicOutputs: setupWidgetDynamicOutputs\"\n ></ng-container>\n </div>\n }\n </main>\n <footer>\n @if (selectedWidget) {\n <button ymtButton=\"secondary\" (click)=\"setupComponentCancel()\">{{ 'yuv.widget-grid.button.cancel' | translate }}</button>\n <button ymtButton=\"primary\" [disabled]=\"!widgetConfigDirty || widgetConfigState === 'INVALID'\" (click)=\"setupComponentSave()\">\n {{ 'yuv.widget-grid.button.save' | translate }}\n </button>\n } @else {\n <button ymtButton=\"secondary\" (click)=\"cancel()\">{{ 'yuv.widget-grid.button.cancel' | translate }}</button>\n }\n </footer>\n</yuv-dialog>\n", styles: [":host .empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}:host main.widget-setup{height:100%;display:grid;grid-template-rows:1fr auto;grid-template-columns:1fr;grid-template-areas:\"component\" \"buttons\"}:host main.widget-listing .widget{padding:var(--app-pane-padding);border-bottom:1px solid var(--panel-divider-color);cursor:pointer}:host main.widget-listing .widget:hover{background-color:var(--item-focus-background-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitle", "headertitel"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i2.MatSelectionList, selector: "mat-selection-list", inputs: ["color", "compareWith", "multiple", "hideSingleSelectionIndicator", "disabled"], outputs: ["selectionChange"], exportAs: ["matSelectionList"] }, { kind: "component", type: i2.MatListOption, selector: "mat-list-option", inputs: ["togglePosition", "checkboxPosition", "color", "value", "selected"], outputs: ["selectedChange"], exportAs: ["matListOption"] }, { kind: "ngmodule", type: DynamicIoModule }, { kind: "directive", type: i3.ComponentOutletInjectorDirective, selector: "[ngComponentOutlet]", exportAs: ["ndcComponentOutletInjector"] }, { kind: "directive", type: i3.ComponentOutletIoDirective, selector: "[ngComponentOutletNdcDynamicInputs],[ngComponentOutletNdcDynamicOutputs]", inputs: ["ngComponentOutletNdcDynamicInputs", "ngComponentOutletNdcDynamicOutputs"], exportAs: ["ndcDynamicIo"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: SignalComponentIoModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
478
- }
479
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WidgetPickerComponent, decorators: [{
480
- type: Component,
481
- args: [{ selector: 'yuv-widget-picker', imports: [
482
- CommonModule,
483
- MatButtonModule,
484
- TranslatePipe,
485
- MatIconModule,
486
- DialogComponent,
487
- YmtButtonDirective,
488
- MatListModule,
489
- DynamicIoModule,
490
- ReactiveFormsModule,
491
- SignalComponentIoModule
492
- ], template: "<yuv-dialog [headertitel]=\"selectedWidget ? selectedWidget.label : ('yuv.widget-grid.widget-picker.title' | translate)\">\n <!-- <header class=\"dark\" [ngClass]=\"{ listing: !selectedWidget }\">\n @if (selectedWidget) {\n <button mat-icon-button (click)=\"reset()\"><mat-icon>back</mat-icon></button>\n }\n <div class=\"title\">{{ selectedWidget ? selectedWidget.label : ('yuv.widget-grid.widget-picker.title' | translate) }}</div>\n <button mat-icon-button (click)=\"cancel()\"><mat-icon>clear</mat-icon></button>\n </header> -->\n\n <main class=\"{{ !selectedWidget ? 'widget-listing' : 'widget-setup' }}\">\n @if (!selectedWidget) {\n <mat-selection-list role=\"list\" [formControl]=\"pickerFormControl\" [multiple]=\"false\" [hideSingleSelectionIndicator]=\"true\">\n <!-- list of avalable widgets -->\n @for (w of registeredWidgets; track $index) {\n <mat-list-option [value]=\"w\">\n {{ w.label }}\n </mat-list-option>\n } @empty {\n <div class=\"empty\">\n {{ 'yuv.widget-grid.widget-picker.empty' | translate }}\n </div>\n }\n </mat-selection-list>\n } @else {\n <div class=\"component\">\n <ng-container\n *ngComponentOutlet=\"selectedWidget!.setupComponent!; ndcDynamicInputs: widgetConfigMap; ndcDynamicOutputs: setupWidgetDynamicOutputs\"\n ></ng-container>\n </div>\n }\n </main>\n <footer>\n @if (selectedWidget) {\n <button ymtButton=\"secondary\" (click)=\"setupComponentCancel()\">{{ 'yuv.widget-grid.button.cancel' | translate }}</button>\n <button ymtButton=\"primary\" [disabled]=\"!widgetConfigDirty || widgetConfigState === 'INVALID'\" (click)=\"setupComponentSave()\">\n {{ 'yuv.widget-grid.button.save' | translate }}\n </button>\n } @else {\n <button ymtButton=\"secondary\" (click)=\"cancel()\">{{ 'yuv.widget-grid.button.cancel' | translate }}</button>\n }\n </footer>\n</yuv-dialog>\n", styles: [":host .empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%}:host main.widget-setup{height:100%;display:grid;grid-template-rows:1fr auto;grid-template-columns:1fr;grid-template-areas:\"component\" \"buttons\"}:host main.widget-listing .widget{padding:var(--app-pane-padding);border-bottom:1px solid var(--panel-divider-color);cursor:pointer}:host main.widget-listing .widget:hover{background-color:var(--item-focus-background-color)}\n"] }]
493
- }], ctorParameters: () => [], propDecorators: { pickerData: [{ type: i0.Input, args: [{ isSignal: true, alias: "pickerData", required: false }] }], buckets: [{ type: i0.Input, args: [{ isSignal: true, alias: "buckets", required: false }] }], picked: [{ type: i0.Output, args: ["picked"] }], canceled: [{ type: i0.Output, args: ["canceled"] }] } });
494
-
495
- class YuvWidgetGridComponent {
496
- #dialog;
497
- #widgetGridService;
498
- #widgetGridEventService;
499
- #gridConfigEffect;
500
- #editModeEffect;
501
- #gridItemConfigEffect;
502
- constructor() {
503
- this.#dialog = inject(MatDialog);
504
- this.#widgetGridService = inject(WidgetGridService);
505
- this.#widgetGridEventService = inject(WidgetGridEventService);
506
- this.gridsterItems = viewChild.required(GridsterItemComponent);
507
- this.widgetPicker = viewChild.required('widgetPicker', { read: TemplateRef });
508
- this.options = {
509
- gridType: GridType.Fit,
510
- displayGrid: DisplayGrid.None,
511
- pushItems: false,
512
- outerMargin: false,
513
- swap: false,
514
- draggable: {
515
- enabled: false,
516
- ignoreContent: true,
517
- dragHandleClass: 'dragHandle'
518
- },
519
- resizable: {
520
- enabled: false
521
- },
522
- itemChangeCallback: (gridsterItem, gridsterItemComponent) => {
523
- this.emitChange();
524
- }
525
- };
526
- this.gridConfig = input(...(ngDevMode ? [undefined, { debugName: "gridConfig" }] : []));
527
- this.#gridConfigEffect = effect(() => {
528
- const cfg = this.gridConfig();
529
- if (cfg?.rows) {
530
- this.options.minRows = cfg.rows;
531
- this.options.maxRows = cfg.rows;
532
- }
533
- if (cfg?.columns) {
534
- this.options.minCols = cfg.columns;
535
- this.options.maxCols = cfg.columns;
536
- }
537
- if (cfg?.gap) {
538
- this.options.margin = cfg.gap;
539
- }
540
- if (cfg?.newItemWidth || cfg?.newItemHeight) {
541
- this.#widgetGridService.addItemSize = {
542
- cols: cfg?.newItemWidth || -1, // default value -1 means the grid will autoposition the new item
543
- rows: cfg?.newItemHeight || -1 // default value -1 means the grid will autoposition the new item
544
- };
545
- }
546
- if (cfg?.gridType) {
547
- this.options.gridType = cfg.gridType;
548
- }
549
- if (this.options.api?.optionsChanged) {
550
- this.options.api.optionsChanged();
551
- }
552
- }, ...(ngDevMode ? [{ debugName: "#gridConfigEffect" }] : []));
553
- this._editMode = signal(false, ...(ngDevMode ? [{ debugName: "_editMode" }] : []));
554
- /**
555
- * Whether or not to enable edit mode. In edit mode controls
556
- * for editing existing tiles and creating new ones are shown.
557
- * This mode also enables positioning and resizing of the tiles.
558
- */
559
- this.editMode = input(false, ...(ngDevMode ? [{ debugName: "editMode" }] : []));
560
- this.#editModeEffect = effect(() => {
561
- const e = this.editMode();
562
- this._editMode.set(e);
563
- this.options.draggable.enabled = !!e;
564
- this.options.resizable.enabled = !!e;
565
- this.options.displayGrid = e ? DisplayGrid.Always : DisplayGrid.None;
566
- // set timeout to ensure that the grid has been redrawn before notifying the widgets about the change
567
- setTimeout(() => {
568
- if (this.options.api?.optionsChanged) {
569
- this.options.api.optionsChanged();
570
- }
571
- }, 0);
572
- }, ...(ngDevMode ? [{ debugName: "#editModeEffect" }] : []));
573
- this.gridItemConfig = input(undefined, ...(ngDevMode ? [{ debugName: "gridItemConfig" }] : []));
574
- this.#gridItemConfigEffect = effect(() => {
575
- this.#widgetGridService.setWidgetGrid(this.gridItemConfig());
576
- }, ...(ngDevMode ? [{ debugName: "#gridItemConfigEffect" }] : []));
577
- /**
578
- * Collection of buckets to load available widgets from. Wildcards are also posssible:
579
- * `[buckets]="['app.default', '*.public.*', 'app.no?.widgets']"`
580
- *
581
- * `*` represents any character 0-n times
582
- * `?` represents exactly one character
583
- */
584
- this.buckets = input(undefined, ...(ngDevMode ? [{ debugName: "buckets" }] : []));
585
- // @Input() buckets?: string[];
586
- /**
587
- * Emitted when the grid has been changed
588
- */
589
- this.gridChange = output();
590
- this.gridItemEvent = output();
591
- /**
592
- * Emitted when the widget picker is opened or closed in edit mode
593
- */
594
- this.widgetPickerOpen = output();
595
- this.widgetGrid = [];
596
- this.#widgetGridService.widgetGrid$.pipe(takeUntilDestroyed()).subscribe((widgetGrid) => {
597
- this.widgetGrid = widgetGrid;
598
- });
599
- this.#widgetGridEventService.widgetEvents$.pipe(takeUntilDestroyed()).subscribe((evt) => {
600
- this.gridItemEvent.emit(evt);
601
- });
602
- this.#widgetGridService.widgetGridUpdate$.pipe(takeUntilDestroyed()).subscribe((_) => {
603
- this.emitChange();
604
- });
605
- }
606
- openWidgetPicker(item) {
607
- if (item) {
608
- // open setup component for selected grid item
609
- this.widgetPickerData = {
610
- widgetName: item.widgetName,
611
- widgetConfigMap: item.widgetConfigMap,
612
- widgetId: item.id
613
- };
614
- }
615
- else {
616
- this.widgetPickerData = undefined;
617
- }
618
- this.widgetPickerOpen.emit(true);
619
- this.#dialog
620
- .open(this.widgetPicker(), {
621
- data: {
622
- pickerData: this.widgetPickerData,
623
- buckets: this.buckets()
624
- }
625
- })
626
- .afterClosed()
627
- .subscribe(() => this.widgetPickerOpen.emit(false));
628
- }
629
- /**
630
- * Removes a widget from the grid
631
- * @param item The widget to be removed
632
- */
633
- removeItem(item) {
634
- this.#widgetGridService.removeWidget(item.id);
635
- }
636
- /**
637
- * Add a new widget to the grid by opening the widget picker
638
- */
639
- addItem() {
640
- this.openWidgetPicker();
641
- }
642
- emitChange() {
643
- const mapped = [];
644
- this.widgetGrid.forEach((i) => {
645
- const m = { ...i };
646
- delete m['widget'];
647
- delete m['widgetConfigMap'];
648
- mapped.push(m);
649
- });
650
- this.gridChange.emit(mapped);
651
- }
652
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: YuvWidgetGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
653
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: YuvWidgetGridComponent, isStandalone: true, selector: "yuv-widget-grid", inputs: { gridConfig: { classPropertyName: "gridConfig", publicName: "gridConfig", isSignal: true, isRequired: false, transformFunction: null }, editMode: { classPropertyName: "editMode", publicName: "editMode", isSignal: true, isRequired: false, transformFunction: null }, gridItemConfig: { classPropertyName: "gridItemConfig", publicName: "gridItemConfig", isSignal: true, isRequired: false, transformFunction: null }, buckets: { classPropertyName: "buckets", publicName: "buckets", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { gridChange: "gridChange", gridItemEvent: "gridItemEvent", widgetPickerOpen: "widgetPickerOpen" }, host: { properties: { "class.widget-grid-edit": "editMode()" } }, providers: [WidgetGridService], viewQueries: [{ propertyName: "gridsterItems", first: true, predicate: GridsterItemComponent, descendants: true, isSignal: true }, { propertyName: "widgetPicker", first: true, predicate: ["widgetPicker"], descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "@if (_editMode()) {\n <button class=\"fab\" mat-fab [attr.aria-label]=\"'yuv.widget-grid.widget.add.label' | translate\" (click)=\"addItem()\" [matTooltip]=\"'yuv.widget-grid.widget.add.tooltip' | translate\">\n <mat-icon>add</mat-icon>\n </button>\n}\n\n@if (widgetGrid.length === 0 && !_editMode()) {\n <div class=\"empty\">\n <!-- <p>{{ 'yuv.widget-grid.empty' | translate }}</p>\n <button ymtButton=\"primary\" (click)=\"_editMode.set(true)\">\n {{'yuv.widget-grid.empty.create' | translate}}</button> -->\n <ng-content select=\".empty\"><p>{{ 'yuv.widget-grid.empty' | translate }}</p></ng-content>\n </div>\n} @else {\n <gridster [options]=\"options\">\n @for (item of widgetGrid; track item.id) {\n <gridster-item [item]=\"item\">\n @if (_editMode()) {\n <div class=\"toolbar\">\n <!-- drag handle -->\n <mat-icon class=\"dragHandle ymt-icon--size-s\">drag_indicator</mat-icon>\n <!-- edit -->\n <button ymt-icon-button icon-button-size=\"small\"\n [matTooltip]=\"'yuv.widget-grid.widget.edit.tooltip' | translate\"\n (click)=\"openWidgetPicker(item)\"><mat-icon class=\"ymt-icon--size-s\">edit</mat-icon></button>\n <!-- remove -->\n <button ymt-icon-button icon-button-size=\"small\"\n [matTooltip]=\"'yuv.widget-grid.widget.remove.tooltip' | translate\"\n (click)=\"removeItem(item)\"><mat-icon class=\"ymt-icon--size-s\">clear</mat-icon></button>\n </div>\n }\n <div class=\"cmp\">\n <ng-container *ngComponentOutlet=\"item.widget; ndcDynamicInputs: item.widgetConfigMap\"></ng-container>\n </div>\n </gridster-item>\n }\n </gridster>\n}\n<ng-template #widgetPicker>\n <yuv-widget-picker [pickerData]=\"widgetPickerData\" [buckets]=\"buckets()\"></yuv-widget-picker>\n</ng-template>\n", styles: [":host{--_widget-grid-toolbar-background: var(--widget-grid-toolbar-background, var(--ymt-surface));--_widget-grid-on-toolbar: var(--widget-grid-on-toolbar, var(--ymt-on-surface));position:relative}:host .fab{position:absolute;inset-inline-end:var(--ymt-spacing-m);inset-block-end:var(--ymt-spacing-m);z-index:100}:host .cmp{height:100%}:host.widget-grid-edit gridster-item{outline:1px solid var(--ymt-outline);outline-offset:-1px}:host .empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--ymt-on-surface);font:var(--ymt-font-body-medium)}:host .empty p{padding:var(--ymt-spacing-m);max-width:45ch;text-align:center}:host gridster{background-color:transparent}:host gridster ::ng-deep .gridster-column,:host gridster ::ng-deep .gridster-row{border-color:var(--ymt-outline-variant);transition:none}:host gridster-item{transition:none;background-color:transparent}:host gridster-item .toolbar{position:absolute;z-index:1;background-color:var(--_widget-grid-toolbar-background);color:var(--_widget-grid-on-toolbar);right:0;top:var(--ymt-spacing-xs);padding:var(--ymt-spacing-xs);gap:var(--ymt-spacing-s);display:flex;flex-flow:row nowrap;align-items:center;outline:1px solid var(--ymt-outline);outline-offset:-1px}:host gridster-item .toolbar button{color:currentColor}:host gridster-item .dragHandle{display:flex;flex-flow:column;align-items:center;justify-content:center;padding:0 var(--ymt-spacing-s);cursor:move}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: DynamicIoModule }, { kind: "directive", type: i3.ComponentOutletInjectorDirective, selector: "[ngComponentOutlet]", exportAs: ["ndcComponentOutletInjector"] }, { kind: "directive", type: i3.ComponentOutletIoDirective, selector: "[ngComponentOutletNdcDynamicInputs],[ngComponentOutletNdcDynamicOutputs]", inputs: ["ngComponentOutletNdcDynamicInputs", "ngComponentOutletNdcDynamicOutputs"], exportAs: ["ndcDynamicIo"] }, { kind: "ngmodule", type: SignalComponentIoModule }, { kind: "component", type: GridsterComponent, selector: "gridster", inputs: ["options"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i5.MatFabButton, selector: "button[mat-fab], a[mat-fab], button[matFab], a[matFab]", inputs: ["extended"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: WidgetPickerComponent, selector: "yuv-widget-picker", inputs: ["pickerData", "buckets"], outputs: ["picked", "canceled"] }, { kind: "component", type: GridsterItemComponent, selector: "gridster-item", inputs: ["item"], outputs: ["itemInit", "itemChange", "itemResize"] }, { kind: "directive", type: YmtIconButtonDirective, selector: "button[ymtIconButton],button[ymt-icon-button],a[ymtIconButton],a[ymt-icon-button]", inputs: ["disabled", "disableRipple", "aria-disabled", "disabledInteractive", "icon-button-size"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
654
- }
655
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: YuvWidgetGridComponent, decorators: [{
656
- type: Component,
657
- args: [{ selector: 'yuv-widget-grid', imports: [
658
- CommonModule,
659
- DynamicIoModule,
660
- SignalComponentIoModule,
661
- TranslatePipe,
662
- GridsterComponent,
663
- MatIconModule,
664
- MatTooltipModule,
665
- MatButtonModule,
666
- WidgetPickerComponent,
667
- GridsterItemComponent,
668
- YmtIconButtonDirective,
669
- MatTooltip
670
- ], providers: [WidgetGridService], host: { '[class.widget-grid-edit]': 'editMode()' }, template: "@if (_editMode()) {\n <button class=\"fab\" mat-fab [attr.aria-label]=\"'yuv.widget-grid.widget.add.label' | translate\" (click)=\"addItem()\" [matTooltip]=\"'yuv.widget-grid.widget.add.tooltip' | translate\">\n <mat-icon>add</mat-icon>\n </button>\n}\n\n@if (widgetGrid.length === 0 && !_editMode()) {\n <div class=\"empty\">\n <!-- <p>{{ 'yuv.widget-grid.empty' | translate }}</p>\n <button ymtButton=\"primary\" (click)=\"_editMode.set(true)\">\n {{'yuv.widget-grid.empty.create' | translate}}</button> -->\n <ng-content select=\".empty\"><p>{{ 'yuv.widget-grid.empty' | translate }}</p></ng-content>\n </div>\n} @else {\n <gridster [options]=\"options\">\n @for (item of widgetGrid; track item.id) {\n <gridster-item [item]=\"item\">\n @if (_editMode()) {\n <div class=\"toolbar\">\n <!-- drag handle -->\n <mat-icon class=\"dragHandle ymt-icon--size-s\">drag_indicator</mat-icon>\n <!-- edit -->\n <button ymt-icon-button icon-button-size=\"small\"\n [matTooltip]=\"'yuv.widget-grid.widget.edit.tooltip' | translate\"\n (click)=\"openWidgetPicker(item)\"><mat-icon class=\"ymt-icon--size-s\">edit</mat-icon></button>\n <!-- remove -->\n <button ymt-icon-button icon-button-size=\"small\"\n [matTooltip]=\"'yuv.widget-grid.widget.remove.tooltip' | translate\"\n (click)=\"removeItem(item)\"><mat-icon class=\"ymt-icon--size-s\">clear</mat-icon></button>\n </div>\n }\n <div class=\"cmp\">\n <ng-container *ngComponentOutlet=\"item.widget; ndcDynamicInputs: item.widgetConfigMap\"></ng-container>\n </div>\n </gridster-item>\n }\n </gridster>\n}\n<ng-template #widgetPicker>\n <yuv-widget-picker [pickerData]=\"widgetPickerData\" [buckets]=\"buckets()\"></yuv-widget-picker>\n</ng-template>\n", styles: [":host{--_widget-grid-toolbar-background: var(--widget-grid-toolbar-background, var(--ymt-surface));--_widget-grid-on-toolbar: var(--widget-grid-on-toolbar, var(--ymt-on-surface));position:relative}:host .fab{position:absolute;inset-inline-end:var(--ymt-spacing-m);inset-block-end:var(--ymt-spacing-m);z-index:100}:host .cmp{height:100%}:host.widget-grid-edit gridster-item{outline:1px solid var(--ymt-outline);outline-offset:-1px}:host .empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--ymt-on-surface);font:var(--ymt-font-body-medium)}:host .empty p{padding:var(--ymt-spacing-m);max-width:45ch;text-align:center}:host gridster{background-color:transparent}:host gridster ::ng-deep .gridster-column,:host gridster ::ng-deep .gridster-row{border-color:var(--ymt-outline-variant);transition:none}:host gridster-item{transition:none;background-color:transparent}:host gridster-item .toolbar{position:absolute;z-index:1;background-color:var(--_widget-grid-toolbar-background);color:var(--_widget-grid-on-toolbar);right:0;top:var(--ymt-spacing-xs);padding:var(--ymt-spacing-xs);gap:var(--ymt-spacing-s);display:flex;flex-flow:row nowrap;align-items:center;outline:1px solid var(--ymt-outline);outline-offset:-1px}:host gridster-item .toolbar button{color:currentColor}:host gridster-item .dragHandle{display:flex;flex-flow:column;align-items:center;justify-content:center;padding:0 var(--ymt-spacing-s);cursor:move}\n"] }]
671
- }], ctorParameters: () => [], propDecorators: { gridsterItems: [{ type: i0.ViewChild, args: [i0.forwardRef(() => GridsterItemComponent), { isSignal: true }] }], widgetPicker: [{ type: i0.ViewChild, args: ['widgetPicker', { ...{ read: TemplateRef }, isSignal: true }] }], gridConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridConfig", required: false }] }], editMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editMode", required: false }] }], gridItemConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridItemConfig", required: false }] }], buckets: [{ type: i0.Input, args: [{ isSignal: true, alias: "buckets", required: false }] }], gridChange: [{ type: i0.Output, args: ["gridChange"] }], gridItemEvent: [{ type: i0.Output, args: ["gridItemEvent"] }], widgetPickerOpen: [{ type: i0.Output, args: ["widgetPickerOpen"] }] } });
672
-
673
- class WorkspaceEditComponent {
674
- constructor() {
675
- this.dialogRef = inject((MatDialogRef));
676
- this.workspaceForm = input.required(...(ngDevMode ? [{ debugName: "workspaceForm" }] : []));
677
- this.workspaceSubmit = output();
678
- }
679
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WorkspaceEditComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
680
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.19", type: WorkspaceEditComponent, isStandalone: true, selector: "yuv-workspace-edit", inputs: { workspaceForm: { classPropertyName: "workspaceForm", publicName: "workspaceForm", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { workspaceSubmit: "workspaceSubmit" }, ngImport: i0, template: "<yuv-dialog [headertitel]=\"'yuv.widget-grid.workspaces.edit.title' | translate\">\n <main>\n <form id=\"workspaceEditForm\" [formGroup]=\"workspaceForm()\" (ngSubmit)=\"workspaceSubmit.emit()\">\n <mat-form-field class=\"yuv-form-field\">\n <mat-label>{{ 'yuv.widget-grid.workspaces.workspace.label' | translate }}</mat-label>\n <input matInput formControlName=\"label\" />\n </mat-form-field>\n </form>\n </main>\n <footer>\n <button ymtButton=\"secondary\" type=\"button\" (click)=\"dialogRef.close()\">\n {{ 'yuv.widget-grid.workspaces.edit.cancel' | translate }}\n </button>\n <button ymtButton=\"primary\" form=\"workspaceEditForm\" type=\"submit\" [disabled]=\"workspaceForm().invalid\">\n {{ 'yuv.widget-grid.workspaces.edit.save' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host main{padding:var(--ymt-spacing-m)}:host mat-form-field{width:100%}\n"], dependencies: [{ kind: "component", type: DialogComponent, selector: "yuv-dialog", inputs: ["headertitle", "headertitel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i1$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i1$1.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: TranslatePipe$1, name: "translate" }] }); }
681
- }
682
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: WorkspaceEditComponent, decorators: [{
683
- type: Component,
684
- args: [{ selector: 'yuv-workspace-edit', imports: [
685
- DialogComponent,
686
- MatFormFieldModule,
687
- MatInputModule,
688
- YmtButtonDirective,
689
- TranslatePipe$1,
690
- ReactiveFormsModule
691
- ], template: "<yuv-dialog [headertitel]=\"'yuv.widget-grid.workspaces.edit.title' | translate\">\n <main>\n <form id=\"workspaceEditForm\" [formGroup]=\"workspaceForm()\" (ngSubmit)=\"workspaceSubmit.emit()\">\n <mat-form-field class=\"yuv-form-field\">\n <mat-label>{{ 'yuv.widget-grid.workspaces.workspace.label' | translate }}</mat-label>\n <input matInput formControlName=\"label\" />\n </mat-form-field>\n </form>\n </main>\n <footer>\n <button ymtButton=\"secondary\" type=\"button\" (click)=\"dialogRef.close()\">\n {{ 'yuv.widget-grid.workspaces.edit.cancel' | translate }}\n </button>\n <button ymtButton=\"primary\" form=\"workspaceEditForm\" type=\"submit\" [disabled]=\"workspaceForm().invalid\">\n {{ 'yuv.widget-grid.workspaces.edit.save' | translate }}\n </button>\n </footer>\n</yuv-dialog>\n", styles: [":host main{padding:var(--ymt-spacing-m)}:host mat-form-field{width:100%}\n"] }]
692
- }], propDecorators: { workspaceForm: [{ type: i0.Input, args: [{ isSignal: true, alias: "workspaceForm", required: true }] }], workspaceSubmit: [{ type: i0.Output, args: ["workspaceSubmit"] }] } });
1
+ export * from '@yuuvis/client-components/widget-grid';
693
2
 
694
3
  /**
695
- * Component for managing multiple widget grids in so called workspaces.
696
- * Each workspace can have its own configuration and widgets. The user can
697
- * switch between workspaces to use or edit the widgets in the current workspace.
4
+ * @deprecated Import from `@yuuvis/client-components/widget-grid` instead.
5
+ * This entry point is a backward-compatibility shim and will be removed in a future release.
698
6
  */
699
- class YuvWidgetGridWorkspacesComponent {
700
- constructor() {
701
- this.#dialog = inject(MatDialog);
702
- this.#fb = inject(FormBuilder);
703
- this.#confirm = inject(ConfirmService);
704
- this.translate = inject(TranslateService);
705
- this.#DEFAULT_WORKSPACE_OPTIONS = {
706
- gridConfig: {
707
- columns: 10,
708
- rows: 10
709
- }
710
- };
711
- this.workspaceForm = this.#fb.group({
712
- id: [''],
713
- label: ['', Validators.required]
714
- });
715
- this.options = input(this.#DEFAULT_WORKSPACE_OPTIONS, ...(ngDevMode ? [{ debugName: "options" }] : []));
716
- this._workspaceOptions = computed(() => ({
717
- gridConfig: {
718
- ...this.#DEFAULT_WORKSPACE_OPTIONS.gridConfig,
719
- ...(this.options().gridConfig || {})
720
- }
721
- }), ...(ngDevMode ? [{ debugName: "_workspaceOptions" }] : []));
722
- this.workspaceConfig = input(undefined, ...(ngDevMode ? [{ debugName: "workspaceConfig" }] : []));
723
- this._workspaceConfig = signal(undefined, ...(ngDevMode ? [{ debugName: "_workspaceConfig" }] : []));
724
- this.#workspaceConfigEffect = effect(() => {
725
- const wsc = this.workspaceConfig();
726
- untracked(() => {
727
- this._workspaceConfig.set(wsc);
728
- this.#updateOriginalWorkspaceConfig();
729
- if (wsc?.currentWorkspace) {
730
- this.setWorkspace(wsc.currentWorkspace, true);
731
- }
732
- });
733
- }, ...(ngDevMode ? [{ debugName: "#workspaceConfigEffect" }] : []));
734
- /**
735
- * Collection of buckets to load available widgets from. Wildcards are also posssible:
736
- * `[buckets]="['app.default', '*.public.*', 'app.no?.widgets']"`
737
- *
738
- * `*` represents any character 0-n times
739
- * `?` represents exactly one character
740
- */
741
- this.buckets = input(undefined, ...(ngDevMode ? [{ debugName: "buckets" }] : []));
742
- this.configChange = output();
743
- this.gridItemEvent = output();
744
- this.editModeChange = output();
745
- this.editMode = signal(false, ...(ngDevMode ? [{ debugName: "editMode" }] : []));
746
- // currently selected workspace
747
- this.workspace = signal(undefined, ...(ngDevMode ? [{ debugName: "workspace" }] : []));
748
- this.#workspaceEffect = effect(() => {
749
- const ws = this.workspace();
750
- this.workspaceLabel.set(ws ? this.getLabel(ws) : '');
751
- untracked(() => {
752
- if (ws)
753
- this.workspaceForm.patchValue({ label: this.workspaceLabel(), id: ws.id });
754
- this.gridItemConfig.set(ws ? JSON.parse(JSON.stringify(ws.grid)) : undefined);
755
- });
756
- }, ...(ngDevMode ? [{ debugName: "#workspaceEffect" }] : []));
757
- this.workspaceLabel = signal('', ...(ngDevMode ? [{ debugName: "workspaceLabel" }] : []));
758
- this.gridItemConfig = signal(undefined, ...(ngDevMode ? [{ debugName: "gridItemConfig" }] : []));
759
- }
760
- #dialog;
761
- #fb;
762
- #confirm;
763
- #DEFAULT_WORKSPACE_OPTIONS;
764
- get workspaceLabelControl() {
765
- return this.workspaceForm.get('label');
766
- }
767
- #workspaceConfigEffect;
768
- // persist the last 'accepted' workspace config to be able to revert changes
769
- #originalWidgetGridWorkspaceConfig;
770
- #workspaceEffect;
771
- getLabel(workspace) {
772
- return workspace.translateLabel ? this.translate.instant(workspace.label) : workspace.label;
773
- }
774
- setWorkspace(id, silent = false) {
775
- const workspace = this._workspaceConfig()?.workspaces.find((w) => w.id === id);
776
- if (workspace) {
777
- this.workspace.set(workspace);
778
- this._workspaceConfig.update((cfg) => ({
779
- ...cfg,
780
- currentWorkspace: id
781
- }));
782
- this.#updateOriginalWorkspaceConfig();
783
- }
784
- else {
785
- this.workspace.set(undefined);
786
- }
787
- if (!silent)
788
- this.emitConfigChange();
789
- }
790
- openWorkspaceDialog(create, tplRef) {
791
- if (create) {
792
- this.workspaceForm.reset();
793
- }
794
- this.workspaceDialogRef = this.#dialog.open(tplRef);
795
- }
796
- saveWorkspace() {
797
- let cfg = this._workspaceConfig();
798
- if (!cfg) {
799
- cfg = {
800
- workspaces: []
801
- };
802
- }
803
- const isNewWorkspace = !this.workspaceForm.value.id;
804
- if (isNewWorkspace) {
805
- const newWorkspace = {
806
- id: WidgetGridUtils.uuid(),
807
- label: this.workspaceForm.value.label,
808
- grid: []
809
- };
810
- this._workspaceConfig.set({
811
- ...cfg,
812
- workspaces: [...cfg.workspaces, newWorkspace],
813
- currentWorkspace: newWorkspace.id
814
- });
815
- this.workspace.set(newWorkspace);
816
- this.workspaceForm.patchValue({ id: newWorkspace.id, label: newWorkspace.label });
817
- }
818
- else {
819
- const existingIndex = cfg.workspaces.findIndex((w) => w.id === this.workspaceForm.value.id);
820
- if (existingIndex === -1) {
821
- const updatedWorkspace = cfg.workspaces[existingIndex];
822
- updatedWorkspace.label = this.workspaceForm.value.label;
823
- const workspaces = cfg.workspaces;
824
- workspaces[existingIndex] = updatedWorkspace;
825
- this._workspaceConfig.set({
826
- ...cfg,
827
- workspaces
828
- });
829
- }
830
- else {
831
- // workspace label may have changed
832
- cfg.workspaces[existingIndex].label = this.workspaceForm.value.label;
833
- }
834
- }
835
- this.workspaceDialogRef?.close();
836
- this.emitConfigChange();
837
- }
838
- #updateOriginalWorkspaceConfig() {
839
- this.#originalWidgetGridWorkspaceConfig = WidgetGridUtils.gridConfigStringify(this.workspaceConfig());
840
- }
841
- onGridEvent(e) {
842
- this.gridItemEvent.emit(e);
843
- }
844
- onGridChange(grid) {
845
- const ws = this.workspace();
846
- if (ws) {
847
- ws.grid = grid;
848
- const wsc = this._workspaceConfig();
849
- const idx = wsc ? wsc.workspaces.findIndex((w) => w.id === ws.id) : -1;
850
- if (idx > -1) {
851
- const wgw = this._workspaceConfig()?.workspaces || [];
852
- wgw[idx] = ws;
853
- this._workspaceConfig.update((curr) => ({
854
- ...curr,
855
- workspaces: wgw
856
- }));
857
- }
858
- }
859
- }
860
- // emit current changes and reset original workspace config internally
861
- persistWorkspaceConfig() {
862
- this.saveWorkspace();
863
- // this.#updateOriginalWorkspaceConfig();
864
- // this.emitConfigChange();
865
- this.editMode.set(false);
866
- }
867
- revertWorkspaceConfig() {
868
- if (this.#originalWidgetGridWorkspaceConfig) {
869
- this._workspaceConfig.set(WidgetGridUtils.gridConfigParse(this.#originalWidgetGridWorkspaceConfig));
870
- }
871
- const cws = this.workspaceConfig()?.currentWorkspace;
872
- if (cws)
873
- this.setWorkspace(cws, true);
874
- this.editMode.set(false);
875
- }
876
- deleteCurrentWorkspace() {
877
- const wsc = this._workspaceConfig();
878
- const ws = this.workspace();
879
- if (ws && wsc) {
880
- const idx = wsc.workspaces.findIndex((w) => w.id === ws.id);
881
- if (idx > -1) {
882
- this.#confirm
883
- .confirm({
884
- message: this.translate.instant('yuv.widget-grid.workspaces.workspace.delete.confirm.message', {
885
- label: ws.label
886
- })
887
- })
888
- .subscribe((confirmed) => {
889
- if (!confirmed)
890
- return;
891
- const workspaces = wsc.workspaces;
892
- workspaces.splice(idx, 1);
893
- // pick another workspace if the current one is deleted
894
- const newCurrentWorkspace = workspaces.length > 0 ? workspaces[0] : undefined;
895
- this._workspaceConfig.set({
896
- ...wsc,
897
- workspaces,
898
- currentWorkspace: newCurrentWorkspace?.id
899
- });
900
- this.workspace.set(newCurrentWorkspace);
901
- this.emitConfigChange();
902
- });
903
- }
904
- }
905
- }
906
- emitConfigChange() {
907
- this.configChange.emit(this._workspaceConfig());
908
- }
909
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: YuvWidgetGridWorkspacesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
910
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.19", type: YuvWidgetGridWorkspacesComponent, isStandalone: true, selector: "yuv-widget-grid-workspaces", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, workspaceConfig: { classPropertyName: "workspaceConfig", publicName: "workspaceConfig", isSignal: true, isRequired: false, transformFunction: null }, buckets: { classPropertyName: "buckets", publicName: "buckets", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { configChange: "configChange", gridItemEvent: "gridItemEvent", editModeChange: "editModeChange" }, ngImport: i0, template: "@let ws = workspace();\n\n<div class=\"toolbar\">\n @if (ws) {\n @let workspaces = _workspaceConfig()?.workspaces || [];\n\n <button\n mat-icon-button\n [matTooltip]=\"'yuv.widget-grid.workspaces.workspace.menu.tooltip' | translate\"\n [disabled]=\"editMode()\"\n [matMenuTriggerFor]=\"workspacePickerMenu\"\n >\n <mat-icon>menu</mat-icon>\n </button>\n\n <mat-menu #workspacePickerMenu=\"matMenu\">\n @for (ws of workspaces; track ws.id) {\n <button mat-menu-item (click)=\"setWorkspace(ws.id)\">{{ getLabel(ws) }}</button>\n }\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"openWorkspaceDialog(true, tplWorkspaceEdit)\">{{ 'yuv.widget-grid.workspaces.workspace.menu.create' | translate }}</button>\n </mat-menu>\n\n @if (!editMode()) {\n <h2 class=\"label\">{{ workspaceLabel() }}</h2>\n @if (!ws.preventEdit) {\n <button mat-icon-button [matMenuTriggerFor]=\"workspaceMenu\"><mat-icon>more_vert</mat-icon></button>\n <mat-menu #workspaceMenu=\"matMenu\">\n <button mat-menu-item (click)=\"editMode.set(!editMode())\">{{ 'yuv.widget-grid.workspaces.workspace.menu.edit' | translate }}</button>\n <button mat-menu-item (click)=\"deleteCurrentWorkspace()\">{{ 'yuv.widget-grid.workspaces.workspace.menu.delete' | translate }}</button>\n </mat-menu>\n }\n } @else {\n @if (ws.preventRename || ws.translateLabel) {\n <h2 class=\"label\">{{ workspaceLabel() }}</h2>\n } @else {\n <input type=\"text\" class=\"label\" [formControl]=\"workspaceLabelControl\" />\n }\n <button ymtButton=\"secondary\" (click)=\"revertWorkspaceConfig()\">\n {{ 'yuv.widget-grid.workspaces.editMode.cancel' | translate }}\n </button>\n <button ymtButton=\"primary\" (click)=\"persistWorkspaceConfig()\">\n {{ 'yuv.widget-grid.workspaces.editMode.save' | translate }}\n </button>\n }\n }\n</div>\n\n@if (ws) {\n <yuv-widget-grid\n [gridConfig]=\"_workspaceOptions().gridConfig\"\n [gridItemConfig]=\"gridItemConfig()\"\n [buckets]=\"buckets()\"\n [editMode]=\"editMode()\"\n (gridChange)=\"onGridChange($event)\"\n (gridItemEvent)=\"onGridEvent($event)\"\n >\n <div class=\"empty\">\n <p>{{ 'yuv.widget-grid.empty' | translate }}</p>\n <button ymtButton=\"primary\" (click)=\"editMode.set(true)\">\n {{ 'yuv.widget-grid.empty.create' | translate }}\n </button>\n </div>\n </yuv-widget-grid>\n} @else {\n <div class=\"empty\">\n <p>{{ 'yuv.widget-grid.workspaces.empty' | translate }}</p>\n <button ymtButton=\"primary\" (click)=\"openWorkspaceDialog(true, tplWorkspaceEdit)\">\n {{ 'yuv.widget-grid.workspaces.empty.button.create' | translate }}\n </button>\n </div>\n}\n\n<ng-template #tplWorkspaceEdit>\n <yuv-workspace-edit [workspaceForm]=\"workspaceForm\" (workspaceSubmit)=\"saveWorkspace()\"></yuv-workspace-edit>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow-y:auto}:host .toolbar{display:flex;flex-direction:row;align-items:center;gap:var(--ymt-spacing-m)}:host .toolbar .label{flex:1;font:var(--ymt-font-headline-medium);letter-spacing:var(--ymt-font-headline-medium-tracking);margin-inline:0;margin-block:.75em;padding-inline:.25em 0;padding-block:.25em}:host .toolbar input.label{border:0;background-color:transparent}:host .toolbar input.label:not([disabled]){outline:1px solid var(--ymt-outline)}:host yuv-widget-grid{flex:1}:host .empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "component", type: YuvWidgetGridComponent, selector: "yuv-widget-grid", inputs: ["gridConfig", "editMode", "gridItemConfig", "buckets"], outputs: ["gridChange", "gridItemEvent", "widgetPickerOpen"] }, { kind: "directive", type: YmtButtonDirective, selector: "button[ymtButton], a[ymtButton]", inputs: ["ymtButton", "disabled", "aria-disabled", "disableRipple", "disabledInteractive", "button-size"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4$1.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: i4$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i2.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: WorkspaceEditComponent, selector: "yuv-workspace-edit", inputs: ["workspaceForm"], outputs: ["workspaceSubmit"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] }); }
911
- }
912
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: YuvWidgetGridWorkspacesComponent, decorators: [{
913
- type: Component,
914
- args: [{ selector: 'yuv-widget-grid-workspaces', imports: [
915
- YuvWidgetGridComponent,
916
- YmtButtonDirective,
917
- ReactiveFormsModule,
918
- MatInputModule,
919
- MatButtonModule,
920
- MatIconModule,
921
- MatFormFieldModule,
922
- MatMenuModule,
923
- MatDividerModule,
924
- MatTooltipModule,
925
- TranslatePipe,
926
- WorkspaceEditComponent
927
- ], template: "@let ws = workspace();\n\n<div class=\"toolbar\">\n @if (ws) {\n @let workspaces = _workspaceConfig()?.workspaces || [];\n\n <button\n mat-icon-button\n [matTooltip]=\"'yuv.widget-grid.workspaces.workspace.menu.tooltip' | translate\"\n [disabled]=\"editMode()\"\n [matMenuTriggerFor]=\"workspacePickerMenu\"\n >\n <mat-icon>menu</mat-icon>\n </button>\n\n <mat-menu #workspacePickerMenu=\"matMenu\">\n @for (ws of workspaces; track ws.id) {\n <button mat-menu-item (click)=\"setWorkspace(ws.id)\">{{ getLabel(ws) }}</button>\n }\n <mat-divider></mat-divider>\n <button mat-menu-item (click)=\"openWorkspaceDialog(true, tplWorkspaceEdit)\">{{ 'yuv.widget-grid.workspaces.workspace.menu.create' | translate }}</button>\n </mat-menu>\n\n @if (!editMode()) {\n <h2 class=\"label\">{{ workspaceLabel() }}</h2>\n @if (!ws.preventEdit) {\n <button mat-icon-button [matMenuTriggerFor]=\"workspaceMenu\"><mat-icon>more_vert</mat-icon></button>\n <mat-menu #workspaceMenu=\"matMenu\">\n <button mat-menu-item (click)=\"editMode.set(!editMode())\">{{ 'yuv.widget-grid.workspaces.workspace.menu.edit' | translate }}</button>\n <button mat-menu-item (click)=\"deleteCurrentWorkspace()\">{{ 'yuv.widget-grid.workspaces.workspace.menu.delete' | translate }}</button>\n </mat-menu>\n }\n } @else {\n @if (ws.preventRename || ws.translateLabel) {\n <h2 class=\"label\">{{ workspaceLabel() }}</h2>\n } @else {\n <input type=\"text\" class=\"label\" [formControl]=\"workspaceLabelControl\" />\n }\n <button ymtButton=\"secondary\" (click)=\"revertWorkspaceConfig()\">\n {{ 'yuv.widget-grid.workspaces.editMode.cancel' | translate }}\n </button>\n <button ymtButton=\"primary\" (click)=\"persistWorkspaceConfig()\">\n {{ 'yuv.widget-grid.workspaces.editMode.save' | translate }}\n </button>\n }\n }\n</div>\n\n@if (ws) {\n <yuv-widget-grid\n [gridConfig]=\"_workspaceOptions().gridConfig\"\n [gridItemConfig]=\"gridItemConfig()\"\n [buckets]=\"buckets()\"\n [editMode]=\"editMode()\"\n (gridChange)=\"onGridChange($event)\"\n (gridItemEvent)=\"onGridEvent($event)\"\n >\n <div class=\"empty\">\n <p>{{ 'yuv.widget-grid.empty' | translate }}</p>\n <button ymtButton=\"primary\" (click)=\"editMode.set(true)\">\n {{ 'yuv.widget-grid.empty.create' | translate }}\n </button>\n </div>\n </yuv-widget-grid>\n} @else {\n <div class=\"empty\">\n <p>{{ 'yuv.widget-grid.workspaces.empty' | translate }}</p>\n <button ymtButton=\"primary\" (click)=\"openWorkspaceDialog(true, tplWorkspaceEdit)\">\n {{ 'yuv.widget-grid.workspaces.empty.button.create' | translate }}\n </button>\n </div>\n}\n\n<ng-template #tplWorkspaceEdit>\n <yuv-workspace-edit [workspaceForm]=\"workspaceForm\" (workspaceSubmit)=\"saveWorkspace()\"></yuv-workspace-edit>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow-y:auto}:host .toolbar{display:flex;flex-direction:row;align-items:center;gap:var(--ymt-spacing-m)}:host .toolbar .label{flex:1;font:var(--ymt-font-headline-medium);letter-spacing:var(--ymt-font-headline-medium-tracking);margin-inline:0;margin-block:.75em;padding-inline:.25em 0;padding-block:.25em}:host .toolbar input.label{border:0;background-color:transparent}:host .toolbar input.label:not([disabled]){outline:1px solid var(--ymt-outline)}:host yuv-widget-grid{flex:1}:host .empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}\n"] }]
928
- }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], workspaceConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "workspaceConfig", required: false }] }], buckets: [{ type: i0.Input, args: [{ isSignal: true, alias: "buckets", required: false }] }], configChange: [{ type: i0.Output, args: ["configChange"] }], gridItemEvent: [{ type: i0.Output, args: ["gridItemEvent"] }], editModeChange: [{ type: i0.Output, args: ["editModeChange"] }] } });
929
-
930
- const cmp = [
931
- YuvWidgetGridComponent,
932
- YuvWidgetGridWorkspacesComponent
933
- ];
934
- class YuvWidgetGridModule {
935
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: YuvWidgetGridModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
936
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.19", ngImport: i0, type: YuvWidgetGridModule, imports: [YuvWidgetGridComponent,
937
- YuvWidgetGridWorkspacesComponent], exports: [YuvWidgetGridComponent,
938
- YuvWidgetGridWorkspacesComponent] }); }
939
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: YuvWidgetGridModule, imports: [cmp] }); }
940
- }
941
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: YuvWidgetGridModule, decorators: [{
942
- type: NgModule,
943
- args: [{
944
- imports: [cmp],
945
- exports: [cmp]
946
- }]
947
- }] });
948
7
 
949
8
  /**
950
9
  * Generated bundle index. Do not edit.
951
10
  */
952
-
953
- export { WidgetGridRegistry, WidgetGridService, YuvWidgetGridComponent, YuvWidgetGridModule, YuvWidgetGridWorkspacesComponent };
954
11
  //# sourceMappingURL=yuuvis-client-framework-widget-grid.mjs.map