@fleetbase/ember-core 0.2.17 → 0.2.18
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.
|
@@ -2,12 +2,14 @@ import SimpleAuthSessionService from 'ember-simple-auth/services/session';
|
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
4
|
import { later } from '@ember/runloop';
|
|
5
|
+
import { debug } from '@ember/debug';
|
|
5
6
|
import getWithDefault from '../utils/get-with-default';
|
|
6
7
|
|
|
7
8
|
export default class SessionService extends SimpleAuthSessionService {
|
|
8
9
|
@service router;
|
|
9
10
|
@service currentUser;
|
|
10
11
|
@service fetch;
|
|
12
|
+
@service notifications;
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Set where to transition to
|
|
@@ -52,10 +54,7 @@ export default class SessionService extends SimpleAuthSessionService {
|
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
const loaderNode = this.showLoader('Starting session...');
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
await this.router.transitionTo(this.redirectTo);
|
|
57
|
+
const removeLoaderNode = () => {
|
|
59
58
|
later(
|
|
60
59
|
this,
|
|
61
60
|
() => {
|
|
@@ -63,11 +62,18 @@ export default class SessionService extends SimpleAuthSessionService {
|
|
|
63
62
|
document.body.removeChild(loaderNode);
|
|
64
63
|
this.isLoaderNodeOpen = false;
|
|
65
64
|
},
|
|
66
|
-
600 *
|
|
65
|
+
600 * 3
|
|
67
66
|
);
|
|
67
|
+
};
|
|
68
|
+
this.isLoaderNodeOpen = true;
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
await this.router.transitionTo(this.redirectTo);
|
|
68
72
|
} catch (error) {
|
|
69
|
-
|
|
73
|
+
debug(`Session's handleAuthentication() failed to transition: ${error.message}`);
|
|
70
74
|
}
|
|
75
|
+
|
|
76
|
+
removeLoaderNode();
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
/**
|
|
@@ -114,6 +120,7 @@ export default class SessionService extends SimpleAuthSessionService {
|
|
|
114
120
|
if (transition) {
|
|
115
121
|
transition.abort();
|
|
116
122
|
}
|
|
123
|
+
|
|
117
124
|
await invalidateWithLoader(error.message ?? 'Session authentication failed...');
|
|
118
125
|
throw error;
|
|
119
126
|
}
|
|
@@ -154,8 +161,7 @@ export default class SessionService extends SimpleAuthSessionService {
|
|
|
154
161
|
}
|
|
155
162
|
|
|
156
163
|
const loaderNode = this.showLoader(loadingMessage);
|
|
157
|
-
|
|
158
|
-
this.isLoaderNodeOpen = false;
|
|
164
|
+
this.isLoaderNodeOpen = true;
|
|
159
165
|
|
|
160
166
|
return this.session.invalidate().then(() => {
|
|
161
167
|
later(
|
package/addon/services/theme.js
CHANGED
|
@@ -7,8 +7,9 @@ import { isBlank } from '@ember/utils';
|
|
|
7
7
|
import { A, isArray } from '@ember/array';
|
|
8
8
|
import { later } from '@ember/runloop';
|
|
9
9
|
import { dasherize, camelize } from '@ember/string';
|
|
10
|
+
import { pluralize } from 'ember-inflector';
|
|
10
11
|
import { getOwner } from '@ember/application';
|
|
11
|
-
import { assert, debug } from '@ember/debug';
|
|
12
|
+
import { assert, debug, warn } from '@ember/debug';
|
|
12
13
|
import RSVP from 'rsvp';
|
|
13
14
|
import loadInstalledExtensions from '../utils/load-installed-extensions';
|
|
14
15
|
import loadExtensions from '../utils/load-extensions';
|
|
@@ -18,18 +19,21 @@ import config from 'ember-get-config';
|
|
|
18
19
|
export default class UniverseService extends Service.extend(Evented) {
|
|
19
20
|
@service router;
|
|
20
21
|
@service intl;
|
|
22
|
+
@tracked applicationInstance;
|
|
23
|
+
@tracked enginesBooted = false;
|
|
24
|
+
@tracked bootedExtensions = A([]);
|
|
21
25
|
@tracked headerMenuItems = A([]);
|
|
22
26
|
@tracked organizationMenuItems = A([]);
|
|
23
27
|
@tracked userMenuItems = A([]);
|
|
24
|
-
@tracked
|
|
28
|
+
@tracked consoleAdminRegistry = {
|
|
25
29
|
menuItems: A([]),
|
|
26
30
|
menuPanels: A([]),
|
|
27
31
|
};
|
|
28
|
-
@tracked
|
|
32
|
+
@tracked consoleAccountRegistry = {
|
|
29
33
|
menuItems: A([]),
|
|
30
34
|
menuPanels: A([]),
|
|
31
35
|
};
|
|
32
|
-
@tracked
|
|
36
|
+
@tracked consoleSettingsRegistry = {
|
|
33
37
|
menuItems: A([]),
|
|
34
38
|
menuPanels: A([]),
|
|
35
39
|
};
|
|
@@ -37,6 +41,7 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
37
41
|
defaultWidgets: A([]),
|
|
38
42
|
widgets: A([]),
|
|
39
43
|
};
|
|
44
|
+
@tracked hooks = {};
|
|
40
45
|
|
|
41
46
|
/**
|
|
42
47
|
* Computed property that returns all administrative menu items.
|
|
@@ -47,8 +52,8 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
47
52
|
* @memberof UniverseService
|
|
48
53
|
* @returns {Array} Array of administrative menu items
|
|
49
54
|
*/
|
|
50
|
-
@computed('
|
|
51
|
-
return this.
|
|
55
|
+
@computed('consoleAdminRegistry.menuItems.[]') get adminMenuItems() {
|
|
56
|
+
return this.consoleAdminRegistry.menuItems;
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
/**
|
|
@@ -60,8 +65,8 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
60
65
|
* @memberof UniverseService
|
|
61
66
|
* @returns {Array} Array of administrative menu panels
|
|
62
67
|
*/
|
|
63
|
-
@computed('
|
|
64
|
-
return this.
|
|
68
|
+
@computed('consoleAdminRegistry.menuPanels.[]') get adminMenuPanels() {
|
|
69
|
+
return this.consoleAdminRegistry.menuPanels;
|
|
65
70
|
}
|
|
66
71
|
|
|
67
72
|
/**
|
|
@@ -73,8 +78,8 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
73
78
|
* @memberof UniverseService
|
|
74
79
|
* @returns {Array} Array of administrative menu items
|
|
75
80
|
*/
|
|
76
|
-
@computed('
|
|
77
|
-
return this.
|
|
81
|
+
@computed('consoleSettingsRegistry.menuItems.[]') get settingsMenuItems() {
|
|
82
|
+
return this.consoleSettingsRegistry.menuItems;
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
/**
|
|
@@ -86,8 +91,8 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
86
91
|
* @memberof UniverseService
|
|
87
92
|
* @returns {Array} Array of administrative menu panels
|
|
88
93
|
*/
|
|
89
|
-
@computed('
|
|
90
|
-
return this.
|
|
94
|
+
@computed('consoleSettingsRegistry.menuPanels.[]') get settingsMenuPanels() {
|
|
95
|
+
return this.consoleSettingsRegistry.menuPanels;
|
|
91
96
|
}
|
|
92
97
|
|
|
93
98
|
/**
|
|
@@ -130,6 +135,15 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
130
135
|
return this.router.transitionTo(route, ...args);
|
|
131
136
|
}
|
|
132
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Retrieves the application instance.
|
|
140
|
+
*
|
|
141
|
+
* @returns {ApplicationInstance} - The application instance object.
|
|
142
|
+
*/
|
|
143
|
+
getApplicationInstance() {
|
|
144
|
+
return this.applicationInstance;
|
|
145
|
+
}
|
|
146
|
+
|
|
133
147
|
/**
|
|
134
148
|
* Retrieves the mount point of a specified engine by its name.
|
|
135
149
|
|
|
@@ -230,13 +244,21 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
230
244
|
* @returns {Transition} Returns a Transition object representing the transition to the route.
|
|
231
245
|
*/
|
|
232
246
|
@action transitionMenuItem(route, menuItem) {
|
|
233
|
-
const { slug, view } = menuItem;
|
|
247
|
+
const { slug, view, section } = menuItem;
|
|
248
|
+
|
|
249
|
+
if (section && slug && view) {
|
|
250
|
+
return this.router.transitionTo(route, section, slug, { queryParams: { view } });
|
|
251
|
+
}
|
|
234
252
|
|
|
235
|
-
if (
|
|
236
|
-
return this.router.transitionTo(route,
|
|
253
|
+
if (section && slug) {
|
|
254
|
+
return this.router.transitionTo(route, section, slug);
|
|
237
255
|
}
|
|
238
256
|
|
|
239
|
-
|
|
257
|
+
if (slug && view) {
|
|
258
|
+
return this.router.transitionTo(route, slug, { queryParams: { view } });
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return this.router.transitionTo(route, slug);
|
|
240
262
|
}
|
|
241
263
|
|
|
242
264
|
/**
|
|
@@ -259,13 +281,20 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
259
281
|
@action createRegistry(registryName, options = {}) {
|
|
260
282
|
const internalRegistryName = this.createInternalRegistryName(registryName);
|
|
261
283
|
|
|
262
|
-
this[internalRegistryName]
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
284
|
+
if (this[internalRegistryName] == undefined) {
|
|
285
|
+
this[internalRegistryName] = {
|
|
286
|
+
name: registryName,
|
|
287
|
+
menuItems: [],
|
|
288
|
+
menuPanels: [],
|
|
289
|
+
renderableComponents: [],
|
|
290
|
+
...options,
|
|
291
|
+
};
|
|
292
|
+
} else {
|
|
293
|
+
this[internalRegistryName] = {
|
|
294
|
+
...this[internalRegistryName],
|
|
295
|
+
...options,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
269
298
|
|
|
270
299
|
// trigger registry created event
|
|
271
300
|
this.trigger('registry.created', this[internalRegistryName]);
|
|
@@ -519,10 +548,11 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
519
548
|
* @param {string} registryName - The name of the registry where the menu item is located.
|
|
520
549
|
* @param {string} slug - The slug of the menu item.
|
|
521
550
|
* @param {string} [view=null] - The view of the menu item, if applicable.
|
|
551
|
+
* @param {string} [section=null] - The section of the menu item, if applicable.
|
|
522
552
|
*
|
|
523
553
|
* @returns {Promise} Returns a Promise that resolves with the menu item if it is found, or null.
|
|
524
554
|
*/
|
|
525
|
-
lookupMenuItemFromRegistry(registryName, slug, view = null) {
|
|
555
|
+
lookupMenuItemFromRegistry(registryName, slug, view = null, section = null) {
|
|
526
556
|
const internalRegistryName = this.createInternalRegistryName(registryName);
|
|
527
557
|
const registry = this[internalRegistryName];
|
|
528
558
|
|
|
@@ -537,8 +567,7 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
537
567
|
for (let i = 0; i < registry.menuItems.length; i++) {
|
|
538
568
|
const menuItem = registry.menuItems[i];
|
|
539
569
|
|
|
540
|
-
|
|
541
|
-
if (menuItem && menuItem.slug === slug && menuItem.view === null && view === 'index') {
|
|
570
|
+
if (menuItem && menuItem.slug === slug && menuItem.section === section && menuItem.view === view) {
|
|
542
571
|
foundMenuItem = menuItem;
|
|
543
572
|
break;
|
|
544
573
|
}
|
|
@@ -557,8 +586,7 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
557
586
|
for (let j = 0; j < menuPanel.items.length; j++) {
|
|
558
587
|
const menuItem = menuPanel.items[j];
|
|
559
588
|
|
|
560
|
-
|
|
561
|
-
if (menuItem && menuItem.slug === slug && menuItem.view === null && view === 'index') {
|
|
589
|
+
if (menuItem && menuItem.slug === slug && menuItem.section === section && menuItem.view === view) {
|
|
562
590
|
foundMenuItem = menuItem;
|
|
563
591
|
break;
|
|
564
592
|
}
|
|
@@ -575,6 +603,134 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
575
603
|
});
|
|
576
604
|
}
|
|
577
605
|
|
|
606
|
+
/**
|
|
607
|
+
* Gets the view param from the transition object.
|
|
608
|
+
*
|
|
609
|
+
* @param {Transition} transition
|
|
610
|
+
* @return {String|Null}
|
|
611
|
+
* @memberof UniverseService
|
|
612
|
+
*/
|
|
613
|
+
getViewFromTransition(transition) {
|
|
614
|
+
const queryParams = transition.to.queryParams ?? { view: null };
|
|
615
|
+
return queryParams.view;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Creates an internal registry name for hooks based on a given registry name.
|
|
620
|
+
* The registry name is transformed to camel case and appended with 'Hooks'.
|
|
621
|
+
* Non-alphanumeric characters are replaced with hyphens.
|
|
622
|
+
*
|
|
623
|
+
* @param {string} registryName - The name of the registry for which to create an internal hook registry name.
|
|
624
|
+
* @returns {string} - The internal hook registry name, formatted as camel case with 'Hooks' appended.
|
|
625
|
+
*/
|
|
626
|
+
createInternalHookRegistryName(registryName) {
|
|
627
|
+
return `${camelize(registryName.replace(/[^a-zA-Z0-9]/g, '-'))}Hooks`;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Registers a hook function under a specified registry name.
|
|
632
|
+
* The hook is stored in an internal registry, and its hash is computed for identification.
|
|
633
|
+
* If the hook is already registered, it is appended to the existing list of hooks.
|
|
634
|
+
*
|
|
635
|
+
* @param {string} registryName - The name of the registry where the hook should be registered.
|
|
636
|
+
* @param {Function} hook - The hook function to be registered.
|
|
637
|
+
*/
|
|
638
|
+
registerHook(registryName, hook) {
|
|
639
|
+
if (typeof hook !== 'function') {
|
|
640
|
+
throw new Error('The hook must be a function.');
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// no duplicate hooks
|
|
644
|
+
if (this.didRegisterHook(registryName, hook)) {
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
const internalHookRegistryName = this.createInternalHookRegistryName(registryName);
|
|
649
|
+
const hookRegistry = this.hooks[internalHookRegistryName] || [];
|
|
650
|
+
hookRegistry.pushObject({ id: this._createHashFromFunctionDefinition(hook), hook });
|
|
651
|
+
|
|
652
|
+
this.hooks[internalHookRegistryName] = hookRegistry;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Checks if a hook was registered already.
|
|
657
|
+
*
|
|
658
|
+
* @param {String} registryName
|
|
659
|
+
* @param {Function} hook
|
|
660
|
+
* @return {Boolean}
|
|
661
|
+
* @memberof UniverseService
|
|
662
|
+
*/
|
|
663
|
+
didRegisterHook(registryName, hook) {
|
|
664
|
+
const hooks = this.getHooks(registryName);
|
|
665
|
+
const hookId = this._createHashFromFunctionDefinition(hook);
|
|
666
|
+
return isArray(hooks) && hooks.some((h) => h.id === hookId);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* Retrieves the list of hooks registered under a specified registry name.
|
|
671
|
+
* If no hooks are registered, returns an empty array.
|
|
672
|
+
*
|
|
673
|
+
* @param {string} registryName - The name of the registry for which to retrieve hooks.
|
|
674
|
+
* @returns {Array<Object>} - An array of hook objects registered under the specified registry name.
|
|
675
|
+
* Each object contains an `id` and a `hook` function.
|
|
676
|
+
*/
|
|
677
|
+
getHooks(registryName) {
|
|
678
|
+
const internalHookRegistryName = this.createInternalHookRegistryName(registryName);
|
|
679
|
+
return this.hooks[internalHookRegistryName] ?? [];
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Executes all hooks registered under a specified registry name with the given parameters.
|
|
684
|
+
* Each hook is called with the provided parameters.
|
|
685
|
+
*
|
|
686
|
+
* @param {string} registryName - The name of the registry under which hooks should be executed.
|
|
687
|
+
* @param {...*} params - The parameters to pass to each hook function.
|
|
688
|
+
*/
|
|
689
|
+
executeHooks(registryName, ...params) {
|
|
690
|
+
const hooks = this.getHooks(registryName);
|
|
691
|
+
hooks.forEach(({ hook }) => {
|
|
692
|
+
try {
|
|
693
|
+
hook(...params);
|
|
694
|
+
} catch (error) {
|
|
695
|
+
debug(`Error executing hook: ${error}`);
|
|
696
|
+
}
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Calls all hooks registered under a specified registry name with the given parameters.
|
|
702
|
+
* This is an alias for `executeHooks` for consistency in naming.
|
|
703
|
+
*
|
|
704
|
+
* @param {string} registryName - The name of the registry under which hooks should be called.
|
|
705
|
+
* @param {...*} params - The parameters to pass to each hook function.
|
|
706
|
+
*/
|
|
707
|
+
callHooks(registryName, ...params) {
|
|
708
|
+
this.executeHooks(registryName, ...params);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Calls a specific hook identified by its ID under a specified registry name with the given parameters.
|
|
713
|
+
* Only the hook with the matching ID is executed.
|
|
714
|
+
*
|
|
715
|
+
* @param {string} registryName - The name of the registry where the hook is registered.
|
|
716
|
+
* @param {string} hookId - The unique identifier of the hook to be called.
|
|
717
|
+
* @param {...*} params - The parameters to pass to the hook function.
|
|
718
|
+
*/
|
|
719
|
+
callHook(registryName, hookId, ...params) {
|
|
720
|
+
const hooks = this.getHooks(registryName);
|
|
721
|
+
const hook = hooks.find((h) => h.id === hookId);
|
|
722
|
+
|
|
723
|
+
if (hook) {
|
|
724
|
+
try {
|
|
725
|
+
hook.hook(...params);
|
|
726
|
+
} catch (error) {
|
|
727
|
+
debug(`Error executing hook: ${error}`);
|
|
728
|
+
}
|
|
729
|
+
} else {
|
|
730
|
+
warn(`Hook with ID ${hookId} not found.`);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
578
734
|
/**
|
|
579
735
|
* Registers a renderable component or an array of components into a specified registry.
|
|
580
736
|
* If a single component is provided, it is registered directly.
|
|
@@ -684,6 +840,26 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
684
840
|
this.trigger('menuItem.registered', menuItem, this[internalRegistryName]);
|
|
685
841
|
}
|
|
686
842
|
|
|
843
|
+
/**
|
|
844
|
+
* Register multiple menu items to a registry.
|
|
845
|
+
*
|
|
846
|
+
* @param {String} registryName
|
|
847
|
+
* @param {Array} [menuItems=[]]
|
|
848
|
+
* @memberof UniverseService
|
|
849
|
+
*/
|
|
850
|
+
registerMenuItems(registryName, menuItems = []) {
|
|
851
|
+
for (let i = 0; i < menuItems.length; i++) {
|
|
852
|
+
const menuItem = menuItems[i];
|
|
853
|
+
if (menuItem && menuItem.title) {
|
|
854
|
+
if (menuItem.options) {
|
|
855
|
+
this.registerMenuItem(registryName, menuItem.title, menuItem.options);
|
|
856
|
+
} else {
|
|
857
|
+
this.registerMenuItem(registryName, menuItem.title, menuItem);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
|
|
687
863
|
/**
|
|
688
864
|
* Registers a menu item's component to one or multiple engines.
|
|
689
865
|
*
|
|
@@ -724,7 +900,7 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
724
900
|
*/
|
|
725
901
|
registerAdminMenuPanel(title, items = [], options = {}) {
|
|
726
902
|
options.section = this._getOption(options, 'section', 'admin');
|
|
727
|
-
this.registerMenuPanel('admin', title, items, options);
|
|
903
|
+
this.registerMenuPanel('console:admin', title, items, options);
|
|
728
904
|
}
|
|
729
905
|
|
|
730
906
|
/**
|
|
@@ -737,7 +913,7 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
737
913
|
* @param {Object} options Additional options for the item
|
|
738
914
|
*/
|
|
739
915
|
registerAdminMenuItem(title, options = {}) {
|
|
740
|
-
this.registerMenuItem('admin', title, options);
|
|
916
|
+
this.registerMenuItem('console:admin', title, options);
|
|
741
917
|
}
|
|
742
918
|
|
|
743
919
|
/**
|
|
@@ -751,94 +927,252 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
751
927
|
* @param {Object} options Additional options for the panel
|
|
752
928
|
*/
|
|
753
929
|
registerSettingsMenuPanel(title, items = [], options = {}) {
|
|
754
|
-
this.registerMenuPanel('settings', title, items, options);
|
|
930
|
+
this.registerMenuPanel('console:settings', title, items, options);
|
|
755
931
|
}
|
|
756
932
|
|
|
757
933
|
/**
|
|
758
|
-
* Registers a new
|
|
934
|
+
* Registers a new settings menu item.
|
|
759
935
|
*
|
|
760
|
-
* @method
|
|
936
|
+
* @method registerSettingsMenuItem
|
|
761
937
|
* @public
|
|
762
938
|
* @memberof UniverseService
|
|
763
|
-
* @param {
|
|
764
|
-
*
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
* @property {Object} options - Additional options for the widget.
|
|
769
|
-
*/
|
|
770
|
-
registerDashboardWidgets(widget) {
|
|
771
|
-
if (isArray(widget)) {
|
|
772
|
-
widget.forEach((w) => this.registerDashboardWidgets(w));
|
|
773
|
-
return;
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
const newWidget = this._createDashboardWidget(widget);
|
|
777
|
-
this.dashboardWidgets.widgets.pushObject(newWidget);
|
|
778
|
-
this.trigger('widget.registered', newWidget);
|
|
939
|
+
* @param {String} title The title of the item
|
|
940
|
+
* @param {Object} options Additional options for the item
|
|
941
|
+
*/
|
|
942
|
+
registerSettingsMenuItem(title, options = {}) {
|
|
943
|
+
this.registerMenuItem('console:settings', title, options);
|
|
779
944
|
}
|
|
780
945
|
|
|
781
946
|
/**
|
|
782
|
-
*
|
|
947
|
+
* Registers a new account menu panel.
|
|
783
948
|
*
|
|
784
|
-
* @method
|
|
949
|
+
* @method registerAccountMenuPanel
|
|
785
950
|
* @public
|
|
786
951
|
* @memberof UniverseService
|
|
787
|
-
* @
|
|
952
|
+
* @param {String} title The title of the panel
|
|
953
|
+
* @param {Array} items The items of the panel
|
|
954
|
+
* @param {Object} options Additional options for the panel
|
|
788
955
|
*/
|
|
789
|
-
|
|
790
|
-
|
|
956
|
+
registerAccountMenuPanel(title, items = [], options = {}) {
|
|
957
|
+
this.registerMenuPanel('console:account', title, items, options);
|
|
791
958
|
}
|
|
792
959
|
|
|
793
960
|
/**
|
|
794
|
-
* Registers a new
|
|
961
|
+
* Registers a new account menu item.
|
|
795
962
|
*
|
|
796
|
-
* @method
|
|
963
|
+
* @method registerAccountMenuItem
|
|
797
964
|
* @public
|
|
798
965
|
* @memberof UniverseService
|
|
799
|
-
* @param {
|
|
800
|
-
*
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
966
|
+
* @param {String} title The title of the item
|
|
967
|
+
* @param {Object} options Additional options for the item
|
|
968
|
+
*/
|
|
969
|
+
registerAccountMenuItem(title, options = {}) {
|
|
970
|
+
this.registerMenuItem('console:account', title, options);
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
/**
|
|
974
|
+
* Registers a new dashboard with the given name.
|
|
975
|
+
* Initializes the dashboard with empty arrays for default widgets and widgets.
|
|
976
|
+
*
|
|
977
|
+
* @param {string} dashboardName - The name of the dashboard to register.
|
|
978
|
+
* @returns {void}
|
|
979
|
+
*/
|
|
980
|
+
registerDashboard(dashboardName) {
|
|
981
|
+
const internalDashboardRegistryName = this.createInternalDashboardName(dashboardName);
|
|
982
|
+
if (this[internalDashboardRegistryName] !== undefined) {
|
|
809
983
|
return;
|
|
810
984
|
}
|
|
811
985
|
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
986
|
+
this[internalDashboardRegistryName] = {
|
|
987
|
+
defaultWidgets: A([]),
|
|
988
|
+
widgets: A([]),
|
|
989
|
+
};
|
|
990
|
+
|
|
991
|
+
this.trigger('dashboard.registered', this[internalDashboardRegistryName]);
|
|
815
992
|
}
|
|
816
993
|
|
|
817
994
|
/**
|
|
818
|
-
* Retrieves the
|
|
995
|
+
* Retrieves the registry for a specific dashboard.
|
|
819
996
|
*
|
|
820
|
-
* @
|
|
821
|
-
* @
|
|
997
|
+
* @param {string} dashboardName - The name of the dashboard to get the registry for.
|
|
998
|
+
* @returns {Object} - The registry object for the specified dashboard, including default and registered widgets.
|
|
999
|
+
*/
|
|
1000
|
+
getDashboardRegistry(dashboardName) {
|
|
1001
|
+
const internalDashboardRegistryName = this.createInternalDashboardName(dashboardName);
|
|
1002
|
+
return this[internalDashboardRegistryName];
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* Checks if a dashboard has been registered.
|
|
1007
|
+
*
|
|
1008
|
+
* @param {String} dashboardName
|
|
1009
|
+
* @return {Boolean}
|
|
822
1010
|
* @memberof UniverseService
|
|
823
|
-
|
|
1011
|
+
*/
|
|
1012
|
+
didRegisterDashboard(dashboardName) {
|
|
1013
|
+
const internalDashboardRegistryName = this.createInternalDashboardName(dashboardName);
|
|
1014
|
+
return this[internalDashboardRegistryName] !== undefined;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* Retrieves the widget registry for a specific dashboard and type.
|
|
1019
|
+
*
|
|
1020
|
+
* @param {string} dashboardName - The name of the dashboard to get the widget registry for.
|
|
1021
|
+
* @param {string} [type='widgets'] - The type of widget registry to retrieve (e.g., 'widgets', 'defaultWidgets').
|
|
1022
|
+
* @returns {Array} - An array of widget objects for the specified dashboard and type.
|
|
1023
|
+
*/
|
|
1024
|
+
getWidgetRegistry(dashboardName, type = 'widgets') {
|
|
1025
|
+
const internalDashboardRegistryName = this.createInternalDashboardName(dashboardName);
|
|
1026
|
+
const typeKey = pluralize(type);
|
|
1027
|
+
return isArray(this[internalDashboardRegistryName][typeKey]) ? this[internalDashboardRegistryName][typeKey] : [];
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* Registers widgets for a specific dashboard.
|
|
1032
|
+
* Supports registering multiple widgets and different types of widget collections.
|
|
1033
|
+
*
|
|
1034
|
+
* @param {string} dashboardName - The name of the dashboard to register widgets for.
|
|
1035
|
+
* @param {Array|Object} widgets - An array of widget objects or a single widget object to register.
|
|
1036
|
+
* @param {string} [type='widgets'] - The type of widgets to register (e.g., 'widgets', 'defaultWidgets').
|
|
1037
|
+
* @returns {void}
|
|
1038
|
+
*/
|
|
1039
|
+
registerWidgets(dashboardName, widgets = [], type = 'widgets') {
|
|
1040
|
+
const internalDashboardRegistryName = this.createInternalDashboardName(dashboardName);
|
|
1041
|
+
if (isArray(widgets)) {
|
|
1042
|
+
widgets.forEach((w) => this.registerWidgets(dashboardName, w, type));
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
const typeKey = pluralize(type);
|
|
1047
|
+
const newWidget = this._createDashboardWidget(widgets);
|
|
1048
|
+
const widgetRegistry = this.getWidgetRegistry(dashboardName, type);
|
|
1049
|
+
if (this.widgetRegistryHasWidget(widgetRegistry, newWidget)) {
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
this[internalDashboardRegistryName][typeKey] = [...widgetRegistry, newWidget];
|
|
1054
|
+
this.trigger('widget.registered', newWidget);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
/**
|
|
1058
|
+
* Checks if a widget with the same ID as the pending widget is already registered in the specified dashboard and type.
|
|
1059
|
+
*
|
|
1060
|
+
* @param {string} dashboardName - The name of the dashboard to check.
|
|
1061
|
+
* @param {Object} widgetPendingRegistry - The widget to check for in the registry.
|
|
1062
|
+
* @param {string} [type='widgets'] - The type of widget registry to check (e.g., 'widgets', 'defaultWidgets').
|
|
1063
|
+
* @returns {boolean} - `true` if a widget with the same ID is found in the registry; otherwise, `false`.
|
|
1064
|
+
*/
|
|
1065
|
+
didRegisterWidget(dashboardName, widgetPendingRegistry, type = 'widgets') {
|
|
1066
|
+
const widgetRegistry = this.getWidgetRegistry(dashboardName, type);
|
|
1067
|
+
return widgetRegistry.includes((widget) => widget.widgetId === widgetPendingRegistry.widgetId);
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
/**
|
|
1071
|
+
* Checks if a widget with the same ID as the pending widget exists in the provided widget registry instance.
|
|
1072
|
+
*
|
|
1073
|
+
* @param {Array} [widgetRegistryInstance=[]] - An array of widget objects to check.
|
|
1074
|
+
* @param {Object} widgetPendingRegistry - The widget to check for in the registry.
|
|
1075
|
+
* @returns {boolean} - `true` if a widget with the same ID is found in the registry; otherwise, `false`.
|
|
1076
|
+
*/
|
|
1077
|
+
widgetRegistryHasWidget(widgetRegistryInstance = [], widgetPendingRegistry) {
|
|
1078
|
+
return widgetRegistryInstance.includes((widget) => widget.widgetId === widgetPendingRegistry.widgetId);
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* Registers widgets for the default 'dashboard' dashboard.
|
|
1083
|
+
*
|
|
1084
|
+
* @param {Array} [widgets=[]] - An array of widget objects to register.
|
|
1085
|
+
* @returns {void}
|
|
1086
|
+
*/
|
|
1087
|
+
registerDashboardWidgets(widgets = []) {
|
|
1088
|
+
this.registerWidgets('dashboard', widgets);
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/**
|
|
1092
|
+
* Registers default widgets for the default 'dashboard' dashboard.
|
|
1093
|
+
*
|
|
1094
|
+
* @param {Array} [widgets=[]] - An array of default widget objects to register.
|
|
1095
|
+
* @returns {void}
|
|
1096
|
+
*/
|
|
1097
|
+
registerDefaultDashboardWidgets(widgets = []) {
|
|
1098
|
+
this.registerWidgets('dashboard', widgets, 'defaultWidgets');
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* Registers default widgets for a specified dashboard.
|
|
1103
|
+
*
|
|
1104
|
+
* @param {String} dashboardName
|
|
1105
|
+
* @param {Array} [widgets=[]] - An array of default widget objects to register.
|
|
1106
|
+
* @returns {void}
|
|
1107
|
+
*/
|
|
1108
|
+
registerDefaultWidgets(dashboardName, widgets = []) {
|
|
1109
|
+
this.registerWidgets(dashboardName, widgets, 'defaultWidgets');
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
/**
|
|
1113
|
+
* Retrieves widgets for a specific dashboard.
|
|
1114
|
+
*
|
|
1115
|
+
* @param {string} dashboardName - The name of the dashboard to retrieve widgets for.
|
|
1116
|
+
* @param {string} [type='widgets'] - The type of widgets to retrieve (e.g., 'widgets', 'defaultWidgets').
|
|
1117
|
+
* @returns {Array} - An array of widgets for the specified dashboard and type.
|
|
1118
|
+
*/
|
|
1119
|
+
getWidgets(dashboardName, type = 'widgets') {
|
|
1120
|
+
const typeKey = pluralize(type);
|
|
1121
|
+
const internalDashboardRegistryName = this.createInternalDashboardName(dashboardName);
|
|
1122
|
+
return isArray(this[internalDashboardRegistryName][typeKey]) ? this[internalDashboardRegistryName][typeKey] : [];
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* Retrieves default widgets for a specific dashboard.
|
|
1127
|
+
*
|
|
1128
|
+
* @param {string} dashboardName - The name of the dashboard to retrieve default widgets for.
|
|
1129
|
+
* @returns {Array} - An array of default widgets for the specified dashboard.
|
|
1130
|
+
*/
|
|
1131
|
+
getDefaultWidgets(dashboardName) {
|
|
1132
|
+
return this.getWidgets(dashboardName, 'defaultWidgets');
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
/**
|
|
1136
|
+
* Retrieves widgets for the default 'dashboard' dashboard.
|
|
1137
|
+
*
|
|
1138
|
+
* @returns {Array} - An array of widgets for the default 'dashboard' dashboard.
|
|
1139
|
+
*/
|
|
1140
|
+
getDashboardWidgets() {
|
|
1141
|
+
return this.getWidgets('dashboard');
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
/**
|
|
1145
|
+
* Retrieves default widgets for the default 'dashboard' dashboard.
|
|
1146
|
+
*
|
|
1147
|
+
* @returns {Array} - An array of default widgets for the default 'dashboard' dashboard.
|
|
824
1148
|
*/
|
|
825
1149
|
getDefaultDashboardWidgets() {
|
|
826
|
-
return this.
|
|
1150
|
+
return this.getWidgets('dashboard', 'defaultWidgets');
|
|
827
1151
|
}
|
|
828
1152
|
|
|
829
1153
|
/**
|
|
830
|
-
* Creates a dashboard
|
|
1154
|
+
* Creates an internal name for a dashboard based on its given name.
|
|
831
1155
|
*
|
|
832
|
-
* @param {
|
|
833
|
-
* @
|
|
1156
|
+
* @param {string} dashboardName - The name of the dashboard.
|
|
1157
|
+
* @returns {string} - The internal name for the dashboard, formatted as `${dashboardName}Widgets`.
|
|
1158
|
+
*/
|
|
1159
|
+
createInternalDashboardName(dashboardName) {
|
|
1160
|
+
return `${camelize(dashboardName.replace(/[^a-zA-Z0-9]/g, '-'))}Widgets`;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
/**
|
|
1164
|
+
* Creates a new widget object from a widget definition.
|
|
1165
|
+
* If the component is a function, it is registered with the host application.
|
|
1166
|
+
*
|
|
1167
|
+
* @param {Object} widget - The widget definition.
|
|
1168
|
+
* @param {string} widget.widgetId - The unique ID of the widget.
|
|
834
1169
|
* @param {string} widget.name - The name of the widget.
|
|
835
|
-
* @param {string} widget.description -
|
|
836
|
-
* @param {string} widget.icon -
|
|
837
|
-
* @param {
|
|
838
|
-
* @param {Object} widget.grid_options - Grid options for the widget
|
|
839
|
-
* @param {Object} widget.options - Additional options for the widget.
|
|
840
|
-
* @returns {Object}
|
|
841
|
-
* @memberof UniverseService
|
|
1170
|
+
* @param {string} [widget.description] - A description of the widget.
|
|
1171
|
+
* @param {string} [widget.icon] - An icon for the widget.
|
|
1172
|
+
* @param {Function|string} [widget.component] - A component definition or name for the widget.
|
|
1173
|
+
* @param {Object} [widget.grid_options] - Grid options for the widget.
|
|
1174
|
+
* @param {Object} [widget.options] - Additional options for the widget.
|
|
1175
|
+
* @returns {Object} - The newly created widget object.
|
|
842
1176
|
*/
|
|
843
1177
|
_createDashboardWidget(widget) {
|
|
844
1178
|
// Extract properties from the widget object
|
|
@@ -872,16 +1206,31 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
872
1206
|
}
|
|
873
1207
|
|
|
874
1208
|
/**
|
|
875
|
-
*
|
|
876
|
-
*
|
|
1209
|
+
* Generates a unique hash for a widget component based on its function definition.
|
|
1210
|
+
* This method delegates the hash creation to the `_createHashFromFunctionDefinition` method.
|
|
877
1211
|
*
|
|
878
|
-
* @param {Function} component - The
|
|
879
|
-
* @returns {string}
|
|
880
|
-
* @memberof UniverseService
|
|
1212
|
+
* @param {Function} component - The function representing the widget component.
|
|
1213
|
+
* @returns {string} - The unique hash representing the widget component.
|
|
881
1214
|
*/
|
|
882
1215
|
_createUniqueWidgetHashFromDefinition(component) {
|
|
883
|
-
|
|
884
|
-
|
|
1216
|
+
return this._createHashFromFunctionDefinition(component);
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
/**
|
|
1220
|
+
* Creates a hash value from a function definition. The hash is generated based on the function's string representation.
|
|
1221
|
+
* If the function has a name, it returns that name. Otherwise, it converts the function's string representation
|
|
1222
|
+
* into a hash value. This is done by iterating over the characters of the string and performing a simple hash calculation.
|
|
1223
|
+
*
|
|
1224
|
+
* @param {Function} func - The function whose definition will be hashed.
|
|
1225
|
+
* @returns {string} - The hash value derived from the function's definition. If the function has a name, it is returned directly.
|
|
1226
|
+
*/
|
|
1227
|
+
_createHashFromFunctionDefinition(func) {
|
|
1228
|
+
if (func.name) {
|
|
1229
|
+
return func.name;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
if (typeof func.toString === 'function') {
|
|
1233
|
+
let definition = func.toString();
|
|
885
1234
|
let hash = 0;
|
|
886
1235
|
for (let i = 0; i < definition.length; i++) {
|
|
887
1236
|
const char = definition.charCodeAt(i);
|
|
@@ -891,20 +1240,7 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
891
1240
|
return hash.toString(16);
|
|
892
1241
|
}
|
|
893
1242
|
|
|
894
|
-
return
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
/**
|
|
898
|
-
* Registers a new settings menu item.
|
|
899
|
-
*
|
|
900
|
-
* @method registerSettingsMenuItem
|
|
901
|
-
* @public
|
|
902
|
-
* @memberof UniverseService
|
|
903
|
-
* @param {String} title The title of the item
|
|
904
|
-
* @param {Object} options Additional options for the item
|
|
905
|
-
*/
|
|
906
|
-
registerSettingsMenuItem(title, options = {}) {
|
|
907
|
-
this.registerMenuItem('settings', title, options);
|
|
1243
|
+
return func.name;
|
|
908
1244
|
}
|
|
909
1245
|
|
|
910
1246
|
/**
|
|
@@ -992,7 +1328,7 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
992
1328
|
const componentParams = this._getOption(options, 'componentParams', {});
|
|
993
1329
|
const renderComponentInPlace = this._getOption(options, 'renderComponentInPlace', false);
|
|
994
1330
|
const slug = this._getOption(options, 'slug', dasherize(title));
|
|
995
|
-
const view = this._getOption(options, 'view');
|
|
1331
|
+
const view = this._getOption(options, 'view', dasherize(title));
|
|
996
1332
|
const queryParams = this._getOption(options, 'queryParams', {});
|
|
997
1333
|
const index = this._getOption(options, 'index', 0);
|
|
998
1334
|
const onClick = this._getOption(options, 'onClick', null);
|
|
@@ -1007,6 +1343,11 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1007
1343
|
const wrapperClass = this._getOption(options, 'wrapperClass', null);
|
|
1008
1344
|
const overwriteWrapperClass = this._getOption(options, 'overwriteWrapperClass', false);
|
|
1009
1345
|
const id = this._getOption(options, 'id', dasherize(title));
|
|
1346
|
+
const type = this._getOption(options, 'type', null);
|
|
1347
|
+
const buttonType = this._getOption(options, 'buttonType', null);
|
|
1348
|
+
const permission = this._getOption(options, 'permission', null);
|
|
1349
|
+
const disabled = this._getOption(options, 'disabled', null);
|
|
1350
|
+
const isLoading = this._getOption(options, 'isLoading', null);
|
|
1010
1351
|
|
|
1011
1352
|
// dasherize route segments
|
|
1012
1353
|
if (typeof route === 'string') {
|
|
@@ -1043,6 +1384,11 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1043
1384
|
inlineClass,
|
|
1044
1385
|
wrapperClass,
|
|
1045
1386
|
overwriteWrapperClass,
|
|
1387
|
+
type,
|
|
1388
|
+
buttonType,
|
|
1389
|
+
permission,
|
|
1390
|
+
disabled,
|
|
1391
|
+
isLoading,
|
|
1046
1392
|
};
|
|
1047
1393
|
|
|
1048
1394
|
return menuItem;
|
|
@@ -1120,6 +1466,7 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1120
1466
|
engineInstance.register(`component:${dasherize(componentClass.name.replace('Component', ''))}`, componentClass);
|
|
1121
1467
|
if (options && typeof options.registerAs === 'string') {
|
|
1122
1468
|
engineInstance.register(`component:${options.registerAs}`, componentClass);
|
|
1469
|
+
this.trigger('component.registered', componentClass, engineInstance);
|
|
1123
1470
|
}
|
|
1124
1471
|
}
|
|
1125
1472
|
}
|
|
@@ -1157,6 +1504,7 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1157
1504
|
if (sharedService) {
|
|
1158
1505
|
// Register the service in the target engine
|
|
1159
1506
|
targetEngineInstance.register(`service:${serviceName}`, sharedService, { instantiate: false });
|
|
1507
|
+
this.trigger('service.registered', serviceName, targetEngineInstance);
|
|
1160
1508
|
}
|
|
1161
1509
|
}
|
|
1162
1510
|
}
|
|
@@ -1275,6 +1623,7 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1275
1623
|
// store loaded instance to engineInstances for booting
|
|
1276
1624
|
engineInstances[name][instanceId] = engineInstance;
|
|
1277
1625
|
|
|
1626
|
+
this.trigger('engine.loaded', engineInstance);
|
|
1278
1627
|
return engineInstance.boot().then(() => {
|
|
1279
1628
|
return engineInstance;
|
|
1280
1629
|
});
|
|
@@ -1340,6 +1689,35 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1340
1689
|
return null;
|
|
1341
1690
|
}
|
|
1342
1691
|
|
|
1692
|
+
/**
|
|
1693
|
+
* Returns a promise that resolves when the `enginesBooted` property is set to true.
|
|
1694
|
+
* The promise will reject with a timeout error if the property does not become true within the specified timeout.
|
|
1695
|
+
*
|
|
1696
|
+
* @function booting
|
|
1697
|
+
* @returns {Promise<void>} A promise that resolves when `enginesBooted` is true or rejects with an error after a timeout.
|
|
1698
|
+
*/
|
|
1699
|
+
booting() {
|
|
1700
|
+
return new Promise((resolve, reject) => {
|
|
1701
|
+
const check = () => {
|
|
1702
|
+
if (this.enginesBooted === true) {
|
|
1703
|
+
this.trigger('booted');
|
|
1704
|
+
clearInterval(intervalId);
|
|
1705
|
+
resolve();
|
|
1706
|
+
}
|
|
1707
|
+
};
|
|
1708
|
+
|
|
1709
|
+
const intervalId = setInterval(check, 100);
|
|
1710
|
+
later(
|
|
1711
|
+
this,
|
|
1712
|
+
() => {
|
|
1713
|
+
clearInterval(intervalId);
|
|
1714
|
+
reject(new Error('Timeout: Universe was unable to boot engines'));
|
|
1715
|
+
},
|
|
1716
|
+
5000
|
|
1717
|
+
);
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1343
1721
|
/**
|
|
1344
1722
|
* Boot all installed engines, ensuring dependencies are resolved.
|
|
1345
1723
|
*
|
|
@@ -1362,10 +1740,13 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1362
1740
|
owner = getOwner(this);
|
|
1363
1741
|
}
|
|
1364
1742
|
|
|
1743
|
+
// Set application instance
|
|
1744
|
+
this.applicationInstance = owner;
|
|
1745
|
+
|
|
1365
1746
|
const tryBootEngine = (extension) => {
|
|
1366
1747
|
this.loadEngine(extension.name).then((engineInstance) => {
|
|
1367
1748
|
if (engineInstance.base && engineInstance.base.setupExtension) {
|
|
1368
|
-
if (
|
|
1749
|
+
if (this.bootedExtensions.includes(extension.name)) {
|
|
1369
1750
|
return;
|
|
1370
1751
|
}
|
|
1371
1752
|
|
|
@@ -1379,6 +1760,8 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1379
1760
|
|
|
1380
1761
|
engineInstance.base.setupExtension(owner, engineInstance, this);
|
|
1381
1762
|
booted.push(extension.name);
|
|
1763
|
+
this.bootedExtensions.pushObject(extension.name);
|
|
1764
|
+
this.trigger('extension.booted', extension);
|
|
1382
1765
|
debug(`Booted : ${extension.name}`);
|
|
1383
1766
|
|
|
1384
1767
|
// Try booting pending engines again
|
|
@@ -1391,7 +1774,7 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1391
1774
|
const stillPending = [];
|
|
1392
1775
|
|
|
1393
1776
|
pending.forEach(({ extension, engineInstance }) => {
|
|
1394
|
-
if (
|
|
1777
|
+
if (this.bootedExtensions.includes(extension.name)) {
|
|
1395
1778
|
return;
|
|
1396
1779
|
}
|
|
1397
1780
|
|
|
@@ -1401,6 +1784,8 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1401
1784
|
if (allDependenciesBooted) {
|
|
1402
1785
|
engineInstance.base.setupExtension(owner, engineInstance, this);
|
|
1403
1786
|
booted.push(extension.name);
|
|
1787
|
+
this.bootedExtensions.pushObject(extension.name);
|
|
1788
|
+
this.trigger('extension.booted', extension);
|
|
1404
1789
|
debug(`Booted : ${extension.name}`);
|
|
1405
1790
|
} else {
|
|
1406
1791
|
stillPending.push({ extension, engineInstance });
|
|
@@ -1414,10 +1799,12 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1414
1799
|
pending.push(...stillPending);
|
|
1415
1800
|
};
|
|
1416
1801
|
|
|
1417
|
-
loadInstalledExtensions(additionalCoreExtensions).then((extensions) => {
|
|
1802
|
+
return loadInstalledExtensions(additionalCoreExtensions).then((extensions) => {
|
|
1418
1803
|
extensions.forEach((extension) => {
|
|
1419
1804
|
tryBootEngine(extension);
|
|
1420
1805
|
});
|
|
1806
|
+
|
|
1807
|
+
this.enginesBooted = true;
|
|
1421
1808
|
});
|
|
1422
1809
|
}
|
|
1423
1810
|
|
|
@@ -1443,6 +1830,9 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1443
1830
|
owner = getOwner(this);
|
|
1444
1831
|
}
|
|
1445
1832
|
|
|
1833
|
+
// Set application instance
|
|
1834
|
+
this.applicationInstance = owner;
|
|
1835
|
+
|
|
1446
1836
|
const tryBootEngine = (extension) => {
|
|
1447
1837
|
this.loadEngine(extension.name).then((engineInstance) => {
|
|
1448
1838
|
if (engineInstance.base && engineInstance.base.setupExtension) {
|
|
@@ -1458,6 +1848,8 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1458
1848
|
|
|
1459
1849
|
engineInstance.base.setupExtension(owner, engineInstance, this);
|
|
1460
1850
|
booted.push(extension.name);
|
|
1851
|
+
this.bootedExtensions.pushObject(extension.name);
|
|
1852
|
+
this.trigger('extension.booted', extension);
|
|
1461
1853
|
debug(`Booted : ${extension.name}`);
|
|
1462
1854
|
|
|
1463
1855
|
// Try booting pending engines again
|
|
@@ -1476,6 +1868,8 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1476
1868
|
if (allDependenciesBooted) {
|
|
1477
1869
|
engineInstance.base.setupExtension(owner, engineInstance, this);
|
|
1478
1870
|
booted.push(extension.name);
|
|
1871
|
+
this.bootedExtensions.pushObject(extension.name);
|
|
1872
|
+
this.trigger('extension.booted', extension);
|
|
1479
1873
|
debug(`Booted : ${extension.name}`);
|
|
1480
1874
|
} else {
|
|
1481
1875
|
stillPending.push({ extension, engineInstance });
|
|
@@ -1489,13 +1883,26 @@ export default class UniverseService extends Service.extend(Evented) {
|
|
|
1489
1883
|
pending.push(...stillPending);
|
|
1490
1884
|
};
|
|
1491
1885
|
|
|
1492
|
-
loadExtensions().then((extensions) => {
|
|
1886
|
+
return loadExtensions().then((extensions) => {
|
|
1493
1887
|
extensions.forEach((extension) => {
|
|
1494
1888
|
tryBootEngine(extension);
|
|
1495
1889
|
});
|
|
1890
|
+
|
|
1891
|
+
this.enginesBooted = true;
|
|
1496
1892
|
});
|
|
1497
1893
|
}
|
|
1498
1894
|
|
|
1895
|
+
/**
|
|
1896
|
+
* Checks if an extension has been booted.
|
|
1897
|
+
*
|
|
1898
|
+
* @param {String} name
|
|
1899
|
+
* @return {Boolean}
|
|
1900
|
+
* @memberof UniverseService
|
|
1901
|
+
*/
|
|
1902
|
+
didBootEngine(name) {
|
|
1903
|
+
return this.bootedExtensions.includes(name);
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1499
1906
|
/**
|
|
1500
1907
|
* Alias for intl service `t`
|
|
1501
1908
|
*
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import { isBlank } from '@ember/utils';
|
|
2
|
+
|
|
1
3
|
export default function isEmptyObject(obj) {
|
|
2
|
-
|
|
4
|
+
if (isBlank(obj)) {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return obj.constructor === Object && Object.keys(obj).length === 0;
|
|
3
9
|
}
|
|
@@ -8,17 +8,12 @@ export default function serializeNormalizeRelationsWithinHash(hash, primaryKey =
|
|
|
8
8
|
|
|
9
9
|
for (let attr in hash) {
|
|
10
10
|
if (typeof attr === 'string' && attr.includes('_uuid')) {
|
|
11
|
-
// console.log(attr, hash[attr]);
|
|
12
11
|
if (typeof hash[attr] === 'object' && !isBlank(hash[attr])) {
|
|
13
12
|
// the relation has loaded back into `_uuid` - change this to the proper `uuid` string value and set the relationship
|
|
14
13
|
const relation = hash[attr];
|
|
15
14
|
const id = get(relation, primaryKey);
|
|
16
15
|
const relationAttr = attr.replace('_uuid', '');
|
|
17
16
|
|
|
18
|
-
// console.log(`normalizing relation ${relationAttr} from ${attr}`);
|
|
19
|
-
// console.log(relationAttr, relation);
|
|
20
|
-
// console.log(attr, id);
|
|
21
|
-
|
|
22
17
|
setProperties(hash, {
|
|
23
18
|
[relationAttr]: relation,
|
|
24
19
|
[attr]: id,
|
package/package.json
CHANGED