@dotglitch/ngx-common 1.0.18 → 1.0.20

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.
@@ -1,22 +1,22 @@
1
1
  import { __awaiter } from 'tslib';
2
2
  import * as i0 from '@angular/core';
3
- import { TemplateRef, Component, Optional, Inject, Input, HostListener, Directive, EventEmitter, Output, Pipe, Injectable, isDevMode, InjectionToken, ViewContainerRef, ViewChild, NgModule } from '@angular/core';
3
+ import { TemplateRef, Component, Optional, Inject, Input, HostListener, Directive, EventEmitter, Output, Pipe, Injectable, InjectionToken, isDevMode, ViewContainerRef, ViewChild, NgModule } from '@angular/core';
4
4
  import * as i1 from '@angular/material/dialog';
5
5
  import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
6
6
  import * as i2 from '@angular/common';
7
7
  import { CommonModule, NgTemplateOutlet, NgIf, NgForOf, DOCUMENT, NgComponentOutlet } from '@angular/common';
8
8
  import * as i1$1 from '@angular/platform-browser';
9
9
  import { createApplication } from '@angular/platform-browser';
10
- import { firstValueFrom, of, Subject, BehaviorSubject, debounceTime } from 'rxjs';
10
+ import { firstValueFrom, debounceTime, of, Subject, BehaviorSubject } from 'rxjs';
11
11
  import * as i4 from '@angular/material/icon';
12
12
  import { MatIconModule } from '@angular/material/icon';
13
13
  import * as i5 from '@angular/material/progress-spinner';
14
14
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
15
15
  import * as i2$1 from '@angular/cdk/portal';
16
16
  import { ComponentPortal, PortalModule } from '@angular/cdk/portal';
17
+ import * as i2$2 from '@angular/cdk/dialog';
17
18
  import { retry } from 'rxjs/operators';
18
19
  import * as i1$2 from '@angular/common/http';
19
- import * as i2$2 from '@angular/cdk/dialog';
20
20
 
