@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,202 +1,251 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { Observable } from
|
|
4
|
-
import { SortColumn } from
|
|
5
|
-
import { SafeHtml } from
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<RetryActionService>;
|
|
1
|
+
import { CustomActionDefinition, DistinctValuesResult, EntityPermissions, EntityType, LookupReference, LookupReferenceListItem, LookupReferenceValue, PersistentObject, ProgramUnitsConfiguration, QueryColumnFilter, QueryResult, RetryActionPayload, RetryActionResult, SparkDeletedFilter, SparkQuery, StreamingMessage, TranslatedString } from "@mintplayer/ng-spark/models";
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import { Observable } from "rxjs";
|
|
4
|
+
import { SortColumn } from "@mintplayer/pagination";
|
|
5
|
+
import { SafeHtml } from "@angular/platform-browser";
|
|
6
|
+
import { HttpFeature, HttpFeatureKind, HttpInterceptorFn } from "@angular/common/http";
|
|
7
|
+
export declare class RetryActionService {
|
|
8
|
+
private resolveRetry;
|
|
9
|
+
payload: import("@angular/core").WritableSignal<RetryActionPayload | null>;
|
|
10
|
+
show(payload: RetryActionPayload): Promise<RetryActionResult>;
|
|
11
|
+
respond(result: RetryActionResult): void;
|
|
12
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RetryActionService, never>;
|
|
13
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
15
14
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<SparkLanguageService>;
|
|
15
|
+
export declare class SparkLanguageService {
|
|
16
|
+
private readonly http;
|
|
17
|
+
private readonly config;
|
|
18
|
+
private readonly baseUrl;
|
|
19
|
+
private readonly currentLang;
|
|
20
|
+
private readonly translationsMap;
|
|
21
|
+
readonly language: import("@angular/core").Signal<string>;
|
|
22
|
+
readonly languages: import("@angular/core").WritableSignal<Record<string, TranslatedString>>;
|
|
23
|
+
constructor();
|
|
24
|
+
private loadCulture;
|
|
25
|
+
private loadTranslations;
|
|
26
|
+
setLanguage(lang: string): void;
|
|
27
|
+
resolve(ts: TranslatedString | undefined): string;
|
|
28
|
+
t(key: string): string;
|
|
29
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkLanguageService, never>;
|
|
30
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
33
31
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<SparkStreamingService>;
|
|
32
|
+
export declare class SparkStreamingService {
|
|
33
|
+
private readonly config;
|
|
34
|
+
private readonly baseUrl;
|
|
35
|
+
private readonly ngZone;
|
|
36
|
+
connectToStreamingQuery(queryId: string): Observable<StreamingMessage>;
|
|
37
|
+
private buildWebSocketUrl;
|
|
38
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkStreamingService, never>;
|
|
39
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
43
40
|
}
|
|
44
|
-
|
|
45
41
|
/**
|
|
46
42
|
* Context for {@link SparkService.newObject}. Everything is optional: a standalone New sends an
|
|
47
43
|
* empty body, and an AsDetail row on a parent that has never been saved sends no `parentId` —
|
|
48
44
|
* which is the honest answer, not a gap. The server hands the hook a null parent rather than
|
|
49
45
|
* trusting the client's copy of one.
|
|
50
46
|
*/
|
|
51
|
-
interface NewObjectOptions {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
47
|
+
export interface NewObjectOptions {
|
|
48
|
+
/** Name of the parent's AsDetail attribute the row is for; absent for a standalone New. */
|
|
49
|
+
asDetailAttribute?: string;
|
|
50
|
+
/** The parent's entity type — required whenever `asDetailAttribute` is set. */
|
|
51
|
+
parentType?: string;
|
|
52
|
+
/** The parent's id, absent while the parent is itself unsaved. */
|
|
53
|
+
parentId?: string;
|
|
54
|
+
/** Free-form arguments, e.g. which variant a New menu chose. */
|
|
55
|
+
parameters?: Record<string, string>;
|
|
56
|
+
/**
|
|
57
|
+
* The sub-query New was started from (#460, D19), with `parentType` and `parentId` and no
|
|
58
|
+
* `asDetailAttribute`. The server loads the parent, checks the parent's type declares this
|
|
59
|
+
* sub-query, and runs `OnNewAsync` with it — whose base fills the reference to the parent.
|
|
60
|
+
*/
|
|
61
|
+
queryId?: string;
|
|
62
|
+
}
|
|
63
|
+
/** Where a bulk delete was started from; see {@link SparkService.deleteMany}. */
|
|
64
|
+
export interface DeleteManyOptions {
|
|
65
|
+
/** The query the rows were selected in, for the server's `OnDisableActionsAsync`. */
|
|
66
|
+
queryId?: string;
|
|
67
|
+
/** The sub-query's container, when deleting from a sub-query. */
|
|
68
|
+
parentId?: string;
|
|
69
|
+
parentType?: string;
|
|
60
70
|
}
|
|
61
71
|
/** Context for {@link SparkService.deleteRow}. Every field is required — see `DeleteRow.cs`. */
|
|
62
|
-
interface DeleteRowOptions {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
export interface DeleteRowOptions {
|
|
73
|
+
asDetailAttribute: string;
|
|
74
|
+
parentType: string;
|
|
75
|
+
parentId: string;
|
|
76
|
+
/** The row's `__sparkRowKey`, as it arrived from the server. */
|
|
77
|
+
rowKey: string;
|
|
78
|
+
parameters?: Record<string, string>;
|
|
69
79
|
}
|
|
70
|
-
declare class SparkService {
|
|
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
|
-
parentId?: string;
|
|
114
|
-
parentType?: string;
|
|
115
|
-
}): Promise<DistinctValuesResult>;
|
|
116
|
-
/**
|
|
117
|
-
* Runs a query identified by name.
|
|
118
|
-
*
|
|
119
|
-
* It used to forward only the parent, dropping skip/take/search — so every reference picker and
|
|
120
|
-
* AsDetail reference column silently saw the server's default of 50 candidates, with no indication
|
|
121
|
-
* that the list was cut. A picker that omits the option you are looking for, and says nothing, is
|
|
122
|
-
* worse than one that fails.
|
|
123
|
-
*/
|
|
124
|
-
executeQueryByName(queryName: string, options?: ExecuteQueryOptions): Promise<QueryResult>;
|
|
125
|
-
getProgramUnits(): Promise<ProgramUnitsConfiguration>;
|
|
126
|
-
get(type: string, id: string): Promise<PersistentObject>;
|
|
127
|
-
create(type: string, data: Partial<PersistentObject>): Promise<PersistentObject>;
|
|
128
|
-
update(type: string, id: string, data: Partial<PersistentObject>): Promise<PersistentObject>;
|
|
129
|
-
/**
|
|
130
|
-
* Asks the server to reshape an in-progress object after `triggeredBy`'s value changed.
|
|
131
|
-
*
|
|
132
|
-
* Writes nothing, but goes through the envelope like every other mutating call: a refresh may
|
|
133
|
-
* legitimately emit notifications, and may open the retry-action prompt.
|
|
134
|
-
*
|
|
135
|
-
* `triggeredBy` is the attribute's name. For a trigger inside an AsDetail row it is the same
|
|
136
|
-
* path form the inline validation errors use — `Jobs[2].ProfessionId`.
|
|
137
|
-
*/
|
|
138
|
-
refresh(type: string, data: Partial<PersistentObject>, triggeredBy: string): Promise<PersistentObject>;
|
|
139
|
-
/**
|
|
140
|
-
* Asks the server to construct a new object of `type`, so `OnNewAsync` can default it.
|
|
141
|
-
*
|
|
142
|
-
* Writes nothing — the object comes back unsaved, and for an AsDetail row the parent still owns
|
|
143
|
-
* the save. Only called for a row type whose `serverSideRowLifecycle` is on; every other type
|
|
144
|
-
* keeps building its blank row locally, which is why switching the flag off costs no request.
|
|
145
|
-
*
|
|
146
|
-
* ⚠️ The row comes back **keyed**: the server constructs the CLR instance, so the row-key field
|
|
147
|
-
* initializer runs and `po.id` carries the key. Flattening it with `nestedPoToDict` therefore
|
|
148
|
-
* populates `__sparkRowKey`, and the row is matchable on save from the moment it is added — the
|
|
149
|
-
* whole reason this round-trip is worth a request.
|
|
150
|
-
*/
|
|
151
|
-
newObject(type: string, options?: NewObjectOptions): Promise<PersistentObject>;
|
|
152
|
-
/**
|
|
153
|
-
* Asks whether a stored row may leave its parent's AsDetail collection.
|
|
154
|
-
*
|
|
155
|
-
* Deletes nothing: a resolved promise means the caller may splice the row out of the collection
|
|
156
|
-
* it is editing, and the removal is persisted with the parent. A hook that refuses rejects with a
|
|
157
|
-
* 400 whose `error.error.result.errors` carries the readable reason, exactly like a save.
|
|
158
|
-
*
|
|
159
|
-
* A POST — as everything is now. It used to be worth explaining: the framework's real delete route
|
|
160
|
-
* was a catch-all that would have swallowed a sibling DELETE. The catch-all is gone with the rest
|
|
161
|
-
* of the route variables.
|
|
162
|
-
*/
|
|
163
|
-
deleteRow(type: string, options: DeleteRowOptions): Promise<void>;
|
|
164
|
-
delete(type: string, id: string): Promise<void>;
|
|
165
|
-
getCustomActions(objectTypeId: string): Promise<CustomActionDefinition[]>;
|
|
166
|
-
/**
|
|
167
|
-
* @param parent The object of THIS type the action is operating on — the detail-page invocation.
|
|
168
|
-
* @param selectedItemIds Row ids from a query. Ids, never row objects: a row is a projection.
|
|
169
|
-
* @param queryParent When invoked from a sub-query, the object whose detail page it was rendered
|
|
170
|
-
* on — a DIFFERENT type (the cars listed on a company's page are Cars, the page is a Company).
|
|
171
|
-
* Sent as id + type, exactly as the query endpoint names it, and resolved server-side under its
|
|
172
|
-
* own type with its own Read gate.
|
|
173
|
-
* @param queryId The query the selection came from, so the server can re-run it narrowed to those
|
|
174
|
-
* ids and hand the action the rows the grid actually had -- index-computed columns included.
|
|
175
|
-
*/
|
|
176
|
-
executeCustomAction(objectTypeId: string, actionName: string, parent?: PersistentObject, selectedItemIds?: string[], queryParent?: {
|
|
177
|
-
id: string;
|
|
178
|
-
type: string;
|
|
179
|
-
}, queryId?: string): Promise<void>;
|
|
180
|
-
getLookupReferences(): Promise<LookupReferenceListItem[]>;
|
|
181
|
-
getLookupReference(name: string): Promise<LookupReference>;
|
|
182
|
-
addLookupReferenceValue(name: string, value: LookupReferenceValue): Promise<LookupReferenceValue>;
|
|
183
|
-
updateLookupReferenceValue(name: string, key: string, value: LookupReferenceValue): Promise<LookupReferenceValue>;
|
|
184
|
-
deleteLookupReferenceValue(name: string, key: string): Promise<void>;
|
|
185
|
-
private postWithEnvelope;
|
|
80
|
+
export declare class SparkService {
|
|
81
|
+
#private;
|
|
82
|
+
private readonly config;
|
|
83
|
+
private readonly baseUrl;
|
|
84
|
+
private readonly http;
|
|
85
|
+
private readonly retryActionService;
|
|
86
|
+
/**
|
|
87
|
+
* How many prompts one request will answer before giving up. Matches the .NET client's
|
|
88
|
+
* `SparkClient.MaxRetryDepth`, and for the same reason: this is a termination bound, not a
|
|
89
|
+
* capacity one. Far above any real conversation (Fleet's longest is two) and far below anything
|
|
90
|
+
* that could hide a spin.
|
|
91
|
+
*/
|
|
92
|
+
private static readonly MAX_RETRY_DEPTH;
|
|
93
|
+
private readonly dispatcher;
|
|
94
|
+
getEntityTypes(): Promise<EntityType[]>;
|
|
95
|
+
getEntityType(id: string): Promise<EntityType>;
|
|
96
|
+
getEntityTypeByClrType(clrType: string): Promise<EntityType | undefined>;
|
|
97
|
+
getPermissions(entityTypeId: string): Promise<EntityPermissions>;
|
|
98
|
+
getQueries(): Promise<SparkQuery[]>;
|
|
99
|
+
getQuery(id: string): Promise<SparkQuery>;
|
|
100
|
+
/**
|
|
101
|
+
* Resolves a query by name, fetching the catalogue at most once per service instance.
|
|
102
|
+
*
|
|
103
|
+
* Without the cache this costs a full `GET /spark/queries` per call, and a form with several
|
|
104
|
+
* reference attributes resolves them in parallel — so opening one page fetched the whole query
|
|
105
|
+
* catalogue N times over. The catalogue is per-caller and effectively static for a page's
|
|
106
|
+
* lifetime; the service is scoped to the app, so a permission change lands on the next load.
|
|
107
|
+
*/
|
|
108
|
+
getQueryByName(name: string): Promise<SparkQuery | undefined>;
|
|
109
|
+
executeQuery(queryId: string, options?: ExecuteQueryOptions): Promise<QueryResult>;
|
|
110
|
+
/**
|
|
111
|
+
* The distinct values behind one column's filter panel (#431).
|
|
112
|
+
*
|
|
113
|
+
* `columns` carries the OTHER columns' current filters, so the values returned are the ones still
|
|
114
|
+
* reachable — offering a value that empties the grid the moment it is picked is worse than
|
|
115
|
+
* omitting it.
|
|
116
|
+
*
|
|
117
|
+
* An empty result means either "nothing matches" or "you may not enumerate this column". The two
|
|
118
|
+
* are deliberately indistinguishable, so there is nothing for a caller to branch on.
|
|
119
|
+
*/
|
|
120
|
+
getDistinctValues(queryId: string, column: string, options?: {
|
|
121
|
+
/** Narrows the listed values themselves (the panel's own box). */
|
|
122
|
+
search?: string;
|
|
186
123
|
/**
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
* The read endpoints moved from GET to POST so their hooks could prompt, but their success
|
|
191
|
-
* responses are still bare — a `PersistentObject`, a `QueryResult`. Only the 449 is enveloped,
|
|
192
|
-
* because a retry has nowhere else to live. So this shares the retry loop with the mutating calls
|
|
193
|
-
* and nothing else.
|
|
124
|
+
* The grid's search term, what `executeQuery` sends as `search` (#460 M15): the values come only
|
|
125
|
+
* from the rows it matches, so a searched grid's panel lists what the grid shows.
|
|
194
126
|
*/
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
127
|
+
querySearch?: string;
|
|
128
|
+
columns?: QueryColumnFilter[];
|
|
129
|
+
parentId?: string;
|
|
130
|
+
parentType?: string;
|
|
131
|
+
/** The same soft-deletion mode as the grid the panel belongs to (#460). */
|
|
132
|
+
deleted?: SparkDeletedFilter;
|
|
133
|
+
/** The same parent mode as the grid the panel belongs to (#460). */
|
|
134
|
+
parentDeleted?: SparkDeletedFilter;
|
|
135
|
+
}): Promise<DistinctValuesResult>;
|
|
136
|
+
/**
|
|
137
|
+
* Runs a query identified by name.
|
|
138
|
+
*
|
|
139
|
+
* It used to forward only the parent, dropping skip/take/search — so every reference picker and
|
|
140
|
+
* AsDetail reference column silently saw the server's default of 50 candidates, with no indication
|
|
141
|
+
* that the list was cut. A picker that omits the option you are looking for, and says nothing, is
|
|
142
|
+
* worse than one that fails.
|
|
143
|
+
*/
|
|
144
|
+
executeQueryByName(queryName: string, options?: ExecuteQueryOptions): Promise<QueryResult>;
|
|
145
|
+
getProgramUnits(): Promise<ProgramUnitsConfiguration>;
|
|
146
|
+
/**
|
|
147
|
+
* Loads one object. `options.deleted` (#460) lets a `ViewDeleted` holder open a soft-deleted row
|
|
148
|
+
* from the recycle bin (`'include'` or `'only'`); without the right the server ignores it and a
|
|
149
|
+
* deleted row stays a 404. Omitted = exclude.
|
|
150
|
+
*/
|
|
151
|
+
get(type: string, id: string, options?: {
|
|
152
|
+
deleted?: SparkDeletedFilter;
|
|
153
|
+
}): Promise<PersistentObject>;
|
|
154
|
+
create(type: string, data: Partial<PersistentObject>): Promise<PersistentObject>;
|
|
155
|
+
update(type: string, id: string, data: Partial<PersistentObject>): Promise<PersistentObject>;
|
|
156
|
+
/**
|
|
157
|
+
* Asks the server to reshape an in-progress object after `triggeredBy`'s value changed.
|
|
158
|
+
*
|
|
159
|
+
* Writes nothing, but goes through the envelope like every other mutating call: a refresh may
|
|
160
|
+
* legitimately emit notifications, and may open the retry-action prompt.
|
|
161
|
+
*
|
|
162
|
+
* `triggeredBy` is the attribute's name. For a trigger inside an AsDetail row it is the same
|
|
163
|
+
* path form the inline validation errors use — `Jobs[2].ProfessionId`.
|
|
164
|
+
*/
|
|
165
|
+
refresh(type: string, data: Partial<PersistentObject>, triggeredBy: string): Promise<PersistentObject>;
|
|
166
|
+
/**
|
|
167
|
+
* Asks the server to construct a new object of `type`, so `OnNewAsync` can default it.
|
|
168
|
+
*
|
|
169
|
+
* Writes nothing — the object comes back unsaved, and for an AsDetail row the parent still owns
|
|
170
|
+
* the save. Called by the create page for every New (#460, D19: with `parentId`/`parentType`/
|
|
171
|
+
* `queryId` when started from a sub-query, whose base hook fills the parent reference), and for an
|
|
172
|
+
* AsDetail row only when its type's `serverSideRowLifecycle` is on; every other row type keeps
|
|
173
|
+
* building its blank row locally, which is why switching the flag off costs no request.
|
|
174
|
+
*
|
|
175
|
+
* ⚠️ The row comes back **keyed**: the server constructs the CLR instance, so the row-key field
|
|
176
|
+
* initializer runs and `po.id` carries the key. Flattening it with `nestedPoToDict` therefore
|
|
177
|
+
* populates `__sparkRowKey`, and the row is matchable on save from the moment it is added — the
|
|
178
|
+
* whole reason this round-trip is worth a request.
|
|
179
|
+
*/
|
|
180
|
+
newObject(type: string, options?: NewObjectOptions): Promise<PersistentObject>;
|
|
181
|
+
/**
|
|
182
|
+
* Asks whether a stored row may leave its parent's AsDetail collection.
|
|
183
|
+
*
|
|
184
|
+
* Deletes nothing: a resolved promise means the caller may splice the row out of the collection
|
|
185
|
+
* it is editing, and the removal is persisted with the parent. A hook that refuses rejects with a
|
|
186
|
+
* 400 whose `error.error.result.errors` carries the readable reason, exactly like a save.
|
|
187
|
+
*
|
|
188
|
+
* A POST — as everything is now. It used to be worth explaining: the framework's real delete route
|
|
189
|
+
* was a catch-all that would have swallowed a sibling DELETE. The catch-all is gone with the rest
|
|
190
|
+
* of the route variables.
|
|
191
|
+
*/
|
|
192
|
+
deleteRow(type: string, options: DeleteRowOptions): Promise<void>;
|
|
193
|
+
delete(type: string, id: string): Promise<void>;
|
|
194
|
+
/**
|
|
195
|
+
* Deletes several rows of one type in one request — the default Delete action on a selection
|
|
196
|
+
* (`POST /spark/po/delete-many`, #460 D18). All or nothing: a 404 means some row is missing or not
|
|
197
|
+
* yours to delete, a 403 that the server's `OnDisableActionsAsync` withholds Delete on the query or
|
|
198
|
+
* on one of the rows, a 400 that the selection breaks the rule or the 200-row cap.
|
|
199
|
+
*/
|
|
200
|
+
deleteMany(type: string, ids: string[], options?: DeleteManyOptions): Promise<void>;
|
|
201
|
+
getCustomActions(objectTypeId: string): Promise<CustomActionDefinition[]>;
|
|
202
|
+
/**
|
|
203
|
+
* @param parent The object of THIS type the action is operating on — the detail-page invocation.
|
|
204
|
+
* @param selectedItemIds Row ids from a query. Ids, never row objects: a row is a projection.
|
|
205
|
+
* @param queryParent When invoked from a sub-query, the object whose detail page it was rendered
|
|
206
|
+
* on — a DIFFERENT type (the cars listed on a company's page are Cars, the page is a Company).
|
|
207
|
+
* Sent as id + type, exactly as the query endpoint names it, and resolved server-side under its
|
|
208
|
+
* own type with its own Read gate.
|
|
209
|
+
* @param queryId The query the selection came from, so the server can re-run it narrowed to those
|
|
210
|
+
* ids and hand the action the rows the grid actually had -- index-computed columns included.
|
|
211
|
+
* @returns What the action handed to `CustomActionArgs.SetResult` (#460, T5) -- the envelope's
|
|
212
|
+
* `result` -- or `undefined` when it set nothing. The value is the action author's to shape: it
|
|
213
|
+
* bypasses the server's redaction. A 403 means the action is disabled for this object, query or
|
|
214
|
+
* selection (the server's `OnDisableActionsAsync` said so), distinct from a 404 for a row the
|
|
215
|
+
* caller cannot see.
|
|
216
|
+
*/
|
|
217
|
+
executeCustomAction<T = unknown>(objectTypeId: string, actionName: string, parent?: PersistentObject, selectedItemIds?: string[], queryParent?: {
|
|
218
|
+
id: string;
|
|
219
|
+
type: string;
|
|
220
|
+
}, queryId?: string): Promise<T | undefined>;
|
|
221
|
+
getLookupReferences(): Promise<LookupReferenceListItem[]>;
|
|
222
|
+
getLookupReference(name: string): Promise<LookupReference>;
|
|
223
|
+
addLookupReferenceValue(name: string, value: LookupReferenceValue): Promise<LookupReferenceValue>;
|
|
224
|
+
updateLookupReferenceValue(name: string, key: string, value: LookupReferenceValue): Promise<LookupReferenceValue>;
|
|
225
|
+
deleteLookupReferenceValue(name: string, key: string): Promise<void>;
|
|
226
|
+
/**
|
|
227
|
+
* Posts to an add-on package's endpoint under the Spark base URL (`/spark` + `path`) and unwraps
|
|
228
|
+
* the `ClientOperationEnvelope` exactly like the built-in mutations: operations are dispatched and
|
|
229
|
+
* a 449 retry opens the retry modal. For the ng-spark add-on entry points (`soft-delete`,
|
|
230
|
+
* `history`, `moderation`) whose server packages answer through core's envelope helpers
|
|
231
|
+
* (`SparkAddOnEndpoints`, #460).
|
|
232
|
+
*/
|
|
233
|
+
postEnvelope<T>(path: string, body: Record<string, unknown>): Promise<T>;
|
|
234
|
+
private postWithEnvelope;
|
|
235
|
+
/**
|
|
236
|
+
* A read: posts the request, and returns the response **as-is** rather than unwrapping an
|
|
237
|
+
* envelope.
|
|
238
|
+
*
|
|
239
|
+
* The read endpoints moved from GET to POST so their hooks could prompt, but their success
|
|
240
|
+
* responses are still bare — a `PersistentObject`, a `QueryResult`. Only the 449 is enveloped,
|
|
241
|
+
* because a retry has nowhere else to live. So this shares the retry loop with the mutating calls
|
|
242
|
+
* and nothing else.
|
|
243
|
+
*/
|
|
244
|
+
private sendRead;
|
|
245
|
+
private sendWithEnvelope;
|
|
246
|
+
private handleEnvelopeRetryError;
|
|
247
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkService, never>;
|
|
248
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
200
249
|
}
|
|
201
250
|
/**
|
|
202
251
|
* The options every query execution takes.
|
|
@@ -205,17 +254,28 @@ declare class SparkService {
|
|
|
205
254
|
* options as separate inline literals a field added to one silently failed to forward from the
|
|
206
255
|
* other — which is how skip/take/search were once dropped for every reference picker.
|
|
207
256
|
*/
|
|
208
|
-
interface ExecuteQueryOptions {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
257
|
+
export interface ExecuteQueryOptions {
|
|
258
|
+
sortColumns?: SortColumn[];
|
|
259
|
+
parentId?: string;
|
|
260
|
+
parentType?: string;
|
|
261
|
+
skip?: number;
|
|
262
|
+
take?: number;
|
|
263
|
+
search?: string;
|
|
264
|
+
/** Per-column value filters (#431). Columns AND together; values within a column OR. */
|
|
265
|
+
columns?: QueryColumnFilter[];
|
|
266
|
+
/**
|
|
267
|
+
* Soft-deletion mode (#460): `exclude` (default), `include`, `only`. Sent only when set; the server
|
|
268
|
+
* honours a widening only for callers holding `ViewDeleted` on the type.
|
|
269
|
+
*/
|
|
270
|
+
deleted?: SparkDeletedFilter;
|
|
271
|
+
/**
|
|
272
|
+
* The mode the PARENT (`parentId`/`parentType`) is resolved under (#460) — `include` for a sub-query
|
|
273
|
+
* on a deleted object's page, opened from the recycle bin. Independent of `deleted`, which stays the
|
|
274
|
+
* rows' filter. Honoured only for callers holding `ViewDeleted` on the parent's type; anyone else
|
|
275
|
+
* gets the same 404 a missing parent gives.
|
|
276
|
+
*/
|
|
277
|
+
parentDeleted?: SparkDeletedFilter;
|
|
217
278
|
}
|
|
218
|
-
|
|
219
279
|
/**
|
|
220
280
|
* R2-M12: SVG icon registry. The registry no longer accepts a raw string —
|
|
221
281
|
* apps must pre-sanitize via `DomSanitizer.bypassSecurityTrustHtml` (or
|
|
@@ -228,29 +288,28 @@ interface ExecuteQueryOptions {
|
|
|
228
288
|
* The built-in icons baked into the package are still bypass-trusted internally
|
|
229
289
|
* because they're known-safe at build time.
|
|
230
290
|
*/
|
|
231
|
-
declare class SparkIconRegistry {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
291
|
+
export declare class SparkIconRegistry {
|
|
292
|
+
private sanitizer;
|
|
293
|
+
private icons;
|
|
294
|
+
constructor();
|
|
295
|
+
/**
|
|
296
|
+
* Registers a pre-sanitized SVG icon. Callers MUST validate or explicitly
|
|
297
|
+
* trust the SVG before passing — for example:
|
|
298
|
+
*
|
|
299
|
+
* ```ts
|
|
300
|
+
* const safe = sanitizer.bypassSecurityTrustHtml(svgFromBuildTimeConstant);
|
|
301
|
+
* registry.register('app-logo', safe);
|
|
302
|
+
* ```
|
|
303
|
+
*
|
|
304
|
+
* For server-supplied SVG, prefer a strict allow-list parser (no `<script>`,
|
|
305
|
+
* no `on*` attributes, no `href="javascript:..."`) before trusting.
|
|
306
|
+
*/
|
|
307
|
+
register(name: string, svg: SafeHtml): void;
|
|
308
|
+
get(name: string): SafeHtml | undefined;
|
|
309
|
+
has(name: string): boolean;
|
|
310
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkIconRegistry, never>;
|
|
311
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
252
312
|
}
|
|
253
|
-
|
|
254
313
|
/**
|
|
255
314
|
* A query's custom actions, reachable **without the grid that usually renders them**.
|
|
256
315
|
*
|
|
@@ -274,44 +333,58 @@ declare class SparkIconRegistry {
|
|
|
274
333
|
* It also does not cache. Actions depend on the caller, and a memo keyed by type id would survive
|
|
275
334
|
* a sign-out.
|
|
276
335
|
*/
|
|
277
|
-
declare class SparkQueryActionsService {
|
|
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
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
336
|
+
export declare class SparkQueryActionsService {
|
|
337
|
+
private readonly sparkService;
|
|
338
|
+
/**
|
|
339
|
+
* The custom actions of the query named by id or alias, already filtered to those that belong on
|
|
340
|
+
* a query surface.
|
|
341
|
+
*
|
|
342
|
+
* Returns an empty list — rather than throwing — when the query resolves to no entity type,
|
|
343
|
+
* because a caller rendering a toolbar wants "no buttons", not a broken page.
|
|
344
|
+
*/
|
|
345
|
+
actionsFor(queryIdOrAlias: string): Promise<CustomActionDefinition[]>;
|
|
346
|
+
/**
|
|
347
|
+
* Runs one of those actions. `selectedItemIds` are row ids, exactly as the grid posts them —
|
|
348
|
+
* the server re-materializes each one through the same load path a detail page uses, so an id
|
|
349
|
+
* from anywhere is treated as caller input rather than as a verified row.
|
|
350
|
+
*/
|
|
351
|
+
execute(queryIdOrAlias: string, actionName: string, options?: {
|
|
352
|
+
parent?: PersistentObject;
|
|
353
|
+
selectedItemIds?: string[];
|
|
354
|
+
/** For a sub-query: the object whose detail page it was rendered on. See SparkService. */
|
|
355
|
+
queryParent?: {
|
|
356
|
+
id: string;
|
|
357
|
+
type: string;
|
|
358
|
+
};
|
|
359
|
+
}): Promise<void>;
|
|
360
|
+
/**
|
|
361
|
+
* The query and the entity type its rows are mapped against — the two-step resolution both
|
|
362
|
+
* methods need, kept in one place so they cannot disagree about which type an action runs on.
|
|
363
|
+
*/
|
|
364
|
+
private contextFor;
|
|
365
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkQueryActionsService, never>;
|
|
366
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
308
367
|
}
|
|
309
|
-
|
|
310
368
|
/**
|
|
311
369
|
* The header carrying the viewer's IANA timezone id, e.g. `Europe/Brussels`.
|
|
312
370
|
* Must stay in lockstep with `RequestTimeZoneResolver.HeaderName` on the server.
|
|
313
371
|
*/
|
|
314
|
-
declare const SPARK_TIMEZONE_HEADER = "X-Spark-Timezone";
|
|
372
|
+
export declare const SPARK_TIMEZONE_HEADER = "X-Spark-Timezone";
|
|
373
|
+
/**
|
|
374
|
+
* The default name of the cookie carrying the same id, for requests the browser makes without any
|
|
375
|
+
* script running first (a server-side render, a link opened from a mail). Must stay in lockstep
|
|
376
|
+
* with `SparkTimeZoneOptions.DefaultCookieName` (`Spark:TimeZone:CookieName`) on the server.
|
|
377
|
+
*/
|
|
378
|
+
export declare const SPARK_TIMEZONE_COOKIE = "spark-timezone";
|
|
379
|
+
/** Options for {@link withSparkTimezone}. */
|
|
380
|
+
export interface SparkTimezoneOptions {
|
|
381
|
+
/**
|
|
382
|
+
* The cookie to write the viewer's zone into; `false` writes none (the header is still sent).
|
|
383
|
+
* Defaults to {@link SPARK_TIMEZONE_COOKIE}. Use the same name as the server's
|
|
384
|
+
* `Spark:TimeZone:CookieName`.
|
|
385
|
+
*/
|
|
386
|
+
cookieName?: string | false;
|
|
387
|
+
}
|
|
315
388
|
/**
|
|
316
389
|
* Returns the browser's IANA zone id, or `null` when the environment cannot name one.
|
|
317
390
|
*
|
|
@@ -319,23 +392,66 @@ declare const SPARK_TIMEZONE_HEADER = "X-Spark-Timezone";
|
|
|
319
392
|
* so a server asked to render "next Tuesday at 09:00" from an offset captured today gets it wrong
|
|
320
393
|
* across a DST boundary. A zone id carries the rules, not one sample of them.
|
|
321
394
|
*/
|
|
322
|
-
declare function resolveBrowserTimeZone(): string | null;
|
|
395
|
+
export declare function resolveBrowserTimeZone(): string | null;
|
|
323
396
|
/**
|
|
324
|
-
*
|
|
397
|
+
* Builds the interceptor for {@link withSparkTimezone}. Exported for apps that compose their own
|
|
398
|
+
* `withInterceptors([...])`.
|
|
325
399
|
*
|
|
326
400
|
* **This does not participate in reading or writing timestamps.** A `DateTimeOffset` means an
|
|
327
|
-
* instant, and the browser converts in both directions on those paths. The header
|
|
328
|
-
* the server
|
|
329
|
-
* browser in the loop to do the converting but the output still has to
|
|
401
|
+
* instant, and the browser converts in both directions on those paths. The header and cookie exist
|
|
402
|
+
* for work the server does on its own — a scheduled export, a notification email, a server-side
|
|
403
|
+
* render — where there is no browser in the loop to do the converting but the output still has to
|
|
404
|
+
* read as local time.
|
|
405
|
+
*
|
|
406
|
+
* ⚠️ **Nothing happens on the server platform.** During a server-side render `Intl` names the Node
|
|
407
|
+
* process's zone (UTC in a container), and a header carrying it would win over the viewer's cookie
|
|
408
|
+
* on the server (spike S-TZ3, #460).
|
|
330
409
|
*/
|
|
331
|
-
declare
|
|
410
|
+
export declare function createSparkTimezoneInterceptor(options?: SparkTimezoneOptions): HttpInterceptorFn;
|
|
332
411
|
/**
|
|
333
|
-
*
|
|
412
|
+
* Attaches {@link SPARK_TIMEZONE_HEADER} to same-origin requests and keeps the
|
|
413
|
+
* {@link SPARK_TIMEZONE_COOKIE} cookie current — with the default options. See
|
|
414
|
+
* {@link createSparkTimezoneInterceptor}.
|
|
415
|
+
*/
|
|
416
|
+
export declare const sparkTimezoneInterceptor: HttpInterceptorFn;
|
|
417
|
+
/**
|
|
418
|
+
* `provideHttpClient(...withSparkTimezone())` — registers the timezone interceptor.
|
|
334
419
|
*
|
|
335
420
|
* Spreadable alongside `withSparkAuth()`:
|
|
336
421
|
* `provideHttpClient(...withSparkAuth(), ...withSparkTimezone())`.
|
|
422
|
+
*
|
|
423
|
+
* The cookie is written on the first request the browser app makes, so the very first server-side
|
|
424
|
+
* render of a first visit has no cookie and renders in UTC.
|
|
425
|
+
*/
|
|
426
|
+
export declare function withSparkTimezone(options?: SparkTimezoneOptions): HttpFeature<HttpFeatureKind>[];
|
|
427
|
+
/** The `history.state` key a list row link stores the list's own URL under. */
|
|
428
|
+
export declare const SPARK_RETURN_URL_STATE_KEY = "sparkReturnUrl";
|
|
429
|
+
/**
|
|
430
|
+
* Where a detail page goes back to after its row stops existing — a Delete, or a Purge from the
|
|
431
|
+
* recycle bin (#460).
|
|
432
|
+
*
|
|
433
|
+
* Neither "the start page" nor "the previous history entry" is the right answer: the first loses the
|
|
434
|
+
* user's place, the second may be the deleted row's edit page, or another site. The right answer is
|
|
435
|
+
* the list the row was opened from, so a list's row link records that list's URL in the navigation
|
|
436
|
+
* state ({@link stateForRowLink}); a detail page reached otherwise (a bookmark, a reference link)
|
|
437
|
+
* falls back to the row type's own list — its program-unit query, else any query over the type.
|
|
337
438
|
*/
|
|
338
|
-
declare
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
439
|
+
export declare class SparkReturnNavigationService {
|
|
440
|
+
private readonly router;
|
|
441
|
+
private readonly spark;
|
|
442
|
+
/** Navigation state for a row link: the current URL (the list, with its `?deleted=` mode). */
|
|
443
|
+
stateForRowLink(): Record<string, string>;
|
|
444
|
+
/** The list URL the current detail page was opened from, when a row link recorded one. */
|
|
445
|
+
recordedReturnUrl(): string | null;
|
|
446
|
+
/**
|
|
447
|
+
* Navigates to the list the row came from, else to the type's list (`?deleted=only` kept when
|
|
448
|
+
* `deletedView`), else to the start page. `replaceUrl`: the gone row's page is not worth a Back.
|
|
449
|
+
*/
|
|
450
|
+
returnToList(entityTypeName: string | null | undefined, options?: {
|
|
451
|
+
deletedView?: boolean;
|
|
452
|
+
}): Promise<void>;
|
|
453
|
+
/** `['/query', alias]` of the type's list: a menu (program-unit) query first, else any query. */
|
|
454
|
+
listRouteFor(entityTypeName: string): Promise<unknown[] | null>;
|
|
455
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SparkReturnNavigationService, never>;
|
|
456
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
457
|
+
}
|