@meshmakers/shared-services 3.3.34 → 3.3.390
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 +40 -13
- package/fesm2022/meshmakers-shared-services.mjs +583 -348
- package/fesm2022/meshmakers-shared-services.mjs.map +1 -1
- package/package.json +5 -5
- package/types/meshmakers-shared-services.d.ts +304 -0
- package/index.d.ts +0 -189
|
@@ -1,14 +1,203 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, Injectable,
|
|
3
|
-
import {
|
|
4
|
-
import { BehaviorSubject, throwError } from 'rxjs';
|
|
5
|
-
import { retry, catchError } from 'rxjs/operators';
|
|
6
|
-
|
|
2
|
+
import { inject, Injectable, makeEnvironmentProviders } from '@angular/core';
|
|
3
|
+
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
|
|
4
|
+
import { BehaviorSubject, Subject, firstValueFrom, throwError } from 'rxjs';
|
|
5
|
+
import { filter, retry, catchError } from 'rxjs/operators';
|
|
6
|
+
|
|
7
|
+
class CommandOptions {
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
class CommandSettingsService {
|
|
11
|
+
_activatedRoute;
|
|
12
|
+
constructor() {
|
|
13
|
+
this._activatedRoute = inject(ActivatedRoute);
|
|
14
|
+
}
|
|
15
|
+
get navigateRelativeToRoute() {
|
|
16
|
+
return this._activatedRoute;
|
|
17
|
+
}
|
|
18
|
+
get commandItems() {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CommandSettingsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
22
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CommandSettingsService });
|
|
23
|
+
}
|
|
24
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CommandSettingsService, decorators: [{
|
|
25
|
+
type: Injectable
|
|
26
|
+
}], ctorParameters: () => [] });
|
|
27
|
+
|
|
28
|
+
class CommandBaseService {
|
|
29
|
+
commandSettingsService;
|
|
30
|
+
router;
|
|
31
|
+
constructor(commandSettingsService, router) {
|
|
32
|
+
this.commandSettingsService = commandSettingsService;
|
|
33
|
+
this.router = router;
|
|
34
|
+
}
|
|
35
|
+
async navigateAsync(commandItem, data) {
|
|
36
|
+
console.debug('navigateAsync', commandItem);
|
|
37
|
+
const hrefUri = await CommandBaseService.getHref(commandItem, data);
|
|
38
|
+
const link = await CommandBaseService.getLink(commandItem, data);
|
|
39
|
+
if (hrefUri) {
|
|
40
|
+
window.open(hrefUri, commandItem.target ?? "_blank");
|
|
41
|
+
}
|
|
42
|
+
else if (link) {
|
|
43
|
+
await this.router.navigate([link], {
|
|
44
|
+
relativeTo: this.commandSettingsService.navigateRelativeToRoute
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else if (commandItem.onClick) {
|
|
48
|
+
await CommandBaseService.executeClickEvent(commandItem, data);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
console.debug('navigateAsync', 'no href or link');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
static async getIsVisible(commandItem) {
|
|
55
|
+
if (commandItem.isVisible !== undefined) {
|
|
56
|
+
if (typeof commandItem.isVisible === 'boolean') {
|
|
57
|
+
return commandItem.isVisible;
|
|
58
|
+
}
|
|
59
|
+
else if (typeof commandItem.isVisible === 'function') {
|
|
60
|
+
return await commandItem.isVisible();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
static getIsDisabled(commandItem) {
|
|
66
|
+
if (commandItem.isDisabled !== undefined) {
|
|
67
|
+
if (typeof commandItem.isDisabled === 'boolean') {
|
|
68
|
+
return commandItem.isDisabled;
|
|
69
|
+
}
|
|
70
|
+
else if (typeof commandItem.isDisabled === 'function') {
|
|
71
|
+
return commandItem.isDisabled();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
static async getLink(commandItem, data) {
|
|
77
|
+
if (commandItem.link !== undefined) {
|
|
78
|
+
if (typeof commandItem.link === 'string') {
|
|
79
|
+
return CommandBaseService.interpolateString(commandItem.link, data);
|
|
80
|
+
}
|
|
81
|
+
else if (typeof commandItem.link === 'function') {
|
|
82
|
+
return CommandBaseService.interpolateString(await commandItem.link({ commandItem, data }), data);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
static async getHref(commandItem, data) {
|
|
88
|
+
if (commandItem.href !== undefined) {
|
|
89
|
+
if (typeof commandItem.href === 'string') {
|
|
90
|
+
return CommandBaseService.interpolateString(commandItem.href, data);
|
|
91
|
+
}
|
|
92
|
+
else if (typeof commandItem.href === 'function') {
|
|
93
|
+
return CommandBaseService.interpolateString(await commandItem.href({ commandItem, data }), data);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
static async executeClickEvent(commandItem, data) {
|
|
99
|
+
if (commandItem.onClick !== undefined) {
|
|
100
|
+
return await commandItem.onClick({ commandItem, data });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
static interpolateString(template, data) {
|
|
104
|
+
return template?.replace(/{{\s*(\w+)\s*}}/g, (match, propName) => {
|
|
105
|
+
return data && data[propName] !== undefined ? data[propName] : match;
|
|
106
|
+
}) ?? null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
class CommandService extends CommandBaseService {
|
|
111
|
+
options = inject(CommandOptions);
|
|
112
|
+
_drawerItems = new BehaviorSubject([]);
|
|
113
|
+
_commandsMap = new Map();
|
|
114
|
+
// noinspection JSUnusedLocalSymbols
|
|
115
|
+
constructor() {
|
|
116
|
+
const router = inject(Router);
|
|
117
|
+
const commandSettingsService = inject(CommandSettingsService);
|
|
118
|
+
super(commandSettingsService, router);
|
|
119
|
+
}
|
|
120
|
+
// noinspection JSUnusedGlobalSymbols
|
|
121
|
+
async initialize() {
|
|
122
|
+
const items = new Array();
|
|
123
|
+
const commandItems = this.commandSettingsService.commandItems;
|
|
124
|
+
await this.createDrawerItems(commandItems, items, null);
|
|
125
|
+
this._drawerItems.next(items);
|
|
126
|
+
}
|
|
127
|
+
async createDrawerItems(commandItems, items, parentId) {
|
|
128
|
+
for (const commandItem of commandItems) {
|
|
129
|
+
const visible = await CommandBaseService.getIsVisible(commandItem);
|
|
130
|
+
if (!visible) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (commandItem.type === 'separator') {
|
|
134
|
+
items.push({
|
|
135
|
+
id: commandItem.id,
|
|
136
|
+
parentId: parentId ?? undefined,
|
|
137
|
+
separator: true
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
items.push({
|
|
142
|
+
id: commandItem.id,
|
|
143
|
+
parentId: parentId ?? undefined,
|
|
144
|
+
text: commandItem.text,
|
|
145
|
+
selected: commandItem.selected,
|
|
146
|
+
svgIcon: commandItem.svgIcon
|
|
147
|
+
});
|
|
148
|
+
if (commandItem.children) {
|
|
149
|
+
await this.createDrawerItems(commandItem.children, items, commandItem.id);
|
|
150
|
+
}
|
|
151
|
+
this._commandsMap.set(commandItem.id, commandItem);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// noinspection JSUnusedGlobalSymbols
|
|
156
|
+
get drawerItems() {
|
|
157
|
+
return this._drawerItems;
|
|
158
|
+
}
|
|
159
|
+
// noinspection JSUnusedGlobalSymbols
|
|
160
|
+
async setSelectedDrawerItem(value) {
|
|
161
|
+
console.debug('setSelectedDrawerItem', value);
|
|
162
|
+
if (typeof value.id !== "string") {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const commandItem = this._commandsMap.get(value.id);
|
|
166
|
+
if (commandItem === undefined) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
await this.navigateAsync(commandItem);
|
|
170
|
+
}
|
|
171
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CommandService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
172
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CommandService });
|
|
173
|
+
}
|
|
174
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: CommandService, decorators: [{
|
|
175
|
+
type: Injectable
|
|
176
|
+
}], ctorParameters: () => [] });
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Transforms known backend error messages into user-friendly messages.
|
|
180
|
+
* Returns null if the error message is not recognized and should be displayed as-is.
|
|
181
|
+
*/
|
|
182
|
+
function transformErrorMessage(message) {
|
|
183
|
+
if (!message)
|
|
184
|
+
return null;
|
|
185
|
+
// MongoDB E11000 duplicate key error
|
|
186
|
+
if (message.includes('E11000 duplicate key')) {
|
|
187
|
+
return {
|
|
188
|
+
userMessage: 'An entity with this ID already exists. If you are importing data, try using the "Upsert" strategy instead of "Insert Only".',
|
|
189
|
+
technicalDetails: message
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
7
194
|
|
|
8
195
|
class MessageService {
|
|
9
|
-
snackBar = inject(MatSnackBar);
|
|
10
196
|
latestErrorMessage;
|
|
11
197
|
errorMessages;
|
|
198
|
+
// New message stream for all message types
|
|
199
|
+
messageSubject = new Subject();
|
|
200
|
+
messages$ = this.messageSubject.asObservable();
|
|
12
201
|
constructor() {
|
|
13
202
|
this.latestErrorMessage = new BehaviorSubject(null);
|
|
14
203
|
this.errorMessages = new Array();
|
|
@@ -22,251 +211,270 @@ class MessageService {
|
|
|
22
211
|
getLatestErrorMessage() {
|
|
23
212
|
return this.latestErrorMessage.asObservable();
|
|
24
213
|
}
|
|
25
|
-
|
|
26
|
-
console.error(message);
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
214
|
+
showErrorWithDetails(message, details) {
|
|
215
|
+
console.error(`${details}: ${message}`);
|
|
216
|
+
const transformed = transformErrorMessage(message);
|
|
217
|
+
const displayMessage = transformed ? transformed.userMessage : message;
|
|
218
|
+
const displayDetails = transformed
|
|
219
|
+
? (details ? `${details}\n\n${transformed.technicalDetails}` : transformed.technicalDetails)
|
|
220
|
+
: details;
|
|
221
|
+
const notificationMessage = {
|
|
222
|
+
level: "error",
|
|
223
|
+
details: displayDetails,
|
|
224
|
+
message: displayMessage,
|
|
225
|
+
timestamp: new Date()
|
|
30
226
|
};
|
|
31
|
-
this.errorMessages.push(
|
|
32
|
-
this.latestErrorMessage.next(
|
|
227
|
+
this.errorMessages.push(notificationMessage);
|
|
228
|
+
this.latestErrorMessage.next(notificationMessage);
|
|
229
|
+
// Emit to the new message stream
|
|
230
|
+
this.messageSubject.next(notificationMessage);
|
|
33
231
|
}
|
|
34
|
-
|
|
35
|
-
if (error instanceof Error) {
|
|
36
|
-
this.showError(error.message, 'Error');
|
|
37
|
-
}
|
|
38
|
-
else if (error === 'string') {
|
|
39
|
-
this.showError(error, 'Error');
|
|
40
|
-
}
|
|
41
|
-
else if (error instanceof Object) {
|
|
42
|
-
this.showError(JSON.stringify(error), 'Error');
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
this.showError('Unknown error', 'Error');
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
showErrorMessage(message) {
|
|
232
|
+
showError(message) {
|
|
49
233
|
console.error(message);
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
234
|
+
const transformed = transformErrorMessage(message);
|
|
235
|
+
const displayMessage = transformed ? transformed.userMessage : message;
|
|
236
|
+
const displayDetails = transformed ? transformed.technicalDetails : undefined;
|
|
237
|
+
const notificationMessage = {
|
|
238
|
+
level: "error",
|
|
239
|
+
message: displayMessage,
|
|
240
|
+
details: displayDetails,
|
|
241
|
+
timestamp: new Date()
|
|
53
242
|
};
|
|
54
|
-
this.errorMessages.push(
|
|
55
|
-
this.latestErrorMessage.next(
|
|
243
|
+
this.errorMessages.push(notificationMessage);
|
|
244
|
+
this.latestErrorMessage.next(notificationMessage);
|
|
245
|
+
// Emit to the new message stream
|
|
246
|
+
this.messageSubject.next(notificationMessage);
|
|
56
247
|
}
|
|
57
248
|
showInformation(message) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
249
|
+
console.log(message);
|
|
250
|
+
// Emit to the new message stream
|
|
251
|
+
this.messageSubject.next({
|
|
252
|
+
level: 'info',
|
|
253
|
+
message,
|
|
254
|
+
timestamp: new Date()
|
|
63
255
|
});
|
|
64
256
|
}
|
|
65
|
-
|
|
66
|
-
|
|
257
|
+
showSuccess(message) {
|
|
258
|
+
console.log(message);
|
|
259
|
+
// Emit to the new message stream
|
|
260
|
+
this.messageSubject.next({
|
|
261
|
+
level: 'success',
|
|
262
|
+
message,
|
|
263
|
+
timestamp: new Date()
|
|
264
|
+
});
|
|
67
265
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
266
|
+
showWarning(message) {
|
|
267
|
+
console.warn(message);
|
|
268
|
+
// Emit to the new message stream
|
|
269
|
+
this.messageSubject.next({
|
|
270
|
+
level: 'warning',
|
|
271
|
+
message: message,
|
|
272
|
+
timestamp: new Date()
|
|
273
|
+
});
|
|
71
274
|
}
|
|
72
|
-
|
|
73
|
-
|
|
275
|
+
showWarningWithDetails(message, details) {
|
|
276
|
+
console.warn(`${message}: ${details}`);
|
|
277
|
+
// Emit to the new message stream
|
|
278
|
+
this.messageSubject.next({
|
|
279
|
+
level: 'warning',
|
|
280
|
+
details: details,
|
|
281
|
+
message: message,
|
|
282
|
+
timestamp: new Date()
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: MessageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
286
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: MessageService, providedIn: 'root' });
|
|
74
287
|
}
|
|
75
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
76
|
-
type: Injectable
|
|
288
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: MessageService, decorators: [{
|
|
289
|
+
type: Injectable,
|
|
290
|
+
args: [{
|
|
291
|
+
providedIn: 'root'
|
|
292
|
+
}]
|
|
77
293
|
}], ctorParameters: () => [] });
|
|
78
294
|
|
|
79
|
-
class
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
295
|
+
class ComponentMenuService extends CommandBaseService {
|
|
296
|
+
activatedRoute = inject(ActivatedRoute);
|
|
297
|
+
_menuItems = new BehaviorSubject([]);
|
|
298
|
+
constructor() {
|
|
299
|
+
const commandSettingsService = inject(CommandSettingsService);
|
|
300
|
+
const router = inject(Router);
|
|
301
|
+
super(commandSettingsService, router);
|
|
302
|
+
router.events
|
|
303
|
+
.pipe(filter(event => event instanceof NavigationEnd))
|
|
304
|
+
.subscribe(() => {
|
|
305
|
+
this._menuItems.next(this.createNavigationMenu(this.activatedRoute.root));
|
|
306
|
+
});
|
|
307
|
+
this._menuItems.next(this.createNavigationMenu(this.activatedRoute.root));
|
|
308
|
+
}
|
|
309
|
+
// noinspection JSUnusedGlobalSymbols
|
|
310
|
+
get menuItems() {
|
|
311
|
+
return this._menuItems;
|
|
312
|
+
}
|
|
313
|
+
createNavigationMenu(route, path = []) {
|
|
314
|
+
const children = route.children;
|
|
315
|
+
for (const child of children) {
|
|
316
|
+
const commandItems = child.snapshot.data['navigationMenu'];
|
|
317
|
+
if (commandItems) {
|
|
318
|
+
path.push(...this.buildMenuItems(commandItems, child));
|
|
319
|
+
}
|
|
320
|
+
return this.createNavigationMenu(child, path);
|
|
321
|
+
}
|
|
322
|
+
return path;
|
|
323
|
+
}
|
|
324
|
+
// noinspection JSUnusedGlobalSymbols
|
|
325
|
+
async setSelectedMenuItem(value) {
|
|
326
|
+
console.debug('setSelectedMenuItem', value);
|
|
327
|
+
const commandItem = value.data;
|
|
328
|
+
if (!commandItem) {
|
|
99
329
|
return;
|
|
100
330
|
}
|
|
101
|
-
this.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
331
|
+
await this.navigateAsync(commandItem);
|
|
332
|
+
}
|
|
333
|
+
buildMenuItems(commandItems, activatedRoute) {
|
|
334
|
+
const items = new Array();
|
|
335
|
+
for (const commandItem of commandItems) {
|
|
336
|
+
if (commandItem.type === 'separator') {
|
|
337
|
+
items.push({ separator: true });
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
let childMenuItems = undefined;
|
|
341
|
+
if (commandItem.children) {
|
|
342
|
+
childMenuItems = this.buildMenuItems(commandItem.children, activatedRoute);
|
|
343
|
+
}
|
|
344
|
+
let label = commandItem.text;
|
|
345
|
+
if (label) {
|
|
346
|
+
// We replace the label parameters with the actual values from route (use updateBreadcrumbLabels to update the labels with data)
|
|
347
|
+
// noinspection RegExpDuplicateCharacterInClass
|
|
348
|
+
const labelParams = label.match(/[^{{]+(?=}})/g);
|
|
349
|
+
if (labelParams) {
|
|
350
|
+
for (const labelParam of labelParams) {
|
|
351
|
+
const routerParamID = activatedRoute.snapshot.params[labelParam];
|
|
352
|
+
if (routerParamID) {
|
|
353
|
+
label = label.replace('{{' + labelParam + '}}', routerParamID);
|
|
354
|
+
}
|
|
117
355
|
}
|
|
118
356
|
}
|
|
119
357
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
catch (err) {
|
|
129
|
-
console.error('Error reading NFC tag: ', err);
|
|
130
|
-
this.nfcStatusSubject.next('Error starting NFC scan.');
|
|
131
|
-
onError('Error starting NFC scan.');
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
stopScan() {
|
|
135
|
-
if (this.abortController) {
|
|
136
|
-
this.abortController.abort();
|
|
137
|
-
this.abortController = null;
|
|
138
|
-
this.ndef = null;
|
|
139
|
-
this.nfcStatusSubject.next('NFC scan stopped.');
|
|
358
|
+
items.push({
|
|
359
|
+
text: label,
|
|
360
|
+
svgIcon: commandItem.svgIcon,
|
|
361
|
+
data: commandItem,
|
|
362
|
+
items: childMenuItems
|
|
363
|
+
});
|
|
364
|
+
}
|
|
140
365
|
}
|
|
366
|
+
return items;
|
|
141
367
|
}
|
|
142
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
143
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
368
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ComponentMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
369
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ComponentMenuService });
|
|
144
370
|
}
|
|
145
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: ComponentMenuService, decorators: [{
|
|
146
372
|
type: Injectable
|
|
147
373
|
}], ctorParameters: () => [] });
|
|
148
374
|
|
|
149
|
-
class
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
375
|
+
class BreadCrumbService {
|
|
376
|
+
activatedRoute = inject(ActivatedRoute);
|
|
377
|
+
router = inject(Router);
|
|
378
|
+
_breadCrumbItems = new BehaviorSubject([]);
|
|
379
|
+
constructor() {
|
|
380
|
+
this.router.events
|
|
381
|
+
.pipe(filter(event => event instanceof NavigationEnd))
|
|
382
|
+
.subscribe(() => {
|
|
383
|
+
this._breadCrumbItems.next(this.createBreadCrumbs(this.activatedRoute.root));
|
|
384
|
+
});
|
|
385
|
+
this._breadCrumbItems.next(this.createBreadCrumbs(this.activatedRoute.root));
|
|
386
|
+
}
|
|
387
|
+
createBreadCrumbs(route, path = []) {
|
|
388
|
+
const children = route.children;
|
|
389
|
+
for (const child of children) {
|
|
390
|
+
const breadCrumbRouteItems = child.snapshot.data['breadcrumb'];
|
|
391
|
+
if (breadCrumbRouteItems) {
|
|
392
|
+
for (const breadCrumbRouteItem of breadCrumbRouteItems) {
|
|
393
|
+
let label = breadCrumbRouteItem.label;
|
|
394
|
+
let url = breadCrumbRouteItem.url;
|
|
395
|
+
// We replace the route parameters with the actual values
|
|
396
|
+
// Match all :paramName patterns in the URL
|
|
397
|
+
const paramMatches = url.match(/:([a-zA-Z0-9_]+)/g);
|
|
398
|
+
if (paramMatches) {
|
|
399
|
+
for (const match of paramMatches) {
|
|
400
|
+
const paramName = match.substring(1); // Remove leading ':'
|
|
401
|
+
const paramValue = child.snapshot.params[paramName];
|
|
402
|
+
if (paramValue) {
|
|
403
|
+
url = url.replace(match, paramValue);
|
|
404
|
+
}
|
|
174
405
|
}
|
|
175
406
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
407
|
+
// We replace the label parameters with the actual values from route (use updateBreadcrumbLabels to update the labels with data)
|
|
408
|
+
// noinspection RegExpDuplicateCharacterInClass
|
|
409
|
+
const labelParams = label.match(/[^{{]+(?=}})/g);
|
|
410
|
+
if (labelParams) {
|
|
411
|
+
for (const labelParam of labelParams) {
|
|
412
|
+
const routerParamID = child.snapshot.params[labelParam];
|
|
413
|
+
if (routerParamID) {
|
|
414
|
+
label = label.replace('{{' + labelParam + '}}', routerParamID);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
180
417
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
418
|
+
path.push({
|
|
419
|
+
text: label,
|
|
420
|
+
title: label,
|
|
421
|
+
labelTemplate: breadCrumbRouteItem.label,
|
|
422
|
+
svgIcon: breadCrumbRouteItem.svgIcon,
|
|
423
|
+
url: url
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return this.createBreadCrumbs(child, path);
|
|
190
428
|
}
|
|
429
|
+
return path;
|
|
191
430
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
431
|
+
/*
|
|
432
|
+
* This method updates the breadcrumb labels with the data passed in the parameter. Parameters are passed in the label as {{paramName}}
|
|
433
|
+
*/
|
|
434
|
+
// noinspection JSUnusedGlobalSymbols
|
|
435
|
+
async updateBreadcrumbLabels(data) {
|
|
436
|
+
const list = await firstValueFrom(this._breadCrumbItems);
|
|
437
|
+
for (const breadCrumbDataItem of list) {
|
|
438
|
+
// noinspection RegExpDuplicateCharacterInClass
|
|
439
|
+
const labelParams = breadCrumbDataItem.labelTemplate.match(/[^{{]+(?=}})/g);
|
|
440
|
+
if (labelParams) {
|
|
441
|
+
for (const labelParam of labelParams) {
|
|
442
|
+
const value = data[labelParam];
|
|
443
|
+
if (!value) {
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
breadCrumbDataItem.title = breadCrumbDataItem.labelTemplate.replace('{{' + labelParam + '}}', data[labelParam]);
|
|
447
|
+
breadCrumbDataItem.text = breadCrumbDataItem.title;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
196
450
|
}
|
|
197
451
|
}
|
|
198
|
-
|
|
199
|
-
|
|
452
|
+
// noinspection JSUnusedGlobalSymbols
|
|
453
|
+
get breadCrumbItems() {
|
|
454
|
+
return this._breadCrumbItems;
|
|
455
|
+
}
|
|
456
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BreadCrumbService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
457
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BreadCrumbService });
|
|
200
458
|
}
|
|
201
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
459
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: BreadCrumbService, decorators: [{
|
|
202
460
|
type: Injectable
|
|
203
|
-
}] });
|
|
461
|
+
}], ctorParameters: () => [] });
|
|
204
462
|
|
|
205
|
-
class
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
AT30: 'ATMA',
|
|
210
|
-
DE20: 'DEHE',
|
|
211
|
-
PL91: 'POGL',
|
|
212
|
-
};
|
|
213
|
-
/**
|
|
214
|
-
* Parses a MACO scheme URL and extracts a mapped location code and machine ID from the last URL segment.
|
|
215
|
-
*
|
|
216
|
-
* @param url - The URL to parse.
|
|
217
|
-
* @returns A `ParseResponse` containing:
|
|
218
|
-
* - `success: true` with extracted location and machine ID if parsing is successful.
|
|
219
|
-
* - `success: false` with an error message if the input is invalid or cannot be parsed.
|
|
220
|
-
*/
|
|
221
|
-
parseUrl(url) {
|
|
222
|
-
if (!url || url.trim() === '') {
|
|
223
|
-
return {
|
|
224
|
-
success: false,
|
|
225
|
-
message: 'The URL is empty. Please enter a valid URL.'
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
// Extract last path segment
|
|
229
|
-
const parts = url.split('/');
|
|
230
|
-
const lastSegment = parts.pop() || '';
|
|
231
|
-
if (!lastSegment) {
|
|
232
|
-
return {
|
|
233
|
-
success: false,
|
|
234
|
-
message: 'URL does not contain a valid last segment.'
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
if (lastSegment.length < 4) {
|
|
238
|
-
return {
|
|
239
|
-
success: false,
|
|
240
|
-
message: 'The last segment format is invalid or too short.'
|
|
241
|
-
};
|
|
242
|
-
}
|
|
243
|
-
const locationCode = lastSegment.substring(0, 4); // e.g. 'AT10'
|
|
244
|
-
const machineCode = lastSegment.substring(4); // e.g. 'MAFEB2'
|
|
245
|
-
if (!this.locationMap[locationCode]) {
|
|
246
|
-
return {
|
|
247
|
-
success: false,
|
|
248
|
-
message: 'Location code is not recognized or supported.'
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
if (!machineCode || machineCode.trim() === '') {
|
|
252
|
-
return {
|
|
253
|
-
success: false,
|
|
254
|
-
message: 'Machine identifier is missing.'
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
return {
|
|
258
|
-
success: true,
|
|
259
|
-
message: `Successfully parsed URL: location=${this.locationMap[locationCode]}, machine=${machineCode}`,
|
|
260
|
-
data: {
|
|
261
|
-
location: this.locationMap[locationCode],
|
|
262
|
-
machineId: machineCode,
|
|
263
|
-
}
|
|
264
|
-
};
|
|
463
|
+
class AppTitleService {
|
|
464
|
+
_appTitle = new BehaviorSubject(null);
|
|
465
|
+
setTitle(title) {
|
|
466
|
+
this._appTitle.next(title);
|
|
265
467
|
}
|
|
266
|
-
|
|
267
|
-
|
|
468
|
+
getTitle() {
|
|
469
|
+
return this._appTitle.value;
|
|
470
|
+
}
|
|
471
|
+
get appTitle() {
|
|
472
|
+
return this._appTitle.asObservable();
|
|
473
|
+
}
|
|
474
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AppTitleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
475
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AppTitleService });
|
|
268
476
|
}
|
|
269
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
477
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AppTitleService, decorators: [{
|
|
270
478
|
type: Injectable
|
|
271
479
|
}] });
|
|
272
480
|
|
|
@@ -275,7 +483,7 @@ class MmHttpErrorInterceptor {
|
|
|
275
483
|
intercept(request, next) {
|
|
276
484
|
return next.handle(request).pipe(retry(0), catchError((error) => {
|
|
277
485
|
if (error.status === 0) {
|
|
278
|
-
this.messageService.showError('Cannot connect to server. Please check your network connection or if the server is down.'
|
|
486
|
+
this.messageService.showError('Cannot connect to server. Please check your network connection or if the server is down.');
|
|
279
487
|
}
|
|
280
488
|
if (error.status === 400 && error.error.statusCode) {
|
|
281
489
|
const apiError = error.error;
|
|
@@ -287,75 +495,33 @@ class MmHttpErrorInterceptor {
|
|
|
287
495
|
}
|
|
288
496
|
}
|
|
289
497
|
}
|
|
290
|
-
this.messageService.
|
|
498
|
+
this.messageService.showErrorWithDetails(details, apiError.message);
|
|
291
499
|
}
|
|
292
500
|
return throwError(() => error);
|
|
293
501
|
}));
|
|
294
502
|
}
|
|
295
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
296
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
503
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: MmHttpErrorInterceptor, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
504
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: MmHttpErrorInterceptor });
|
|
297
505
|
}
|
|
298
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
506
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: MmHttpErrorInterceptor, decorators: [{
|
|
299
507
|
type: Injectable
|
|
300
508
|
}] });
|
|
301
509
|
|
|
302
|
-
class
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SharedServicesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
310
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.12", ngImport: i0, type: SharedServicesModule });
|
|
311
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SharedServicesModule });
|
|
312
|
-
}
|
|
313
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: SharedServicesModule, decorators: [{
|
|
314
|
-
type: NgModule,
|
|
315
|
-
args: [{
|
|
316
|
-
declarations: [],
|
|
317
|
-
imports: [],
|
|
318
|
-
exports: []
|
|
319
|
-
}]
|
|
320
|
-
}] });
|
|
321
|
-
|
|
322
|
-
class BreadcrumbService {
|
|
323
|
-
_breadcrumbLabels;
|
|
324
|
-
_newBreadcrumb;
|
|
325
|
-
constructor() {
|
|
326
|
-
this._breadcrumbLabels = new BehaviorSubject([]);
|
|
327
|
-
this._newBreadcrumb = new BehaviorSubject([]);
|
|
328
|
-
}
|
|
329
|
-
get breadcrumbLabels() {
|
|
330
|
-
return this._breadcrumbLabels;
|
|
510
|
+
class BreadCrumbData {
|
|
511
|
+
constructor(label, labelTemplate, url) {
|
|
512
|
+
this.text = label;
|
|
513
|
+
this.labelTemplate = labelTemplate;
|
|
514
|
+
this.url = url;
|
|
331
515
|
}
|
|
332
|
-
|
|
333
|
-
return this._newBreadcrumb;
|
|
334
|
-
}
|
|
335
|
-
updateBreadcrumbLabels(labels) {
|
|
336
|
-
this.breadcrumbLabels.next(labels);
|
|
337
|
-
}
|
|
338
|
-
updateBreadcrumb(newBreadcrumb) {
|
|
339
|
-
this.newBreadcrumb.next(newBreadcrumb);
|
|
340
|
-
}
|
|
341
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BreadcrumbService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
342
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BreadcrumbService, providedIn: 'root' });
|
|
343
|
-
}
|
|
344
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: BreadcrumbService, decorators: [{
|
|
345
|
-
type: Injectable,
|
|
346
|
-
args: [{
|
|
347
|
-
providedIn: 'root'
|
|
348
|
-
}]
|
|
349
|
-
}], ctorParameters: () => [] });
|
|
350
|
-
|
|
351
|
-
class AutoCompleteResult {
|
|
352
|
-
searchTerm;
|
|
353
|
-
list;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
class ErrorMessage {
|
|
516
|
+
text;
|
|
357
517
|
title;
|
|
358
|
-
|
|
518
|
+
disabled;
|
|
519
|
+
icon;
|
|
520
|
+
svgIcon;
|
|
521
|
+
iconClass;
|
|
522
|
+
imageUrl;
|
|
523
|
+
labelTemplate;
|
|
524
|
+
url;
|
|
359
525
|
}
|
|
360
526
|
|
|
361
527
|
class PagedResultDto {
|
|
@@ -371,14 +537,67 @@ class PagedResultDto {
|
|
|
371
537
|
}
|
|
372
538
|
}
|
|
373
539
|
|
|
540
|
+
class TreeItemDataTyped {
|
|
541
|
+
_id;
|
|
542
|
+
_text;
|
|
543
|
+
_tooltip;
|
|
544
|
+
_item;
|
|
545
|
+
_svgIcon;
|
|
546
|
+
_isExpandable;
|
|
547
|
+
_isExpanded;
|
|
548
|
+
constructor(_id, _text, _tooltip, _item, _svgIcon, expandable = false, isExpanded = false) {
|
|
549
|
+
this._id = _id;
|
|
550
|
+
this._text = _text;
|
|
551
|
+
this._tooltip = _tooltip;
|
|
552
|
+
this._item = _item;
|
|
553
|
+
this._svgIcon = _svgIcon;
|
|
554
|
+
this._isExpandable = expandable;
|
|
555
|
+
this._isExpanded = expandable && isExpanded;
|
|
556
|
+
}
|
|
557
|
+
get id() {
|
|
558
|
+
return this._id;
|
|
559
|
+
}
|
|
560
|
+
get text() {
|
|
561
|
+
return this._text;
|
|
562
|
+
}
|
|
563
|
+
get tooltip() {
|
|
564
|
+
return this._tooltip;
|
|
565
|
+
}
|
|
566
|
+
get item() {
|
|
567
|
+
return this._item;
|
|
568
|
+
}
|
|
569
|
+
get svgIcon() {
|
|
570
|
+
return this._svgIcon;
|
|
571
|
+
}
|
|
572
|
+
get expandable() {
|
|
573
|
+
return this._isExpandable;
|
|
574
|
+
}
|
|
575
|
+
set expandable(value) {
|
|
576
|
+
this._isExpandable = value;
|
|
577
|
+
}
|
|
578
|
+
get isExpanded() {
|
|
579
|
+
return this._isExpanded;
|
|
580
|
+
}
|
|
581
|
+
set isExpanded(value) {
|
|
582
|
+
this._isExpanded = value;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Legacy DataSourceBase class for backward compatibility with libraries
|
|
588
|
+
* that import DataSourceBase from @meshmakers/shared-services.
|
|
589
|
+
*
|
|
590
|
+
* In the Refinery Studio version, DataSourceBase moved to @meshmakers/shared-ui.
|
|
591
|
+
* This re-export ensures old compiled libraries (octo-services, etc.) continue to work.
|
|
592
|
+
*/
|
|
374
593
|
class DataSourceBase {
|
|
375
594
|
dataSubject = new BehaviorSubject([]);
|
|
376
595
|
loadingSubject = new BehaviorSubject(false);
|
|
377
596
|
totalCountSubject = new BehaviorSubject(0);
|
|
378
597
|
loading$ = this.loadingSubject.asObservable();
|
|
379
598
|
totalCount$ = this.totalCountSubject.asObservable();
|
|
380
|
-
addedDtoList =
|
|
381
|
-
removedDtoList =
|
|
599
|
+
addedDtoList = [];
|
|
600
|
+
removedDtoList = [];
|
|
382
601
|
lastPagedResult = null;
|
|
383
602
|
get totalCount() {
|
|
384
603
|
return this.totalCount$;
|
|
@@ -413,10 +632,10 @@ class DataSourceBase {
|
|
|
413
632
|
get removedTemporaryDtos() {
|
|
414
633
|
return this.removedDtoList;
|
|
415
634
|
}
|
|
416
|
-
connect(
|
|
635
|
+
connect(_collectionViewer) {
|
|
417
636
|
return this.dataSubject.asObservable();
|
|
418
637
|
}
|
|
419
|
-
disconnect(
|
|
638
|
+
disconnect(_collectionViewer) {
|
|
420
639
|
this.clear();
|
|
421
640
|
}
|
|
422
641
|
clear() {
|
|
@@ -433,7 +652,7 @@ class DataSourceBase {
|
|
|
433
652
|
}
|
|
434
653
|
onEndLoad() {
|
|
435
654
|
if (this.lastPagedResult !== null) {
|
|
436
|
-
const totalCount = this.lastPagedResult
|
|
655
|
+
const totalCount = this.lastPagedResult.totalCount + this.addedDtoList.length - this.removedDtoList.length;
|
|
437
656
|
const list = this.lastPagedResult.list.concat(this.addedDtoList).filter((x) => !this.removedDtoList.includes(x));
|
|
438
657
|
this.loadingSubject?.next(false);
|
|
439
658
|
this.dataSubject?.next(list);
|
|
@@ -449,104 +668,120 @@ class DataSourceBase {
|
|
|
449
668
|
}
|
|
450
669
|
}
|
|
451
670
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
this.data = data;
|
|
457
|
-
this.dataSubject.next(data);
|
|
458
|
-
}
|
|
459
|
-
emitChanged() {
|
|
460
|
-
this.dataSubject.next(this.data);
|
|
461
|
-
}
|
|
462
|
-
connect(_) {
|
|
463
|
-
return this.dataSubject.asObservable();
|
|
464
|
-
}
|
|
465
|
-
disconnect(_) {
|
|
466
|
-
this.dataSubject.complete();
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
671
|
+
/**
|
|
672
|
+
* Legacy IsoDateTime utility class for backward compatibility.
|
|
673
|
+
* Uses native Date API instead of date-fns.
|
|
674
|
+
*/
|
|
470
675
|
class IsoDateTime {
|
|
471
676
|
static utcToLocalDateTimeIso(utcDateTime) {
|
|
472
677
|
if (!utcDateTime) {
|
|
473
678
|
return null;
|
|
474
679
|
}
|
|
475
|
-
return
|
|
680
|
+
return new Date(utcDateTime).toISOString();
|
|
476
681
|
}
|
|
477
682
|
static localToUtcDateTimeIso(localDateTime) {
|
|
478
683
|
if (!localDateTime) {
|
|
479
684
|
return null;
|
|
480
685
|
}
|
|
481
|
-
return
|
|
686
|
+
return new Date(localDateTime).toISOString();
|
|
482
687
|
}
|
|
483
688
|
static currentUtcDateTimeIso() {
|
|
484
|
-
return
|
|
689
|
+
return new Date().toISOString();
|
|
485
690
|
}
|
|
486
691
|
}
|
|
487
692
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
getNamesAndValues() {
|
|
498
|
-
return this.getNames().map((n) => {
|
|
499
|
-
return { name: this.value[n], id: n };
|
|
500
|
-
});
|
|
501
|
-
}
|
|
502
|
-
getNames() {
|
|
503
|
-
return Object.keys(this.value);
|
|
504
|
-
}
|
|
505
|
-
getObjValues() {
|
|
506
|
-
return Object.keys(this.value).map((k) => this.value[k]);
|
|
693
|
+
/**
|
|
694
|
+
* Legacy QrCodeScannerService for backward compatibility.
|
|
695
|
+
*/
|
|
696
|
+
class QrCodeScannerService {
|
|
697
|
+
stream = null;
|
|
698
|
+
async isSupported() {
|
|
699
|
+
const BarcodeDetectorClass = window.BarcodeDetector;
|
|
700
|
+
return !!BarcodeDetectorClass &&
|
|
701
|
+
await BarcodeDetectorClass.getSupportedFormats().then((formats) => formats.includes('qr_code'));
|
|
507
702
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
703
|
+
async scan(video) {
|
|
704
|
+
const BarcodeDetectorClass = window.BarcodeDetector;
|
|
705
|
+
const detector = new BarcodeDetectorClass({ formats: ['qr_code'] });
|
|
706
|
+
try {
|
|
707
|
+
this.stream = await navigator.mediaDevices.getUserMedia({
|
|
708
|
+
video: { facingMode: 'environment' }
|
|
709
|
+
});
|
|
710
|
+
video.srcObject = this.stream;
|
|
711
|
+
await video.play();
|
|
712
|
+
return new Promise((resolve, reject) => {
|
|
713
|
+
const detectLoop = async () => {
|
|
714
|
+
try {
|
|
715
|
+
const barcodes = await detector.detect(video);
|
|
716
|
+
if (barcodes.length > 0) {
|
|
717
|
+
this.stop();
|
|
718
|
+
resolve(barcodes[0].rawValue);
|
|
719
|
+
return;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
catch (err) {
|
|
723
|
+
this.stop();
|
|
724
|
+
reject(err);
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
requestAnimationFrame(detectLoop);
|
|
728
|
+
};
|
|
729
|
+
detectLoop();
|
|
519
730
|
});
|
|
520
731
|
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
const clonedObject = Object.assign({}, source);
|
|
525
|
-
if (ignoreProperties != null) {
|
|
526
|
-
for (const prop of ignoreProperties) {
|
|
527
|
-
delete clonedObject[prop];
|
|
528
|
-
}
|
|
732
|
+
catch (err) {
|
|
733
|
+
this.stop();
|
|
734
|
+
throw err;
|
|
529
735
|
}
|
|
530
|
-
return clonedObject;
|
|
531
736
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
delete clonedObject[prop];
|
|
537
|
-
}
|
|
737
|
+
stop() {
|
|
738
|
+
if (this.stream) {
|
|
739
|
+
this.stream.getTracks().forEach(track => track.stop());
|
|
740
|
+
this.stream = null;
|
|
538
741
|
}
|
|
539
|
-
return clonedObject;
|
|
540
742
|
}
|
|
743
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: QrCodeScannerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
744
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: QrCodeScannerService });
|
|
745
|
+
}
|
|
746
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: QrCodeScannerService, decorators: [{
|
|
747
|
+
type: Injectable
|
|
748
|
+
}] });
|
|
749
|
+
|
|
750
|
+
/**
|
|
751
|
+
* Legacy ErrorMessage class for backward compatibility.
|
|
752
|
+
*/
|
|
753
|
+
class ErrorMessage {
|
|
754
|
+
title;
|
|
755
|
+
message;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
class AutoCompleteResult {
|
|
759
|
+
searchTerm;
|
|
760
|
+
list;
|
|
541
761
|
}
|
|
542
762
|
|
|
543
763
|
/*
|
|
544
764
|
* Public API Surface of shared-services
|
|
545
765
|
*/
|
|
766
|
+
function provideMmSharedServices(commandOptions) {
|
|
767
|
+
return makeEnvironmentProviders([
|
|
768
|
+
MessageService,
|
|
769
|
+
CommandService,
|
|
770
|
+
CommandSettingsService,
|
|
771
|
+
ComponentMenuService,
|
|
772
|
+
AppTitleService,
|
|
773
|
+
MmHttpErrorInterceptor,
|
|
774
|
+
BreadCrumbService,
|
|
775
|
+
{
|
|
776
|
+
provide: CommandOptions,
|
|
777
|
+
useValue: commandOptions
|
|
778
|
+
}
|
|
779
|
+
]);
|
|
780
|
+
}
|
|
546
781
|
|
|
547
782
|
/**
|
|
548
783
|
* Generated bundle index. Do not edit.
|
|
549
784
|
*/
|
|
550
785
|
|
|
551
|
-
export { AutoCompleteResult,
|
|
786
|
+
export { AppTitleService, AutoCompleteResult, BreadCrumbData, BreadCrumbService, BreadCrumbService as BreadcrumbService, CommandBaseService, CommandOptions, CommandService, CommandSettingsService, ComponentMenuService, DataSourceBase, ErrorMessage, IsoDateTime, MessageService, MmHttpErrorInterceptor, PagedResultDto, QrCodeScannerService, TreeItemDataTyped, provideMmSharedServices };
|
|
552
787
|
//# sourceMappingURL=meshmakers-shared-services.mjs.map
|