21
21
  /**
22
22
  * This utils file exists outside of the strict angular DI zone
@@ -615,7 +615,7 @@ class MenuComponent {
615
615
  position: cords,
616
616
  panelClass: ["ngx-menu", "ngx-app-menu"].concat(((_a = this.config) === null || _a === void 0 ? void 0 : _a.customClass) || []),
617
617
  backdropClass: "ngx-menu-backdrop",
618
- hasBackdrop: !hideBackdrop,
618
+ hasBackdrop: false,
619
619
  data: {
620
620
  data: this.data,
621
621
  parentCords: (_d = (_c = (_b = this.viewContainer) === null || _b === void 0 ? void 0 : _b.element) === null || _c === void 0 ? void 0 : _c.nativeElement) === null || _d === void 0 ? void 0 : _d.getBoundingClientRect(),
@@ -1057,409 +1057,65 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
1057
1057
  }] }];
1058
1058
  } });
1059
1059
 
1060
- const { log: log$1, warn: warn$1, err: err$1 } = Logger("DialogService", "#607d8b");
1061
- class DialogService {
1062
- constructor(dialog, lazyLoader) {
1063
- this.dialog = dialog;
1064
- this.lazyLoader = lazyLoader;
1065
- this.dialogs = [];
1066
- }
1067
- open(name, groupOrOptions, opts = {}) {
1068
- const group = typeof groupOrOptions == "string" ? groupOrOptions : 'default';
1069
- if (typeof groupOrOptions == 'object')
1070
- opts = groupOrOptions;
1071
- return new Promise((resolve, reject) => {
1072
- const registration = this.lazyLoader.resolveRegistrationEntry(name, group);
1073
- if (!registration)
1074
- return reject(new Error("Cannot open dialog for " + name + ". Could not find in registry."));
1075
- const args = Object.assign(Object.assign({ closeOnNavigation: true, restoreFocus: true, width: registration['width'], height: registration['height'] }, opts), { data: {
1076
- id: name,
1077
- inputs: opts.inputs || {},
1078
- outputs: opts.outputs || {},
1079
- group: group
1080
- }, panelClass: [
1081
- "dialog-" + name,
1082
- ...(Array.isArray(opts.panelClass) ? opts.panelClass : [opts.panelClass] || [])
1083
- ] });
1084
- // TODO:
1085
- let dialog = this.dialog.open(undefined, args);
1086
- dialog['idx'] = name;
1087
- this.dialogs.push(dialog);
1088
- dialog.afterClosed().subscribe(result => {
1089
- log$1("Dialog closed " + name, result);
1090
- resolve(result);
1091
- });
1092
- });
1093
- }
1094
- // Close all dialogs matching the given name
1095
- close(name) {
1096
- const dialogs = this.dialogs.filter(d => d['idx'] == name);
1097
- dialogs.forEach(dialog => dialog.close());
1098
- }
1099
- /**
1100
- * Method to close _all_ dialogs.
1101
- * Should be used sparingly.
1102
- */
1103
- clearDialog() {
1104
- this.dialogs.forEach(dialog => dialog.close());
1105
- }
1106
- }
1107
- DialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DialogService, deps: [{ token: i1.MatDialog }, { token: LazyLoaderService }], target: i0.ɵɵFactoryTarget.Injectable });
1108
- DialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DialogService, providedIn: 'root' });
1109
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DialogService, decorators: [{
1110
- type: Injectable,
1111
- args: [{
1112
- providedIn: 'root'
1113
- }]
1114
- }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: LazyLoaderService }]; } });
1115
-
1116
- // Total number of _retries_ if there is a 429 response code.
1117
- const retryCount = 2;
1118
- class Fetch {
1119
- constructor(http) {
1120
- this.http = http;
1121
- }
1122
- // Public interface for making AJAX transactions
1123
- get(url, options = {}, returnError = false) {
1124
- return this.request("get", url, options, returnError);
1125
- }
1126
- put(url, body, options = {}, returnError = false) {
1127
- options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
1128
- return this.request("put", url, options, returnError);
1129
- }
1130
- post(url, body, options = {}, returnError = false) {
1131
- options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
1132
- return this.request("post", url, options, returnError);
1133
- }
1134
- patch(url, body, options = {}, returnError = false) {
1135
- options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
1136
- return this.request("patch", url, options, returnError);
1137
- }
1138
- delete(url, options = {}, returnError = false) {
1139
- return this.request("delete", url, options, returnError);
1140
- }
1141
- // Internally, handle the observable as a promise.
1142
- request(method, url, options = {}, returnError = false) {
1143
- options.reportProgress = true;
1144
- // Allow support for different response types.
1145
- // Generally we shouldn't need this to be anything other than JSON.
1146
- options.responseType = options.responseType || "json";
1147
- options.withCredentials = true;
1148
- const p = new Promise((resolve, reject) => {
1149
- const o = this.http.request(method, url, options)
1150
- .pipe(retry({
1151
- delay(error, retryCount) {
1152
- // 429 and 502 are most common for overloaded
1153
- // backends -- so we'll retry if we get these errors
1154
- if (error.status == 429 || error.status == 502)
1155
- return of({});
1156
- if (error.status == 504 && isDevMode())
1157
- alert("It looks like you can't reach your development backend anymore");
1158
- throw error;
1159
- },
1160
- count: retryCount
1161
- }))
1162
- .subscribe(data => {
1163
- resolve(data);
1164
- // provide 3ms slacktime before releasing observable.
1165
- setTimeout(() => {
1166
- o.unsubscribe();
1167
- }, 3);
1168
- });
1169
- });
1170
- return p;
1171
- }
1172
- }
1173
- Fetch.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: Fetch, deps: [{ token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
1174
- Fetch.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: Fetch, providedIn: "root" });
1175
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: Fetch, decorators: [{
1176
- type: Injectable,
1177
- args: [{
1178
- providedIn: "root"
1179
- }]
1180
- }], ctorParameters: function () { return [{ type: i1$2.HttpClient }]; } });
1181
-
1182
- /**
1183
- * Service that listens for global keyboard events
1184
- */
1185
- class KeyboardService {
1186
- constructor() {
1187
- this.heldKeys = {};
1188
- this.keyCommands = [];
1189
- window.addEventListener("keydown", (evt) => this.onKeyDown(evt));
1190
- window.addEventListener("keyup", (evt) => this.onKeyUp(evt));
1191
- }
1192
- onKeyDown(evt) {
1193
- // console.log("keydown", evt.key)
1194
- this.heldKeys[evt.key.toLowerCase()] = true;
1195
- // Do a general filter where all of the modifiers must be matched if specified
1196
- // Then check that the actual keys match what was specified
1197
- let commands = this.keyCommands
1198
- .filter(kc => {
1199
- var _a;
1200
- return (kc.ctrl == undefined || kc.ctrl === evt.ctrlKey) &&
1201
- (kc.alt == undefined || kc.alt === evt.altKey) &&
1202
- (kc.shift == undefined || kc.shift === evt.shiftKey) &&
1203
- (kc.super == undefined || kc.super === evt.metaKey) &&
1204
- kc.keys.length == ((_a = kc.keys.filter(k => this.heldKeys[k])) === null || _a === void 0 ? void 0 : _a.length);
1205
- });
1206
- if (evt.ctrlKey && commands.length > 0 || commands.find(c => c.interrupt)) {
1207
- evt.stopPropagation();
1208
- evt.preventDefault();
1209
- }
1210
- if (evt.key == "Pause")
1211
- debugger;
1212
- commands.forEach(kc => kc.sub.next(evt));
1213
- /**
1214
- * Prevent CTRL+P and other standard key events from being handled by the browser.
1215
- * Allow specific combonations:
1216
- * CTRL+W
1217
- * CTRL+T
1218
- * CTRL+F5
1219
- */
1220
- // if (evt.ctrlKey && !['w', 't', 'F5'].includes(evt.key)) {
1221
- // evt.preventDefault();
1222
- // }
1223
- }
1224
- onKeyUp(evt) {
1225
- this.heldKeys[evt.key.toLowerCase()] = false;
1226
- }
1227
- onKeyPress(evt) {
1228
- // this.heldKeys[evt.key] = false;
1229
- }
1060
+ var ComponentResolveStrategy;
1061
+ (function (ComponentResolveStrategy) {
1230
1062
  /**
1231
- * Use this to subscribe to keyboard events throughout
1232
- * the application. This is a passive listener and will
1233
- * **NOT** interrupt the event chain.
1063
+ * Match the fist component we find
1064
+ * (best used for standalone components)
1065
+ * @default
1234
1066
  */
1235
- onKeyCommand(key) {
1236
- const sub = new Subject();
1237
- let item = Object.assign(Object.assign({}, key), { keys: (Array.isArray(key.key) ? key.key : [key.key]), sub: sub });
1238
- this.keyCommands.push(item);
1239
- return Object.assign(Object.assign({}, sub), { subscribe: ((...args) => {
1240
- const s = sub.subscribe(...args);
1241
- return Object.assign(Object.assign({}, s), { unsubscribe: () => {
1242
- s.unsubscribe();
1243
- // Remove the keycommand from the list of listeners.
1244
- const i = this.keyCommands.findIndex(c => c == item);
1245
- this.keyCommands.splice(i, 1);
1246
- } });
1247
- }) });
1248
- }
1067
+ ComponentResolveStrategy[ComponentResolveStrategy["PickFirst"] = 0] = "PickFirst";
1249
1068
  /**
1250
- * Return `true` if shift is currently pressed.
1069
+ * Perform an Exact ID to Classname of the Component
1070
+ * case sensitive, zero tolerance.
1251
1071
  */
1252
- get isShiftPressed() {
1253
- return !!this.heldKeys["shift"];
1254
- }
1072
+ ComponentResolveStrategy[ComponentResolveStrategy["MatchIdToClassName"] = 1] = "MatchIdToClassName";
1255
1073
  /**
1256
- * Return `true` if ctrl is currently pressed.
1074
+ * Perform a fuzzy ID to classname match
1075
+ * case insensitive, mutes symbols
1076
+ * ignores "Component" and "Module" postfixes on class
1077
+ * names
1257
1078
  */
1258
- get isCtrlPressed() {
1259
- return !!this.heldKeys["control"];
1260
- }
1079
+ ComponentResolveStrategy[ComponentResolveStrategy["FuzzyIdClassName"] = 2] = "FuzzyIdClassName";
1261
1080
  /**
1262
- * Return `true` if alt is currently pressed.
1081
+ * Use a user-provided component match function
1263
1082
  */
1264
- get isAltPressed() {
1265
- return !!this.heldKeys["alt"];
1083
+ ComponentResolveStrategy[ComponentResolveStrategy["Custom"] = 3] = "Custom";
1084
+ })(ComponentResolveStrategy || (ComponentResolveStrategy = {}));
1085
+
1086
+ // Monkey-patch the type of these symbols.
1087
+ const $id = Symbol("id");
1088
+ const $group = Symbol("group");
1089
+ const NGX_LAZY_LOADER_CONFIG = new InjectionToken('config');
1090
+ class LazyLoaderService {
1091
+ get err() { return LazyLoaderService.config.logger.err; }
1092
+ get log() { return LazyLoaderService.config.logger.log; }
1093
+ get warn() { return LazyLoaderService.config.logger.warn; }
1094
+ constructor(config = {}) {
1095
+ // Ensure this is singleton and works regardless of special instancing requirements.
1096
+ LazyLoaderService.configure(config);
1266
1097
  }
1267
- /**
1268
- * Return `true` if super (mac/linux) or the windows key is currently pressed.
1269
- */
1270
- get isSuperPressed() {
1271
- return !!this.heldKeys["super"];
1272
- }
1273
- /**
1274
- * Return `true` if tab is currently pressed.
1275
- */
1276
- get isTabPressed() {
1277
- return !!this.heldKeys["tab"];
1278
- }
1279
- clearKeys() {
1280
- Object.keys(this.heldKeys).forEach(k => {
1281
- this.heldKeys[k] = false;
1282
- });
1283
- }
1284
- }
1285
- KeyboardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: KeyboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1286
- KeyboardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: KeyboardService, providedIn: 'root' });
1287
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: KeyboardService, decorators: [{
1288
- type: Injectable,
1289
- args: [{
1290
- providedIn: 'root'
1291
- }]
1292
- }], ctorParameters: function () { return []; }, propDecorators: { clearKeys: [{
1293
- type: HostListener,
1294
- args: ["window:blur"]
1295
- }, {
1296
- type: HostListener,
1297
- args: ["window:resize"]
1298
- }] } });
1299
-
1300
- /**
1301
- * Service that listens for global keyboard events
1302
- */
1303
- class FileService {
1304
- constructor(fetch) {
1305
- this.fetch = fetch;
1306
- this.chooseFile = (accept, multiple = false, formMetadata = {}) => {
1307
- return new Promise(r => {
1308
- const inEl = document.createElement('input');
1309
- inEl.setAttribute('type', 'file');
1310
- if (multiple)
1311
- inEl.setAttribute('multiple', '');
1312
- if (accept)
1313
- inEl.setAttribute('accept', accept);
1314
- inEl.click();
1315
- let formData = new FormData();
1316
- inEl.addEventListener('change', () => {
1317
- Object.keys(inEl.files).forEach(k => {
1318
- const file = inEl.files[k];
1319
- const name = file.name;
1320
- formData.append(name, file);
1321
- });
1322
- formData.append("data", JSON.stringify(formMetadata));
1323
- inEl.remove();
1324
- r(formData);
1325
- });
1326
- });
1327
- };
1328
- }
1329
- }
1330
- FileService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileService, deps: [{ token: Fetch }], target: i0.ɵɵFactoryTarget.Injectable });
1331
- FileService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileService, providedIn: 'root' });
1332
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileService, decorators: [{
1333
- type: Injectable,
1334
- args: [{
1335
- providedIn: 'root'
1336
- }]
1337
- }], ctorParameters: function () { return [{ type: Fetch }]; } });
1338
-
1339
- class ThemeService extends BehaviorSubject {
1340
- constructor() {
1341
- super("dark");
1342
- this.subscribe(t => {
1343
- document.body.classList.remove("dark");
1344
- document.body.classList.remove("light");
1345
- document.body.classList.add(t);
1346
- });
1347
- }
1348
- setTheme(t) {
1349
- this.next(t);
1350
- }
1351
- }
1352
- ThemeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1353
- ThemeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ThemeService, providedIn: 'root' });
1354
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ThemeService, decorators: [{
1355
- type: Injectable,
1356
- args: [{
1357
- providedIn: 'root'
1358
- }]
1359
- }], ctorParameters: function () { return []; } });
1360
-
1361
- const { log, warn, err } = Logger("NavigationService", "#ff9800");
1362
- class NavigationService {
1363
- constructor(lazyLoader) {
1364
- this.lazyLoader = lazyLoader;
1365
- this.virtualPath$ = new BehaviorSubject(null);
1366
- window.onhashchange = () => this.loadRootPageFromUrl();
1367
- this.loadRootPageFromUrl();
1368
- }
1369
- loadRootPageFromUrl() {
1370
- const hash = location.hash.split("?")[0];
1371
- // If the URL is imprecisely set, we restore it to the landing page
1372
- if (!this.lazyLoader.isComponentRegistered(hash))
1373
- return this.loadRootPage("#/Landing");
1374
- this.loadRootPage(location.hash);
1375
- }
1376
- loadRootPage(url, data = {}) {
1377
- const [path, query] = url.split('?');
1378
- const hash = path.replace(/^\/?#\/?/, '');
1379
- const chunks = hash.split('/');
1380
- // Get query params and pass them as @Input arguments.
1381
- const params = (query === null || query === void 0 ? void 0 : query.split('&').reduce((pars, par) => {
1382
- const [key, value] = par.split("=");
1383
- const decoded = decodeURIComponent(value);
1384
- pars[key] = decoded;
1385
- return pars;
1386
- }, {})) || {};
1387
- log(`Root page navigate to '${hash}'`, { params, chunks });
1388
- this.virtualPath$.next({
1389
- root: chunks[0],
1390
- chunks: chunks,
1391
- args: params
1392
- });
1393
- }
1394
- }
1395
- NavigationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NavigationService, deps: [{ token: LazyLoaderService }], target: i0.ɵɵFactoryTarget.Injectable });
1396
- NavigationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NavigationService, providedIn: 'root' });
1397
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NavigationService, decorators: [{
1398
- type: Injectable,
1399
- args: [{
1400
- providedIn: 'root'
1401
- }]
1402
- }], ctorParameters: function () { return [{ type: LazyLoaderService }]; } });
1403
-
1404
- var ComponentResolveStrategy;
1405
- (function (ComponentResolveStrategy) {
1406
- /**
1407
- * Match the fist component we find
1408
- * (best used for standalone components)
1409
- * @default
1410
- */
1411
- ComponentResolveStrategy[ComponentResolveStrategy["PickFirst"] = 0] = "PickFirst";
1412
- /**
1413
- * Perform an Exact ID to Classname of the Component
1414
- * case sensitive, zero tolerance.
1415
- */
1416
- ComponentResolveStrategy[ComponentResolveStrategy["MatchIdToClassName"] = 1] = "MatchIdToClassName";
1417
- /**
1418
- * Perform a fuzzy ID to classname match
1419
- * case insensitive, mutes symbols
1420
- * ignores "Component" and "Module" postfixes on class
1421
- * names
1422
- */
1423
- ComponentResolveStrategy[ComponentResolveStrategy["FuzzyIdClassName"] = 2] = "FuzzyIdClassName";
1424
- /**
1425
- * Use a user-provided component match function
1426
- */
1427
- ComponentResolveStrategy[ComponentResolveStrategy["Custom"] = 3] = "Custom";
1428
- })(ComponentResolveStrategy || (ComponentResolveStrategy = {}));
1429
-
1430
- // Monkey-patch the type of these symbols.
1431
- const $id = Symbol("id");
1432
- const $group = Symbol("group");
1433
- const NGX_LAZY_LOADER_CONFIG = new InjectionToken('config');
1434
- class LazyLoaderService {
1435
- get err() { return LazyLoaderService.config.logger.err; }
1436
- get log() { return LazyLoaderService.config.logger.log; }
1437
- get warn() { return LazyLoaderService.config.logger.warn; }
1438
- constructor(config = {}) {
1439
- // Ensure this is singleton and works regardless of special instancing requirements.
1440
- LazyLoaderService.configure(config);
1441
- }
1442
- static configure(config) {
1443
- var _a;
1444
- const { log, warn, err } = Logger("ngx-lazy-loader", "#009688");
1445
- this.config = Object.assign({ componentResolveStrategy: ComponentResolveStrategy.PickFirst, logger: {
1446
- log,
1447
- warn,
1448
- err
1449
- } }, config);
1450
- (_a = config.entries) === null || _a === void 0 ? void 0 : _a.forEach(e => this.addComponentToRegistry(e));
1451
- // If a custom resolution strategy is provided but no resolution function is passed,
1452
- // we throw an error
1453
- if (this.config.componentResolveStrategy == ComponentResolveStrategy.Custom &&
1454
- !this.config.customResolver) {
1455
- throw new Error("Cannot initialize. Configuration specifies a custom resolve matcher but none was provided");
1456
- }
1457
- if (this.config.loaderDistractorComponent && this.config.loaderDistractorTemplate)
1458
- throw new Error("Cannot have both a Component and Template for Distractor view.");
1459
- if (this.config.errorComponent && this.config.errorTemplate)
1460
- throw new Error("Cannot have both a Component and Template for Error view.");
1461
- if (this.config.notFoundComponent && this.config.notFoundTemplate)
1462
- throw new Error("Cannot have both a Component and Template for NotFound view.");
1098
+ static configure(config) {
1099
+ var _a;
1100
+ const { log, warn, err } = Logger("ngx-lazy-loader", "#009688");
1101
+ this.config = Object.assign({ componentResolveStrategy: ComponentResolveStrategy.PickFirst, logger: {
1102
+ log,
1103
+ warn,
1104
+ err
1105
+ } }, config);
1106
+ (_a = config.entries) === null || _a === void 0 ? void 0 : _a.forEach(e => this.addComponentToRegistry(e));
1107
+ // If a custom resolution strategy is provided but no resolution function is passed,
1108
+ // we throw an error
1109
+ if (this.config.componentResolveStrategy == ComponentResolveStrategy.Custom &&
1110
+ !this.config.customResolver) {
1111
+ throw new Error("Cannot initialize. Configuration specifies a custom resolve matcher but none was provided");
1112
+ }
1113
+ if (this.config.loaderDistractorComponent && this.config.loaderDistractorTemplate)
1114
+ throw new Error("Cannot have both a Component and Template for Distractor view.");
1115
+ if (this.config.errorComponent && this.config.errorTemplate)
1116
+ throw new Error("Cannot have both a Component and Template for Error view.");
1117
+ if (this.config.notFoundComponent && this.config.notFoundTemplate)
1118
+ throw new Error("Cannot have both a Component and Template for NotFound view.");
1463
1119
  }
1464
1120
  static addComponentToRegistry(registration) {
1465
1121
  var _a;
@@ -1995,6 +1651,349 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImpor
1995
1651
  type: Output
1996
1652
  }] } });
