@mintplayer/ng-spark 22.23.0 → 22.25.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/README.md +196 -0
- package/fesm2022/mintplayer-ng-spark-attribute-description.mjs +100 -47
- package/fesm2022/mintplayer-ng-spark-attribute-description.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-client-operations.mjs +310 -329
- package/fesm2022/mintplayer-ng-spark-client-operations.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-column-filter.mjs +175 -135
- package/fesm2022/mintplayer-ng-spark-column-filter.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-contributions.mjs +721 -0
- package/fesm2022/mintplayer-ng-spark-contributions.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-grid.mjs +2385 -1118
- package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-history.mjs +598 -0
- package/fesm2022/mintplayer-ng-spark-history.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-icon.mjs +64 -27
- package/fesm2022/mintplayer-ng-spark-icon.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-models.mjs +405 -762
- package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-moderation.mjs +1212 -0
- package/fesm2022/mintplayer-ng-spark-moderation.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-panels.mjs +60 -0
- package/fesm2022/mintplayer-ng-spark-panels.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-pipes.mjs +1158 -765
- package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-create.mjs +273 -169
- package/fesm2022/mintplayer-ng-spark-po-create.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs +795 -410
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-edit.mjs +1196 -280
- package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-form.mjs +2244 -1224
- package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-query-list.mjs +571 -303
- package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-renderers.mjs +44 -55
- package/fesm2022/mintplayer-ng-spark-renderers.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +216 -177
- package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-routes.mjs +24 -28
- package/fesm2022/mintplayer-ng-spark-routes.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-services.mjs +625 -640
- package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-shell.mjs +1031 -397
- package/fesm2022/mintplayer-ng-spark-shell.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-soft-delete.mjs +294 -0
- package/fesm2022/mintplayer-ng-spark-soft-delete.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark.mjs +14 -48
- package/fesm2022/mintplayer-ng-spark.mjs.map +1 -1
- package/package.json +23 -2
- package/types/mintplayer-ng-spark-attribute-description.d.ts +25 -18
- package/types/mintplayer-ng-spark-client-operations.d.ts +139 -160
- package/types/mintplayer-ng-spark-column-filter.d.ts +73 -55
- package/types/mintplayer-ng-spark-contributions.d.ts +231 -0
- package/types/mintplayer-ng-spark-grid.d.ts +917 -448
- package/types/mintplayer-ng-spark-history.d.ts +216 -0
- package/types/mintplayer-ng-spark-icon.d.ts +15 -13
- package/types/mintplayer-ng-spark-models.d.ts +681 -573
- package/types/mintplayer-ng-spark-moderation.d.ts +402 -0
- package/types/mintplayer-ng-spark-panels.d.ts +143 -0
- package/types/mintplayer-ng-spark-pipes.d.ts +131 -149
- package/types/mintplayer-ng-spark-po-create.d.ts +46 -37
- package/types/mintplayer-ng-spark-po-detail.d.ts +180 -117
- package/types/mintplayer-ng-spark-po-edit.d.ts +367 -64
- package/types/mintplayer-ng-spark-po-form.d.ts +558 -373
- package/types/mintplayer-ng-spark-query-list.d.ts +143 -82
- package/types/mintplayer-ng-spark-renderers.d.ts +121 -85
- package/types/mintplayer-ng-spark-retry-action-modal.d.ts +31 -34
- package/types/mintplayer-ng-spark-routes.d.ts +7 -11
- package/types/mintplayer-ng-spark-services.d.ts +377 -261
- package/types/mintplayer-ng-spark-shell.d.ts +228 -132
- package/types/mintplayer-ng-spark-soft-delete.d.ts +90 -0
- package/types/mintplayer-ng-spark.d.ts +19 -12
|
@@ -1,304 +1,572 @@
|
|
|
1
|
-
import * as i0 from
|
|
2
|
-
import {
|
|
3
|
-
import { takeUntilDestroyed } from
|
|
4
|
-
import * as i1 from
|
|
5
|
-
import { CommonModule, NgTemplateOutlet } from
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, computed, effect, inject, input, output, signal, viewChild } from "@angular/core";
|
|
3
|
+
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
|
4
|
+
import * as i1 from "@angular/common";
|
|
5
|
+
import { CommonModule, NgComponentOutlet, NgTemplateOutlet } from "@angular/common";
|
|
6
|
+
import { ActivatedRoute, Router } from "@angular/router";
|
|
7
|
+
import { Color } from "@mintplayer/ng-bootstrap";
|
|
8
|
+
import { BsBadgeComponent } from "@mintplayer/ng-bootstrap/badge";
|
|
9
|
+
import { BsAlertComponent } from "@mintplayer/ng-bootstrap/alert";
|
|
10
|
+
import { BsGridColumnDirective, BsGridComponent, BsGridRowDirective } from "@mintplayer/ng-bootstrap/grid";
|
|
11
|
+
import { BsPriorityNavComponent, BsPriorityNavItemDirective } from "@mintplayer/ng-bootstrap/priority-nav";
|
|
12
|
+
import { BsSpinnerComponent } from "@mintplayer/ng-bootstrap/spinner";
|
|
13
|
+
import { SparkLanguageService, SparkService, SparkStreamingService } from "@mintplayer/ng-spark/services";
|
|
14
|
+
import { ResolveTranslationPipe, TranslateKeyPipe } from "@mintplayer/ng-spark/pipes";
|
|
15
|
+
import { SparkIconComponent } from "@mintplayer/ng-spark/icon";
|
|
16
|
+
import { SparkQueryGridComponent, SparkSearchBoxComponent, sparkActionClass } from "@mintplayer/ng-spark/grid";
|
|
17
|
+
import { SPARK_QUERY_LIST_ACTIONS, orderSparkExtensions, parseSparkDeletedParam } from "@mintplayer/ng-spark/panels";
|
|
18
|
+
var SparkQueryListComponent = class SparkQueryListComponent {
|
|
19
|
+
route = inject(ActivatedRoute);
|
|
20
|
+
router = inject(Router);
|
|
21
|
+
sparkService = inject(SparkService);
|
|
22
|
+
streamingService = inject(SparkStreamingService);
|
|
23
|
+
destroyRef = inject(DestroyRef);
|
|
24
|
+
lang = inject(SparkLanguageService);
|
|
25
|
+
extraActionsTemplate = input(null, ...ngDevMode ? [{ debugName: "extraActionsTemplate" }] : /* istanbul ignore next */ []);
|
|
26
|
+
showCustomActions = input(true, ...ngDevMode ? [{ debugName: "showCustomActions" }] : /* istanbul ignore next */ []);
|
|
27
|
+
rowRoute = input(null, ...ngDevMode ? [{ debugName: "rowRoute" }] : /* istanbul ignore next */ []);
|
|
28
|
+
rowClicked = output();
|
|
29
|
+
createClicked = output();
|
|
30
|
+
customActionExecuted = output();
|
|
31
|
+
colors = Color;
|
|
32
|
+
queryId = signal(null, ...ngDevMode ? [{ debugName: "queryId" }] : /* istanbul ignore next */ []);
|
|
33
|
+
errorMessage = signal(null, ...ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []);
|
|
34
|
+
searchTerm = signal("", ...ngDevMode ? [{ debugName: "searchTerm" }] : /* istanbul ignore next */ []);
|
|
35
|
+
grid = viewChild(SparkQueryGridComponent, ...ngDevMode ? [{ debugName: "grid" }] : /* istanbul ignore next */ []);
|
|
36
|
+
query = computed(() => this.grid()?.query() ?? null, ...ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []);
|
|
37
|
+
entityType = computed(() => this.grid()?.entityType() ?? null, ...ngDevMode ? [{ debugName: "entityType" }] : /* istanbul ignore next */ []);
|
|
38
|
+
customActions = computed(() => this.grid()?.customActions() ?? [], ...ngDevMode ? [{ debugName: "customActions" }] : /* istanbul ignore next */ []);
|
|
39
|
+
canCreate = computed(() => this.grid()?.offersCreate() ?? false, ...ngDevMode ? [{ debugName: "canCreate" }] : /* istanbul ignore next */ []);
|
|
40
|
+
resultCount = computed(() => this.grid()?.resultCount() ?? null, ...ngDevMode ? [{ debugName: "resultCount" }] : /* istanbul ignore next */ []);
|
|
41
|
+
isVirtualScrolling = computed(() => this.grid()?.isVirtualScrolling() ?? false, ...ngDevMode ? [{ debugName: "isVirtualScrolling" }] : /* istanbul ignore next */ []);
|
|
42
|
+
gridError = computed(() => this.grid()?.errorMessage() ?? null, ...ngDevMode ? [{ debugName: "gridError" }] : /* istanbul ignore next */ []);
|
|
43
|
+
permissions = computed(() => this.grid()?.permissions() ?? null, ...ngDevMode ? [{ debugName: "permissions" }] : /* istanbul ignore next */ []);
|
|
44
|
+
listActions = orderSparkExtensions(inject(SPARK_QUERY_LIST_ACTIONS, { optional: true }), (a) => a.priority ?? 60);
|
|
45
|
+
deletedMode = signal("exclude", ...ngDevMode ? [{ debugName: "deletedMode" }] : /* istanbul ignore next */ []);
|
|
46
|
+
reloadToken = signal(0, ...ngDevMode ? [{ debugName: "reloadToken" }] : /* istanbul ignore next */ []);
|
|
47
|
+
listContext = computed(() => {
|
|
48
|
+
const query = this.query();
|
|
49
|
+
if (!query) return null;
|
|
50
|
+
return {
|
|
51
|
+
query,
|
|
52
|
+
entityType: this.entityType(),
|
|
53
|
+
permissions: this.permissions(),
|
|
54
|
+
deleted: this.deletedMode(),
|
|
55
|
+
setDeleted: (mode) => this.setDeleted(mode),
|
|
56
|
+
reload: () => this.reloadToken.update((n) => n + 1)
|
|
57
|
+
};
|
|
58
|
+
}, ...ngDevMode ? [{ debugName: "listContext" }] : /* istanbul ignore next */ []);
|
|
59
|
+
gridReloadToken = this.reloadToken.asReadonly();
|
|
60
|
+
setDeleted(mode) {
|
|
61
|
+
this.router.navigate([], {
|
|
62
|
+
relativeTo: this.route,
|
|
63
|
+
queryParams: { deleted: mode === "exclude" ? null : mode },
|
|
64
|
+
queryParamsHandling: "merge",
|
|
65
|
+
replaceUrl: true
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
customActionClass(action) {
|
|
69
|
+
const variant = action.variant?.toLowerCase();
|
|
70
|
+
switch (variant) {
|
|
71
|
+
case "danger":
|
|
72
|
+
case "warning":
|
|
73
|
+
case "primary":
|
|
74
|
+
case "secondary":
|
|
75
|
+
case "success": return `btn btn-${variant}`;
|
|
76
|
+
default: return "btn btn-outline-primary";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
toolbarActions = computed(() => this.grid()?.toolbarActions() ?? [], ...ngDevMode ? [{ debugName: "toolbarActions" }] : /* istanbul ignore next */ []);
|
|
80
|
+
toolbarActionClass(action) {
|
|
81
|
+
return action.kind === "new" ? "btn btn-primary" : sparkActionClass(action.definition);
|
|
82
|
+
}
|
|
83
|
+
isToolbarActionEnabled(action) {
|
|
84
|
+
return this.grid()?.isToolbarActionEnabled(action) ?? false;
|
|
85
|
+
}
|
|
86
|
+
runToolbarAction(action) {
|
|
87
|
+
if (action.kind === "new") {
|
|
88
|
+
this.onCreate();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this.grid()?.runToolbarAction(action);
|
|
92
|
+
}
|
|
93
|
+
isActionEnabled(action) {
|
|
94
|
+
return this.grid()?.isActionEnabled(action) ?? false;
|
|
95
|
+
}
|
|
96
|
+
isStreaming = signal(false, ...ngDevMode ? [{ debugName: "isStreaming" }] : /* istanbul ignore next */ []);
|
|
97
|
+
streamingSub = null;
|
|
98
|
+
streamColumns = signal([], ...ngDevMode ? [{ debugName: "streamColumns" }] : /* istanbul ignore next */ []);
|
|
99
|
+
allItems = signal([], ...ngDevMode ? [{ debugName: "allItems" }] : /* istanbul ignore next */ []);
|
|
100
|
+
streamItems = signal([], ...ngDevMode ? [{ debugName: "streamItems" }] : /* istanbul ignore next */ []);
|
|
101
|
+
gridData = computed(() => this.query()?.isStreamingQuery ? this.streamItems() : null, ...ngDevMode ? [{ debugName: "gridData" }] : /* istanbul ignore next */ []);
|
|
102
|
+
constructor() {
|
|
103
|
+
this.route.paramMap.pipe(takeUntilDestroyed()).subscribe((params) => {
|
|
104
|
+
this.onParamsChange(params).catch((e) => this.reportLoadFailure(e));
|
|
105
|
+
});
|
|
106
|
+
this.route.queryParamMap.pipe(takeUntilDestroyed()).subscribe((query) => {
|
|
107
|
+
this.deletedMode.set(parseSparkDeletedParam(query.get("deleted")) ?? "exclude");
|
|
108
|
+
this.applyUrlScope(query);
|
|
109
|
+
});
|
|
110
|
+
this.destroyRef.onDestroy(() => this.disconnectStreaming());
|
|
111
|
+
effect(() => {
|
|
112
|
+
const q = this.query();
|
|
113
|
+
if (q?.isStreamingQuery) this.connectStreaming(q.id);
|
|
114
|
+
else this.disconnectStreaming();
|
|
115
|
+
});
|
|
116
|
+
effect(() => {
|
|
117
|
+
this.searchTerm();
|
|
118
|
+
this.grid()?.settings();
|
|
119
|
+
this.allItems();
|
|
120
|
+
if (this.isStreaming()) this.applyFilter();
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
urlParentId = signal("", ...ngDevMode ? [{ debugName: "urlParentId" }] : /* istanbul ignore next */ []);
|
|
124
|
+
urlParentType = signal("", ...ngDevMode ? [{ debugName: "urlParentType" }] : /* istanbul ignore next */ []);
|
|
125
|
+
urlFilters = signal([], ...ngDevMode ? [{ debugName: "urlFilters" }] : /* istanbul ignore next */ []);
|
|
126
|
+
activeUrlFilters = computed(() => this.grid()?.appliedPresetFilters() ?? [], ...ngDevMode ? [{ debugName: "activeUrlFilters" }] : /* istanbul ignore next */ []);
|
|
127
|
+
static reservedParams = /* @__PURE__ */ new Set([
|
|
128
|
+
"deleted",
|
|
129
|
+
"parentId",
|
|
130
|
+
"parentType",
|
|
131
|
+
"queryId",
|
|
132
|
+
"parentDeleted"
|
|
133
|
+
]);
|
|
134
|
+
applyUrlScope(query) {
|
|
135
|
+
const parentId = query.get("parentId") ?? "";
|
|
136
|
+
const parentType = query.get("parentType") ?? "";
|
|
137
|
+
const both = !!parentId && !!parentType;
|
|
138
|
+
if (this.urlParentId() !== (both ? parentId : "")) this.urlParentId.set(both ? parentId : "");
|
|
139
|
+
if (this.urlParentType() !== (both ? parentType : "")) this.urlParentType.set(both ? parentType : "");
|
|
140
|
+
const filters = query.keys.filter((key) => !SparkQueryListComponent.reservedParams.has(key)).map((key) => ({
|
|
141
|
+
name: key,
|
|
142
|
+
includes: query.getAll(key).filter((v) => v !== "")
|
|
143
|
+
})).filter((f) => f.includes.length > 0);
|
|
144
|
+
if (JSON.stringify(filters) !== JSON.stringify(this.urlFilters())) this.urlFilters.set(filters);
|
|
145
|
+
}
|
|
146
|
+
clearUrlFilter(name) {
|
|
147
|
+
this.router.navigate([], {
|
|
148
|
+
relativeTo: this.route,
|
|
149
|
+
queryParams: { [name]: null },
|
|
150
|
+
queryParamsHandling: "merge",
|
|
151
|
+
replaceUrl: true
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
clearUrlScope() {
|
|
155
|
+
const queryParams = {
|
|
156
|
+
parentId: null,
|
|
157
|
+
parentType: null
|
|
158
|
+
};
|
|
159
|
+
for (const filter of this.urlFilters()) queryParams[filter.name] = null;
|
|
160
|
+
this.router.navigate([], {
|
|
161
|
+
relativeTo: this.route,
|
|
162
|
+
queryParams,
|
|
163
|
+
queryParamsHandling: "merge",
|
|
164
|
+
replaceUrl: true
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
filterValues(filter) {
|
|
168
|
+
return (filter.includes ?? []).map((v) => String(v)).join(", ");
|
|
169
|
+
}
|
|
170
|
+
filterLabel(name) {
|
|
171
|
+
const attribute = this.entityType()?.attributes?.find((a) => a.name === name);
|
|
172
|
+
return this.lang.resolve(attribute?.label) || name;
|
|
173
|
+
}
|
|
174
|
+
async onParamsChange(params) {
|
|
175
|
+
this.errorMessage.set(null);
|
|
176
|
+
this.queryId.set(null);
|
|
177
|
+
this.allItems.set([]);
|
|
178
|
+
this.streamItems.set([]);
|
|
179
|
+
this.streamColumns.set([]);
|
|
180
|
+
this.disconnectStreaming();
|
|
181
|
+
const queryId = params.get("queryId");
|
|
182
|
+
const typeParam = params.get("type");
|
|
183
|
+
if (queryId) {
|
|
184
|
+
this.queryId.set(queryId);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (!typeParam) return;
|
|
188
|
+
const [entityTypes, queries] = await Promise.all([this.sparkService.getEntityTypes(), this.sparkService.getQueries()]);
|
|
189
|
+
const entityType = entityTypes.find((t) => t.id === typeParam || t.alias === typeParam);
|
|
190
|
+
if (!entityType) {
|
|
191
|
+
this.reportLoadFailure({ status: 404 });
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const singularName = entityType.name;
|
|
195
|
+
const match = queries.find((q) => {
|
|
196
|
+
if (q.entityType === singularName) return true;
|
|
197
|
+
const sourceName = q.source.includes(".") ? q.source.substring(q.source.indexOf(".") + 1) : q.source;
|
|
198
|
+
return sourceName === singularName || sourceName === singularName + "s";
|
|
199
|
+
});
|
|
200
|
+
if (match) this.queryId.set(match.alias || match.id);
|
|
201
|
+
else this.reportLoadFailure({ status: 404 });
|
|
202
|
+
}
|
|
203
|
+
reportLoadFailure(err) {
|
|
204
|
+
this.errorMessage.set(err?.status === 404 ? this.lang.t("spark.query.unavailable") || "This list is not available." : err?.error?.error || err?.message || "An unexpected error occurred");
|
|
205
|
+
}
|
|
206
|
+
async onCustomAction(action) {
|
|
207
|
+
await this.grid()?.onCustomAction(action);
|
|
208
|
+
}
|
|
209
|
+
onCreate() {
|
|
210
|
+
this.createClicked.emit();
|
|
211
|
+
const et = this.entityType();
|
|
212
|
+
if (et) this.router.navigate([
|
|
213
|
+
"/po",
|
|
214
|
+
et.alias || et.id,
|
|
215
|
+
"new"
|
|
216
|
+
]);
|
|
217
|
+
}
|
|
218
|
+
clearSearch() {
|
|
219
|
+
this.searchTerm.set("");
|
|
220
|
+
}
|
|
221
|
+
connectStreaming(queryId) {
|
|
222
|
+
if (this.streamingSub) return;
|
|
223
|
+
this.isStreaming.set(true);
|
|
224
|
+
this.streamingSub = this.streamingService.connectToStreamingQuery(queryId).subscribe({
|
|
225
|
+
next: (message) => this.handleStreamingMessage(message),
|
|
226
|
+
error: (err) => {
|
|
227
|
+
this.errorMessage.set(err?.message || "Streaming connection failed");
|
|
228
|
+
this.isStreaming.set(false);
|
|
229
|
+
},
|
|
230
|
+
complete: () => this.isStreaming.set(false)
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
disconnectStreaming() {
|
|
234
|
+
if (this.streamingSub) {
|
|
235
|
+
this.streamingSub.unsubscribe();
|
|
236
|
+
this.streamingSub = null;
|
|
237
|
+
}
|
|
238
|
+
this.isStreaming.set(false);
|
|
239
|
+
}
|
|
240
|
+
handleStreamingMessage(message) {
|
|
241
|
+
switch (message.type) {
|
|
242
|
+
case "snapshot":
|
|
243
|
+
this.errorMessage.set(null);
|
|
244
|
+
this.streamColumns.set(message.columns);
|
|
245
|
+
this.allItems.set(message.data);
|
|
246
|
+
break;
|
|
247
|
+
case "patch":
|
|
248
|
+
if (message.updated.length > 0) this.allItems.update((items) => items.map((item) => {
|
|
249
|
+
const patch = message.updated.find((u) => u.id === item.id);
|
|
250
|
+
if (!patch) return item;
|
|
251
|
+
return {
|
|
252
|
+
...item,
|
|
253
|
+
values: item.values.map((v) => v.key in patch.values ? {
|
|
254
|
+
...v,
|
|
255
|
+
value: patch.values[v.key]
|
|
256
|
+
} : v)
|
|
257
|
+
};
|
|
258
|
+
}));
|
|
259
|
+
break;
|
|
260
|
+
case "error": this.errorMessage.set(message.message);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
applyFilter() {
|
|
264
|
+
let items = this.allItems();
|
|
265
|
+
const term = this.searchTerm().toLowerCase();
|
|
266
|
+
if (term) items = items.filter((item) => item.values.some((v) => String(v.value ?? "").toLowerCase().includes(term)));
|
|
267
|
+
const sortCols = this.grid()?.settings().sortColumns ?? [];
|
|
268
|
+
if (sortCols.length > 0) items = [...items].sort((a, b) => {
|
|
269
|
+
for (const col of sortCols) {
|
|
270
|
+
const aVal = a.values.find((v) => v.key === col.property)?.value ?? "";
|
|
271
|
+
const bVal = b.values.find((v) => v.key === col.property)?.value ?? "";
|
|
272
|
+
const cmp = String(aVal).localeCompare(String(bVal));
|
|
273
|
+
if (cmp !== 0) return col.direction === "descending" ? -cmp : cmp;
|
|
274
|
+
}
|
|
275
|
+
return 0;
|
|
276
|
+
});
|
|
277
|
+
this.streamItems.set(items);
|
|
278
|
+
}
|
|
279
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
280
|
+
minVersion: "12.0.0",
|
|
281
|
+
version: "22.2.0",
|
|
282
|
+
ngImport: i0,
|
|
283
|
+
type: SparkQueryListComponent,
|
|
284
|
+
deps: [],
|
|
285
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
286
|
+
});
|
|
287
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
288
|
+
minVersion: "17.0.0",
|
|
289
|
+
version: "22.2.0",
|
|
290
|
+
type: SparkQueryListComponent,
|
|
291
|
+
isStandalone: true,
|
|
292
|
+
selector: "spark-query-list",
|
|
293
|
+
inputs: {
|
|
294
|
+
extraActionsTemplate: {
|
|
295
|
+
classPropertyName: "extraActionsTemplate",
|
|
296
|
+
publicName: "extraActionsTemplate",
|
|
297
|
+
isSignal: true,
|
|
298
|
+
isRequired: false,
|
|
299
|
+
transformFunction: null
|
|
300
|
+
},
|
|
301
|
+
showCustomActions: {
|
|
302
|
+
classPropertyName: "showCustomActions",
|
|
303
|
+
publicName: "showCustomActions",
|
|
304
|
+
isSignal: true,
|
|
305
|
+
isRequired: false,
|
|
306
|
+
transformFunction: null
|
|
307
|
+
},
|
|
308
|
+
rowRoute: {
|
|
309
|
+
classPropertyName: "rowRoute",
|
|
310
|
+
publicName: "rowRoute",
|
|
311
|
+
isSignal: true,
|
|
312
|
+
isRequired: false,
|
|
313
|
+
transformFunction: null
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
outputs: {
|
|
317
|
+
rowClicked: "rowClicked",
|
|
318
|
+
createClicked: "createClicked",
|
|
319
|
+
customActionExecuted: "customActionExecuted"
|
|
320
|
+
},
|
|
321
|
+
host: { properties: { "class.virtual-scrolling": "isVirtualScrolling()" } },
|
|
322
|
+
viewQueries: [{
|
|
323
|
+
propertyName: "grid",
|
|
324
|
+
first: true,
|
|
325
|
+
predicate: SparkQueryGridComponent,
|
|
326
|
+
descendants: true,
|
|
327
|
+
isSignal: true
|
|
328
|
+
}],
|
|
329
|
+
ngImport: i0,
|
|
330
|
+
template: "<div class=\"d-flex flex-column h-100\">\n <div class=\"spark-actionbar py-2 flex-shrink-0\" [class.spark-actionbar-wide]=\"isVirtualScrolling()\">\n <bs-priority-nav [moreLabel]=\"lang.t('common.more')\" [collapseAt]=\"'sm'\">\n <!-- The grid's toolbar model (#460, M15): New, Delete and the custom actions — the list the\n sub-query card renders too. Disabled, not hidden: hiding makes the affordance\n undiscoverable and reflows the priority nav on every selection change. The server\n enforces the same rules. -->\n @for (action of toolbarActions(); track action.name) {\n @if (action.kind !== 'custom' || showCustomActions()) {\n <button *bsPriorityNavItem=\"action.priority\" type=\"button\" [class]=\"toolbarActionClass(action)\"\n [attr.data-action]=\"action.name\"\n [disabled]=\"!isToolbarActionEnabled(action)\" (click)=\"runToolbarAction(action)\">\n @if (action.kind === 'new') {\n <spark-icon name=\"plus-lg\" /> {{ 'common.new' | t }}\n } @else {\n @if (action.definition.icon && action.kind === 'delete') {\n <spark-icon [name]=\"action.definition.icon\" />\n }\n {{ action.definition.displayName | resolveTranslation }}\n }\n </button>\n }\n }\n @if (extraActionsTemplate(); as extraActionsTpl) {\n <ng-container *bsPriorityNavItem=\"50\">\n <ng-container *ngTemplateOutlet=\"extraActionsTpl\"></ng-container>\n </ng-container>\n }\n <!-- Add-on actions (SPARK_QUERY_LIST_ACTIONS), e.g. the soft-delete Deleted toggle. -->\n @if (listContext(); as ctx) {\n @for (action of listActions; track action.id) {\n <ng-container *bsPriorityNavItem=\"action.priority ?? 60\">\n <ng-container *ngComponentOutlet=\"action.component; inputs: { context: ctx }\" />\n </ng-container>\n }\n }\n </bs-priority-nav>\n </div>\n\n <h2 class=\"mb-4 flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\">\n {{ (query()?.description | resolveTranslation) || query()?.name || ('common.loading' | t) }}\n @if (isStreaming()) {\n <bs-badge [type]=\"colors.success\" class=\"ms-2 align-middle spark-live-badge\">LIVE</bs-badge>\n }\n @if (deletedMode() === 'only') {\n <bs-badge [type]=\"colors.secondary\" class=\"ms-2 align-middle spark-deleted-badge\">{{ 'softDelete.deleted' | t }}</bs-badge>\n }\n </h2>\n\n @if (errorMessage(); as err) {\n <!-- The route could not be resolved to a query at all. A failure INSIDE the grid renders in\n the grid; this is the one it cannot report, because it never got a query id. -->\n <bs-alert [type]=\"colors.danger\" class=\"m-3 d-block\">\n {{ err }}\n </bs-alert>\n } @else if (queryId(); as qId) {\n <div class=\"flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\">\n <bs-grid>\n <div bsRow class=\"mb-3\">\n <div [md]=\"12\">\n <!-- The same box as the sub-query card's header (#460 M15): debounce, clear button. -->\n <spark-search-box [(term)]=\"searchTerm\" />\n </div>\n <!-- Its own full-width row rather than a column beside the box: the count is\n occasional, and reserving 8 columns for it shrank the search permanently. The\n @if moved out of the column so nothing reserves vertical space when absent. -->\n @if (searchTerm() && resultCount() !== null) {\n <div [md]=\"12\" class=\"text-end mt-1\">\n <span class=\"text-muted\">\n {{ resultCount() }} {{ resultCount() === 1 ? ('common.resultFound' | t) : ('common.resultsFound' | t) }}\n </span>\n </div>\n }\n </div>\n </bs-grid>\n </div>\n\n <!--\n One grid, both transports. `data` is null for a normal query, so the grid fetches and pages\n server-side; for a streaming query this page owns the socket and hands the filtered snapshot\n in. This used to be two near-identical <bs-datatable> blocks with a shared row template.\n -->\n <!-- The URL's scope (#contributions M5b): a parent and column filters from the query string, as\n the History link sends them. Shown so the narrowing is visible, and clearable. -->\n @if (urlParentId() || activeUrlFilters().length) {\n <div class=\"spark-url-filters d-flex flex-wrap align-items-center gap-2 mb-2 flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\">\n <span class=\"text-muted small\">{{ 'common.filteredBy' | t }}</span>\n @for (filter of activeUrlFilters(); track filter.name) {\n <bs-badge [type]=\"colors.secondary\" class=\"spark-url-filter\" [attr.data-filter]=\"filter.name\">\n {{ filterLabel(filter.name) }}: {{ filterValues(filter) }}\n <button type=\"button\" class=\"spark-url-filter-clear\" [attr.aria-label]=\"'common.clearFilter' | t\"\n (click)=\"clearUrlFilter(filter.name)\">\n <spark-icon name=\"x-circle\" />\n </button>\n </bs-badge>\n }\n <button type=\"button\" class=\"btn btn-sm btn-link spark-url-filters-clear\" (click)=\"clearUrlScope()\">\n {{ 'common.clearFilters' | t }}\n </button>\n </div>\n }\n\n <spark-query-grid class=\"flex-grow-1\"\n [queryId]=\"qId\"\n [parentId]=\"urlParentId()\"\n [parentType]=\"urlParentType()\"\n [presetFilters]=\"urlFilters()\"\n [data]=\"gridData()\"\n [columns]=\"gridData() ? streamColumns() : null\"\n [search]=\"searchTerm()\"\n [deleted]=\"deletedMode()\"\n [reloadToken]=\"gridReloadToken()\"\n [rowRoute]=\"rowRoute()\"\n (rowClicked)=\"rowClicked.emit($event)\"\n (customActionExecuted)=\"customActionExecuted.emit($event)\" />\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n",
|
|
331
|
+
styles: [".spark-actionbar{--_bleed-block: var(--spark-content-inset-block, 0px);--_bleed-inline: var(--spark-content-inset-inline, 0px);--_gutter: var(--spark-actionbar-gutter, 1rem);position:sticky;top:calc(-1 * var(--_bleed-block));z-index:400;background-color:var(--spark-shell-main-bg, var(--bs-body-bg));border-bottom:1px solid var(--bs-border-color);margin-bottom:1rem;margin-inline:calc(-1 * var(--_bleed-inline));padding-inline:calc(var(--_bleed-inline) + var(--_gutter))}.spark-actionbar .btn{border-radius:0}.spark-actionbar-wide{--spark-actionbar-gutter: 1.5rem}:host{display:flex;flex-direction:column;flex:1;min-height:0}:host.virtual-scrolling{margin:0 calc(-1 * var(--spark-main-padding, 1.5rem)) calc(-1 * var(--spark-main-padding, 1.5rem));--spark-content-inset-inline: 0px}:host.virtual-scrolling spark-query-grid{display:flex;flex-direction:column;min-height:0}:host.virtual-scrolling ::ng-deep bs-datatable{display:flex;flex-direction:column;min-height:0;--mp-datatable-virtual-max-height: 100%}:host.virtual-scrolling ::ng-deep bs-datatable mp-datatable{flex:1 1 auto;min-height:0}tr:hover{background-color:rgba(var(--bs-emphasis-color-rgb),.05)}td input[type=checkbox]:disabled{opacity:1;pointer-events:none}.spark-live-badge{font-size:.6em}.spark-url-filter-clear{background:none;border:0;padding:0 0 0 .25rem;color:inherit;line-height:1}\n"],
|
|
332
|
+
dependencies: [
|
|
333
|
+
{
|
|
334
|
+
kind: "component",
|
|
335
|
+
type: BsBadgeComponent,
|
|
336
|
+
selector: "bs-badge",
|
|
337
|
+
inputs: [
|
|
338
|
+
"type",
|
|
339
|
+
"unit",
|
|
340
|
+
"decorative"
|
|
341
|
+
]
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
kind: "ngmodule",
|
|
345
|
+
type: CommonModule
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
kind: "directive",
|
|
349
|
+
type: i1.NgComponentOutlet,
|
|
350
|
+
selector: "[ngComponentOutlet]",
|
|
351
|
+
inputs: [
|
|
352
|
+
"ngComponentOutlet",
|
|
353
|
+
"ngComponentOutletInputs",
|
|
354
|
+
"ngComponentOutletInjector",
|
|
355
|
+
"ngComponentOutletEnvironmentInjector",
|
|
356
|
+
"ngComponentOutletContent",
|
|
357
|
+
"ngComponentOutletNgModule"
|
|
358
|
+
],
|
|
359
|
+
exportAs: ["ngComponentOutlet"]
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
kind: "directive",
|
|
363
|
+
type: i1.NgTemplateOutlet,
|
|
364
|
+
selector: "[ngTemplateOutlet]",
|
|
365
|
+
inputs: [
|
|
366
|
+
"ngTemplateOutletContext",
|
|
367
|
+
"ngTemplateOutlet",
|
|
368
|
+
"ngTemplateOutletInjector"
|
|
369
|
+
]
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
kind: "component",
|
|
373
|
+
type: BsAlertComponent,
|
|
374
|
+
selector: "bs-alert",
|
|
375
|
+
inputs: [
|
|
376
|
+
"type",
|
|
377
|
+
"announce",
|
|
378
|
+
"isVisible"
|
|
379
|
+
],
|
|
380
|
+
outputs: ["isVisibleChange", "afterOpenedOrClosed"]
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
kind: "component",
|
|
384
|
+
type: BsGridComponent,
|
|
385
|
+
selector: "bs-grid",
|
|
386
|
+
inputs: ["stopFullWidthAt"]
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
kind: "directive",
|
|
390
|
+
type: BsGridRowDirective,
|
|
391
|
+
selector: "[bsRow]"
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
kind: "directive",
|
|
395
|
+
type: BsGridColumnDirective,
|
|
396
|
+
selector: "[xxs],[xs],[sm],[md],[lg],[xl],[xxl]",
|
|
397
|
+
inputs: [
|
|
398
|
+
"xxs",
|
|
399
|
+
"xs",
|
|
400
|
+
"sm",
|
|
401
|
+
"md",
|
|
402
|
+
"lg",
|
|
403
|
+
"xl",
|
|
404
|
+
"xxl"
|
|
405
|
+
]
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
kind: "component",
|
|
409
|
+
type: BsPriorityNavComponent,
|
|
410
|
+
selector: "bs-priority-nav",
|
|
411
|
+
inputs: [
|
|
412
|
+
"moreLabel",
|
|
413
|
+
"moreLabelTemplate",
|
|
414
|
+
"collapseAt",
|
|
415
|
+
"overflowFrom",
|
|
416
|
+
"hideEmptyMore",
|
|
417
|
+
"ariaLabel"
|
|
418
|
+
],
|
|
419
|
+
outputs: ["overflowChange"]
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
kind: "directive",
|
|
423
|
+
type: BsPriorityNavItemDirective,
|
|
424
|
+
selector: "[bsPriorityNavItem]",
|
|
425
|
+
inputs: ["bsPriorityNavItem", "bsPriorityNavItemHideBelow"]
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
kind: "component",
|
|
429
|
+
type: BsSpinnerComponent,
|
|
430
|
+
selector: "bs-spinner",
|
|
431
|
+
inputs: ["type", "color"]
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
kind: "component",
|
|
435
|
+
type: SparkIconComponent,
|
|
436
|
+
selector: "spark-icon",
|
|
437
|
+
inputs: ["name"]
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
kind: "component",
|
|
441
|
+
type: SparkQueryGridComponent,
|
|
442
|
+
selector: "spark-query-grid",
|
|
443
|
+
inputs: [
|
|
444
|
+
"queryId",
|
|
445
|
+
"parentId",
|
|
446
|
+
"parentType",
|
|
447
|
+
"presetFilters",
|
|
448
|
+
"data",
|
|
449
|
+
"search",
|
|
450
|
+
"columns",
|
|
451
|
+
"reloadToken",
|
|
452
|
+
"deleted",
|
|
453
|
+
"parentDeleted",
|
|
454
|
+
"settings",
|
|
455
|
+
"selection",
|
|
456
|
+
"rowRoute",
|
|
457
|
+
"selectionModeSetting"
|
|
458
|
+
],
|
|
459
|
+
outputs: [
|
|
460
|
+
"settingsChange",
|
|
461
|
+
"selectionChange",
|
|
462
|
+
"error",
|
|
463
|
+
"rowClicked",
|
|
464
|
+
"customActionExecuted",
|
|
465
|
+
"createClicked"
|
|
466
|
+
]
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
kind: "component",
|
|
470
|
+
type: SparkSearchBoxComponent,
|
|
471
|
+
selector: "spark-search-box",
|
|
472
|
+
inputs: [
|
|
473
|
+
"term",
|
|
474
|
+
"size",
|
|
475
|
+
"debounce"
|
|
476
|
+
],
|
|
477
|
+
outputs: ["termChange"]
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
kind: "pipe",
|
|
481
|
+
type: ResolveTranslationPipe,
|
|
482
|
+
name: "resolveTranslation"
|
|
483
|
+
},
|
|
484
|
+
{
|
|
485
|
+
kind: "pipe",
|
|
486
|
+
type: TranslateKeyPipe,
|
|
487
|
+
name: "t"
|
|
488
|
+
}
|
|
489
|
+
],
|
|
490
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
491
|
+
});
|
|
492
|
+
};
|
|
493
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
494
|
+
minVersion: "12.0.0",
|
|
495
|
+
version: "22.2.0",
|
|
496
|
+
ngImport: i0,
|
|
497
|
+
type: SparkQueryListComponent,
|
|
498
|
+
decorators: [{
|
|
499
|
+
type: Component,
|
|
500
|
+
args: [{
|
|
501
|
+
selector: "spark-query-list",
|
|
502
|
+
imports: [
|
|
503
|
+
BsBadgeComponent,
|
|
504
|
+
CommonModule,
|
|
505
|
+
NgTemplateOutlet,
|
|
506
|
+
NgComponentOutlet,
|
|
507
|
+
BsAlertComponent,
|
|
508
|
+
BsGridComponent,
|
|
509
|
+
BsGridRowDirective,
|
|
510
|
+
BsGridColumnDirective,
|
|
511
|
+
BsPriorityNavComponent,
|
|
512
|
+
BsPriorityNavItemDirective,
|
|
513
|
+
BsSpinnerComponent,
|
|
514
|
+
SparkIconComponent,
|
|
515
|
+
SparkQueryGridComponent,
|
|
516
|
+
SparkSearchBoxComponent,
|
|
517
|
+
ResolveTranslationPipe,
|
|
518
|
+
TranslateKeyPipe
|
|
519
|
+
],
|
|
520
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
521
|
+
host: { "[class.virtual-scrolling]": "isVirtualScrolling()" },
|
|
522
|
+
template: "<div class=\"d-flex flex-column h-100\">\n <div class=\"spark-actionbar py-2 flex-shrink-0\" [class.spark-actionbar-wide]=\"isVirtualScrolling()\">\n <bs-priority-nav [moreLabel]=\"lang.t('common.more')\" [collapseAt]=\"'sm'\">\n <!-- The grid's toolbar model (#460, M15): New, Delete and the custom actions — the list the\n sub-query card renders too. Disabled, not hidden: hiding makes the affordance\n undiscoverable and reflows the priority nav on every selection change. The server\n enforces the same rules. -->\n @for (action of toolbarActions(); track action.name) {\n @if (action.kind !== 'custom' || showCustomActions()) {\n <button *bsPriorityNavItem=\"action.priority\" type=\"button\" [class]=\"toolbarActionClass(action)\"\n [attr.data-action]=\"action.name\"\n [disabled]=\"!isToolbarActionEnabled(action)\" (click)=\"runToolbarAction(action)\">\n @if (action.kind === 'new') {\n <spark-icon name=\"plus-lg\" /> {{ 'common.new' | t }}\n } @else {\n @if (action.definition.icon && action.kind === 'delete') {\n <spark-icon [name]=\"action.definition.icon\" />\n }\n {{ action.definition.displayName | resolveTranslation }}\n }\n </button>\n }\n }\n @if (extraActionsTemplate(); as extraActionsTpl) {\n <ng-container *bsPriorityNavItem=\"50\">\n <ng-container *ngTemplateOutlet=\"extraActionsTpl\"></ng-container>\n </ng-container>\n }\n <!-- Add-on actions (SPARK_QUERY_LIST_ACTIONS), e.g. the soft-delete Deleted toggle. -->\n @if (listContext(); as ctx) {\n @for (action of listActions; track action.id) {\n <ng-container *bsPriorityNavItem=\"action.priority ?? 60\">\n <ng-container *ngComponentOutlet=\"action.component; inputs: { context: ctx }\" />\n </ng-container>\n }\n }\n </bs-priority-nav>\n </div>\n\n <h2 class=\"mb-4 flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\">\n {{ (query()?.description | resolveTranslation) || query()?.name || ('common.loading' | t) }}\n @if (isStreaming()) {\n <bs-badge [type]=\"colors.success\" class=\"ms-2 align-middle spark-live-badge\">LIVE</bs-badge>\n }\n @if (deletedMode() === 'only') {\n <bs-badge [type]=\"colors.secondary\" class=\"ms-2 align-middle spark-deleted-badge\">{{ 'softDelete.deleted' | t }}</bs-badge>\n }\n </h2>\n\n @if (errorMessage(); as err) {\n <!-- The route could not be resolved to a query at all. A failure INSIDE the grid renders in\n the grid; this is the one it cannot report, because it never got a query id. -->\n <bs-alert [type]=\"colors.danger\" class=\"m-3 d-block\">\n {{ err }}\n </bs-alert>\n } @else if (queryId(); as qId) {\n <div class=\"flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\">\n <bs-grid>\n <div bsRow class=\"mb-3\">\n <div [md]=\"12\">\n <!-- The same box as the sub-query card's header (#460 M15): debounce, clear button. -->\n <spark-search-box [(term)]=\"searchTerm\" />\n </div>\n <!-- Its own full-width row rather than a column beside the box: the count is\n occasional, and reserving 8 columns for it shrank the search permanently. The\n @if moved out of the column so nothing reserves vertical space when absent. -->\n @if (searchTerm() && resultCount() !== null) {\n <div [md]=\"12\" class=\"text-end mt-1\">\n <span class=\"text-muted\">\n {{ resultCount() }} {{ resultCount() === 1 ? ('common.resultFound' | t) : ('common.resultsFound' | t) }}\n </span>\n </div>\n }\n </div>\n </bs-grid>\n </div>\n\n <!--\n One grid, both transports. `data` is null for a normal query, so the grid fetches and pages\n server-side; for a streaming query this page owns the socket and hands the filtered snapshot\n in. This used to be two near-identical <bs-datatable> blocks with a shared row template.\n -->\n <!-- The URL's scope (#contributions M5b): a parent and column filters from the query string, as\n the History link sends them. Shown so the narrowing is visible, and clearable. -->\n @if (urlParentId() || activeUrlFilters().length) {\n <div class=\"spark-url-filters d-flex flex-wrap align-items-center gap-2 mb-2 flex-shrink-0\" [class.px-4]=\"isVirtualScrolling()\">\n <span class=\"text-muted small\">{{ 'common.filteredBy' | t }}</span>\n @for (filter of activeUrlFilters(); track filter.name) {\n <bs-badge [type]=\"colors.secondary\" class=\"spark-url-filter\" [attr.data-filter]=\"filter.name\">\n {{ filterLabel(filter.name) }}: {{ filterValues(filter) }}\n <button type=\"button\" class=\"spark-url-filter-clear\" [attr.aria-label]=\"'common.clearFilter' | t\"\n (click)=\"clearUrlFilter(filter.name)\">\n <spark-icon name=\"x-circle\" />\n </button>\n </bs-badge>\n }\n <button type=\"button\" class=\"btn btn-sm btn-link spark-url-filters-clear\" (click)=\"clearUrlScope()\">\n {{ 'common.clearFilters' | t }}\n </button>\n </div>\n }\n\n <spark-query-grid class=\"flex-grow-1\"\n [queryId]=\"qId\"\n [parentId]=\"urlParentId()\"\n [parentType]=\"urlParentType()\"\n [presetFilters]=\"urlFilters()\"\n [data]=\"gridData()\"\n [columns]=\"gridData() ? streamColumns() : null\"\n [search]=\"searchTerm()\"\n [deleted]=\"deletedMode()\"\n [reloadToken]=\"gridReloadToken()\"\n [rowRoute]=\"rowRoute()\"\n (rowClicked)=\"rowClicked.emit($event)\"\n (customActionExecuted)=\"customActionExecuted.emit($event)\" />\n } @else {\n <div class=\"text-center p-5\">\n <bs-spinner />\n </div>\n }\n</div>\n",
|
|
523
|
+
styles: [".spark-actionbar{--_bleed-block: var(--spark-content-inset-block, 0px);--_bleed-inline: var(--spark-content-inset-inline, 0px);--_gutter: var(--spark-actionbar-gutter, 1rem);position:sticky;top:calc(-1 * var(--_bleed-block));z-index:400;background-color:var(--spark-shell-main-bg, var(--bs-body-bg));border-bottom:1px solid var(--bs-border-color);margin-bottom:1rem;margin-inline:calc(-1 * var(--_bleed-inline));padding-inline:calc(var(--_bleed-inline) + var(--_gutter))}.spark-actionbar .btn{border-radius:0}.spark-actionbar-wide{--spark-actionbar-gutter: 1.5rem}:host{display:flex;flex-direction:column;flex:1;min-height:0}:host.virtual-scrolling{margin:0 calc(-1 * var(--spark-main-padding, 1.5rem)) calc(-1 * var(--spark-main-padding, 1.5rem));--spark-content-inset-inline: 0px}:host.virtual-scrolling spark-query-grid{display:flex;flex-direction:column;min-height:0}:host.virtual-scrolling ::ng-deep bs-datatable{display:flex;flex-direction:column;min-height:0;--mp-datatable-virtual-max-height: 100%}:host.virtual-scrolling ::ng-deep bs-datatable mp-datatable{flex:1 1 auto;min-height:0}tr:hover{background-color:rgba(var(--bs-emphasis-color-rgb),.05)}td input[type=checkbox]:disabled{opacity:1;pointer-events:none}.spark-live-badge{font-size:.6em}.spark-url-filter-clear{background:none;border:0;padding:0 0 0 .25rem;color:inherit;line-height:1}\n"]
|
|
524
|
+
}]
|
|
525
|
+
}],
|
|
526
|
+
ctorParameters: () => [],
|
|
527
|
+
propDecorators: {
|
|
528
|
+
extraActionsTemplate: [{
|
|
529
|
+
type: i0.Input,
|
|
530
|
+
args: [{
|
|
531
|
+
isSignal: true,
|
|
532
|
+
alias: "extraActionsTemplate",
|
|
533
|
+
required: false
|
|
534
|
+
}]
|
|
535
|
+
}],
|
|
536
|
+
showCustomActions: [{
|
|
537
|
+
type: i0.Input,
|
|
538
|
+
args: [{
|
|
539
|
+
isSignal: true,
|
|
540
|
+
alias: "showCustomActions",
|
|
541
|
+
required: false
|
|
542
|
+
}]
|
|
543
|
+
}],
|
|
544
|
+
rowRoute: [{
|
|
545
|
+
type: i0.Input,
|
|
546
|
+
args: [{
|
|
547
|
+
isSignal: true,
|
|
548
|
+
alias: "rowRoute",
|
|
549
|
+
required: false
|
|
550
|
+
}]
|
|
551
|
+
}],
|
|
552
|
+
rowClicked: [{
|
|
553
|
+
type: i0.Output,
|
|
554
|
+
args: ["rowClicked"]
|
|
555
|
+
}],
|
|
556
|
+
createClicked: [{
|
|
557
|
+
type: i0.Output,
|
|
558
|
+
args: ["createClicked"]
|
|
559
|
+
}],
|
|
560
|
+
customActionExecuted: [{
|
|
561
|
+
type: i0.Output,
|
|
562
|
+
args: ["customActionExecuted"]
|
|
563
|
+
}],
|
|
564
|
+
grid: [{
|
|
565
|
+
type: i0.ViewChild,
|
|
566
|
+
args: [i0.forwardRef(() => SparkQueryGridComponent), { isSignal: true }]
|
|
567
|
+
}]
|
|
568
|
+
}
|
|
569
|
+
});
|
|
303
570
|
export { SparkQueryListComponent };
|
|
304
|
-
|
|
571
|
+
|
|
572
|
+
//# sourceMappingURL=mintplayer-ng-spark-query-list.mjs.map
|