1997
1653
 
1654
+ const { log: log$1, warn: warn$1, err: err$1 } = Logger("DialogService", "#607d8b");
1655
+ class DialogService {
1656
+ constructor(dialog, lazyLoader) {
1657
+ this.dialog = dialog;
1658
+ this.lazyLoader = lazyLoader;
1659
+ this.dialogs = [];
1660
+ }
1661
+ open(name, groupOrOptions, opts = {}) {
1662
+ const group = typeof groupOrOptions == "string" ? groupOrOptions : 'default';
1663
+ if (typeof groupOrOptions == 'object')
1664
+ opts = groupOrOptions;
1665
+ return new Promise((resolve, reject) => {
1666
+ const registration = this.lazyLoader.resolveRegistrationEntry(name, group);
1667
+ if (!registration)
1668
+ return reject(new Error("Cannot open dialog for " + name + ". Could not find in registry."));
1669
+ const args = Object.assign(Object.assign({ closeOnNavigation: true, restoreFocus: true, width: registration['width'], height: registration['height'] }, opts), { data: {
1670
+ id: name,
1671
+ inputs: opts.inputs || {},
1672
+ outputs: opts.outputs || {},
1673
+ group: group
1674
+ }, panelClass: [
1675
+ "dialog-" + name,
1676
+ ...(Array.isArray(opts.panelClass) ? opts.panelClass : [opts.panelClass] || [])
1677
+ ] });
1678
+ let dialog = this.dialog.open(LazyLoaderComponent, args);
1679
+ dialog['idx'] = name;
1680
+ this.dialogs.push(dialog);
1681
+ dialog.afterClosed().subscribe(result => {
1682
+ log$1("Dialog closed " + name, result);
1683
+ resolve(result);
1684
+ });
1685
+ });
1686
+ }
1687
+ // Close all dialogs matching the given name
1688
+ close(name) {
1689
+ const dialogs = this.dialogs.filter(d => d['idx'] == name);
1690
+ dialogs.forEach(dialog => dialog.close());
1691
+ }
1692
+ /**
1693
+ * Method to close _all_ dialogs.
1694
+ * Should be used sparingly.
1695
+ */
1696
+ clearDialog() {
1697
+ this.dialogs.forEach(dialog => dialog.close());
1698
+ }
1699
+ }
1700
+ DialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DialogService, deps: [{ token: i1.MatDialog }, { token: LazyLoaderService }], target: i0.ɵɵFactoryTarget.Injectable });
1701
+ DialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DialogService, providedIn: 'root' });
1702
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DialogService, decorators: [{
1703
+ type: Injectable,
1704
+ args: [{
1705
+ providedIn: 'root'
1706
+ }]
1707
+ }], ctorParameters: function () { return [{ type: i1.MatDialog }, { type: LazyLoaderService }]; } });
1708
+
1709
+ // Total number of _retries_ if there is a 429 response code.
1710
+ const retryCount = 2;
1711
+ class Fetch {
1712
+ constructor(http) {
1713
+ this.http = http;
1714
+ }
1715
+ // Public interface for making AJAX transactions
1716
+ get(url, options = {}, returnError = false) {
1717
+ return this.request("get", url, options, returnError);
1718
+ }
1719
+ put(url, body, options = {}, returnError = false) {
1720
+ options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
1721
+ return this.request("put", url, options, returnError);
1722
+ }
1723
+ post(url, body, options = {}, returnError = false) {
1724
+ options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
1725
+ return this.request("post", url, options, returnError);
1726
+ }
1727
+ patch(url, body, options = {}, returnError = false) {
1728
+ options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
1729
+ return this.request("patch", url, options, returnError);
1730
+ }
1731
+ delete(url, options = {}, returnError = false) {
1732
+ return this.request("delete", url, options, returnError);
1733
+ }
1734
+ // Internally, handle the observable as a promise.
1735
+ request(method, url, options = {}, returnError = false) {
1736
+ options.reportProgress = true;
1737
+ // Allow support for different response types.
1738
+ // Generally we shouldn't need this to be anything other than JSON.
1739
+ options.responseType = options.responseType || "json";
1740
+ options.withCredentials = true;
1741
+ const p = new Promise((resolve, reject) => {
1742
+ const o = this.http.request(method, url, options)
1743
+ .pipe(retry({
1744
+ delay(error, retryCount) {
1745
+ // 429 and 502 are most common for overloaded
1746
+ // backends -- so we'll retry if we get these errors
1747
+ if (error.status == 429 || error.status == 502)
1748
+ return of({});
1749
+ if (error.status == 504 && isDevMode())
1750
+ alert("It looks like you can't reach your development backend anymore");
1751
+ throw error;
1752
+ },
1753
+ count: retryCount
1754
+ }))
1755
+ .subscribe(data => {
1756
+ resolve(data);
1757
+ // provide 3ms slacktime before releasing observable.
1758
+ setTimeout(() => {
1759
+ o.unsubscribe();
1760
+ }, 3);
1761
+ });
1762
+ });
1763
+ return p;
1764
+ }
1765
+ }
1766
+ Fetch.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: Fetch, deps: [{ token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
1767
+ Fetch.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: Fetch, providedIn: "root" });
1768
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: Fetch, decorators: [{
1769
+ type: Injectable,
1770
+ args: [{
1771
+ providedIn: "root"
1772
+ }]
1773
+ }], ctorParameters: function () { return [{ type: i1$2.HttpClient }]; } });
1774
+
1775
+ /**
1776
+ * Service that listens for global keyboard events
1777
+ */
1778
+ class KeyboardService {
1779
+ constructor() {
1780
+ this.heldKeys = {};
1781
+ this.keyCommands = [];
1782
+ window.addEventListener("keydown", (evt) => this.onKeyDown(evt));
1783
+ window.addEventListener("keyup", (evt) => this.onKeyUp(evt));
1784
+ }
1785
+ onKeyDown(evt) {
1786
+ // console.log("keydown", evt.key)
1787
+ this.heldKeys[evt.key.toLowerCase()] = true;
1788
+ // Do a general filter where all of the modifiers must be matched if specified
1789
+ // Then check that the actual keys match what was specified
1790
+ let commands = this.keyCommands
1791
+ .filter(kc => {
1792
+ var _a;
1793
+ return (kc.ctrl == undefined || kc.ctrl === evt.ctrlKey) &&
1794
+ (kc.alt == undefined || kc.alt === evt.altKey) &&
1795
+ (kc.shift == undefined || kc.shift === evt.shiftKey) &&
1796
+ (kc.super == undefined || kc.super === evt.metaKey) &&
1797
+ kc.keys.length == ((_a = kc.keys.filter(k => this.heldKeys[k])) === null || _a === void 0 ? void 0 : _a.length);
1798
+ });
1799
+ if (evt.ctrlKey && commands.length > 0 || commands.find(c => c.interrupt)) {
1800
+ evt.stopPropagation();
1801
+ evt.preventDefault();
1802
+ }
1803
+ if (evt.key == "Pause")
1804
+ debugger;
1805
+ commands.forEach(kc => kc.sub.next(evt));
1806
+ /**
1807
+ * Prevent CTRL+P and other standard key events from being handled by the browser.
1808
+ * Allow specific combonations:
1809
+ * CTRL+W
1810
+ * CTRL+T
1811
+ * CTRL+F5
1812
+ */
1813
+ // if (evt.ctrlKey && !['w', 't', 'F5'].includes(evt.key)) {
1814
+ // evt.preventDefault();
1815
+ // }
1816
+ }
1817
+ onKeyUp(evt) {
1818
+ this.heldKeys[evt.key.toLowerCase()] = false;
1819
+ }
1820
+ onKeyPress(evt) {
1821
+ // this.heldKeys[evt.key] = false;
1822
+ }
1823
+ /**
1824
+ * Use this to subscribe to keyboard events throughout
1825
+ * the application. This is a passive listener and will
1826
+ * **NOT** interrupt the event chain.
1827
+ */
1828
+ onKeyCommand(key) {
1829
+ const sub = new Subject();
1830
+ let item = Object.assign(Object.assign({}, key), { keys: (Array.isArray(key.key) ? key.key : [key.key]), sub: sub });
1831
+ this.keyCommands.push(item);
1832
+ return Object.assign(Object.assign({}, sub), { subscribe: ((...args) => {
1833
+ const s = sub.subscribe(...args);
1834
+ return Object.assign(Object.assign({}, s), { unsubscribe: () => {
1835
+ s.unsubscribe();
1836
+ // Remove the keycommand from the list of listeners.
1837
+ const i = this.keyCommands.findIndex(c => c == item);
1838
+ this.keyCommands.splice(i, 1);
1839
+ } });
1840
+ }) });
1841
+ }
1842
+ /**
1843
+ * Return `true` if shift is currently pressed.
1844
+ */
1845
+ get isShiftPressed() {
1846
+ return !!this.heldKeys["shift"];
1847
+ }
1848
+ /**
1849
+ * Return `true` if ctrl is currently pressed.
1850
+ */
1851
+ get isCtrlPressed() {
1852
+ return !!this.heldKeys["control"];
1853
+ }
1854
+ /**
1855
+ * Return `true` if alt is currently pressed.
1856
+ */
1857
+ get isAltPressed() {
1858
+ return !!this.heldKeys["alt"];
1859
+ }
1860
+ /**
1861
+ * Return `true` if super (mac/linux) or the windows key is currently pressed.
1862
+ */
1863
+ get isSuperPressed() {
1864
+ return !!this.heldKeys["super"];
1865
+ }
1866
+ /**
1867
+ * Return `true` if tab is currently pressed.
1868
+ */
1869
+ get isTabPressed() {
1870
+ return !!this.heldKeys["tab"];
1871
+ }
1872
+ clearKeys() {
1873
+ Object.keys(this.heldKeys).forEach(k => {
1874
+ this.heldKeys[k] = false;
1875
+ });
1876
+ }
1877
+ }
1878
+ KeyboardService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: KeyboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1879
+ KeyboardService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: KeyboardService, providedIn: 'root' });
1880
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: KeyboardService, decorators: [{
1881
+ type: Injectable,
1882
+ args: [{
1883
+ providedIn: 'root'
1884
+ }]
1885
+ }], ctorParameters: function () { return []; }, propDecorators: { clearKeys: [{
1886
+ type: HostListener,
1887
+ args: ["window:blur"]
1888
+ }, {
1889
+ type: HostListener,
1890
+ args: ["window:resize"]
1891
+ }] } });
1892
+
1893
+ /**
1894
+ * Service that listens for global keyboard events
1895
+ */
1896
+ class FileService {
1897
+ constructor(fetch) {
1898
+ this.fetch = fetch;
1899
+ this.chooseFile = (accept, multiple = false, formMetadata = {}) => {
1900
+ return new Promise(r => {
1901
+ const inEl = document.createElement('input');
1902
+ inEl.setAttribute('type', 'file');
1903
+ if (multiple)
1904
+ inEl.setAttribute('multiple', '');
1905
+ if (accept)
1906
+ inEl.setAttribute('accept', accept);
1907
+ inEl.click();
1908
+ let formData = new FormData();
1909
+ inEl.addEventListener('change', () => {
1910
+ Object.keys(inEl.files).forEach(k => {
1911
+ const file = inEl.files[k];
1912
+ const name = file.name;
1913
+ formData.append(name, file);
1914
+ });
1915
+ formData.append("data", JSON.stringify(formMetadata));
1916
+ inEl.remove();
1917
+ r(formData);
1918
+ });
1919
+ });
1920
+ };
1921
+ }
1922
+ }
1923
+ FileService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileService, deps: [{ token: Fetch }], target: i0.ɵɵFactoryTarget.Injectable });
1924
+ FileService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileService, providedIn: 'root' });
1925
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: FileService, decorators: [{
1926
+ type: Injectable,
1927
+ args: [{
1928
+ providedIn: 'root'
1929
+ }]
1930
+ }], ctorParameters: function () { return [{ type: Fetch }]; } });
1931
+
1932
+ class ThemeService extends BehaviorSubject {
1933
+ constructor() {
1934
+ super("dark");
1935
+ this.subscribe(t => {
1936
+ document.body.classList.remove("dark");
1937
+ document.body.classList.remove("light");
1938
+ document.body.classList.add(t);
1939
+ });
1940
+ }
1941
+ setTheme(t) {
1942
+ this.next(t);
1943
+ }
1944
+ }
1945
+ ThemeService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1946
+ ThemeService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ThemeService, providedIn: 'root' });
1947
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ThemeService, decorators: [{
1948
+ type: Injectable,
1949
+ args: [{
1950
+ providedIn: 'root'
1951
+ }]
1952
+ }], ctorParameters: function () { return []; } });
1953
+
1954
+ const { log, warn, err } = Logger("NavigationService", "#ff9800");
1955
+ class NavigationService {
1956
+ constructor(lazyLoader) {
1957
+ this.lazyLoader = lazyLoader;
1958
+ this.virtualPath$ = new BehaviorSubject(null);
1959
+ window.onhashchange = () => this.loadRootPageFromUrl();
1960
+ this.loadRootPageFromUrl();
1961
+ }
1962
+ loadRootPageFromUrl() {
1963
+ const hash = location.hash.split("?")[0];
1964
+ // If the URL is imprecisely set, we restore it to the landing page
1965
+ if (!this.lazyLoader.isComponentRegistered(hash))
1966
+ return this.loadRootPage("#/Landing");
1967
+ this.loadRootPage(location.hash);
1968
+ }
1969
+ loadRootPage(url, data = {}) {
1970
+ const [path, query] = url.split('?');
1971
+ const hash = path.replace(/^\/?#\/?/, '');
1972
+ const chunks = hash.split('/');
1973
+ // Get query params and pass them as @Input arguments.
1974
+ const params = (query === null || query === void 0 ? void 0 : query.split('&').reduce((pars, par) => {
1975
+ const [key, value] = par.split("=");
1976
+ const decoded = decodeURIComponent(value);
1977
+ pars[key] = decoded;
1978
+ return pars;
1979
+ }, {})) || {};
1980
+ log(`Root page navigate to '${hash}'`, { params, chunks });
1981
+ this.virtualPath$.next({
1982
+ root: chunks[0],
1983
+ chunks: chunks,
1984
+ args: params
1985
+ });
1986
+ }
1987
+ }
1988
+ NavigationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NavigationService, deps: [{ token: LazyLoaderService }], target: i0.ɵɵFactoryTarget.Injectable });
1989
+ NavigationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NavigationService, providedIn: 'root' });
1990
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NavigationService, decorators: [{
1991
+ type: Injectable,
1992
+ args: [{
1993
+ providedIn: 'root'
1994
+ }]
1995
+ }], ctorParameters: function () { return [{ type: LazyLoaderService }]; } });
1996
+
1998
1997
  class LazyLoaderModule {
1999
1998
  static forRoot(config) {
2000
1999
  return ({