Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions addon/services/universe.js
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,50 @@ export default class UniverseService extends Service.extend(Evented) {
this.widgetService.registerDashboard(name, options);
}

/**
* Register a dashboard render slot.
*
* @method registerDashboardSlot
* @param {String} slotId Dashboard slot identifier
* @param {Object} options Slot options
*/
registerDashboardSlot(slotId, options = {}) {
this.widgetService.registerDashboardSlot(slotId, options);
}

/**
* Register a system dashboard for a render slot.
*
* @method registerDashboardForSlot
* @param {String} slotId Dashboard slot identifier
* @param {String} dashboardName Dashboard widget namespace
* @param {Object} options Dashboard slot options
*/
registerDashboardForSlot(slotId, dashboardName, options = {}) {
this.widgetService.registerDashboardForSlot(slotId, dashboardName, options);
}

/**
* Set the first system dashboard for a render slot.
*
* @method setDefaultDashboardForSlot
* @param {String} slotId Dashboard slot identifier
* @param {String} dashboardName Dashboard widget namespace
*/
setDefaultDashboardForSlot(slotId, dashboardName) {
this.widgetService.setDefaultDashboardForSlot(slotId, dashboardName);
}

/**
* Set the dashboard that should load first on the console home.
*
* @method setConsoleDashboard
* @param {String} dashboardName Dashboard widget namespace
*/
setConsoleDashboard(dashboardName) {
this.widgetService.setConsoleDashboard(dashboardName);
}

/**
* Get dashboard widgets
*
Expand Down
100 changes: 100 additions & 0 deletions addon/services/universe/widget-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,106 @@ export default class WidgetService extends Service {
this.registry.register('dashboards', 'dashboard', name, dashboard);
}

/**
* Register a dashboard render slot.
*
* Slots describe where dashboards render (for example `console.home`),
* while dashboard names continue to describe widget namespaces.
*
* @method registerDashboardSlot
* @param {String} slotId Slot identifier
* @param {Object} options Slot options
*/
registerDashboardSlot(slotId, options = {}) {
const slot = {
id: slotId,
...options,
};

this.registry.register('dashboard:slots', 'slot', slotId, slot);
}

/**
* Register a system dashboard that should be available in a render slot.
*
* @method registerDashboardForSlot
* @param {String} slotId Slot identifier
* @param {String} dashboardName Dashboard widget namespace
* @param {Object} options Dashboard slot options
*/
registerDashboardForSlot(slotId, dashboardName, options = {}) {
this.registerDashboardSlot(slotId);
this.registerDashboard(dashboardName, options);

const dashboard = {
id: dashboardName,
dashboardId: dashboardName,
name: options.name ?? options.defaultDashboardName ?? dashboardName,
extension: options.extension ?? 'core',
priority: options.priority ?? 0,
...options,
};

this.registry.register('dashboard:slots', 'dashboard', `${slotId}#${dashboardName}`, {
slotId,
...dashboard,
});
}

/**
* Set the system dashboard that should load first for a render slot.
*
* @method setDefaultDashboardForSlot
* @param {String} slotId Slot identifier
* @param {String} dashboardName Dashboard widget namespace
*/
setDefaultDashboardForSlot(slotId, dashboardName) {
this.registerDashboardSlot(slotId);
this.registry.register('dashboard:slots', 'default', slotId, {
slotId,
dashboardId: dashboardName,
});
}

/**
* Convenience alias for setting the console home dashboard.
*
* @method setConsoleDashboard
* @param {String} dashboardName Dashboard widget namespace
*/
setConsoleDashboard(dashboardName) {
this.setDefaultDashboardForSlot('console.home', dashboardName);
}

/**
* Get system dashboards registered for a slot.
*
* @method getDashboardsForSlot
* @param {String} slotId Slot identifier
* @returns {Array} Slot dashboard registrations
*/
getDashboardsForSlot(slotId) {
if (!slotId) {
return [];
}

const prefix = `${slotId}#`;
return [...this.registry.getRegistry('dashboard:slots', 'dashboard')]
.filter((dashboard) => dashboard?._registryKey?.startsWith(prefix))
.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
}

/**
* Get the dashboard namespace that should load first for a slot.
*
* @method getDefaultDashboardForSlot
* @param {String} slotId Slot identifier
* @returns {String|null} Dashboard namespace
*/
getDefaultDashboardForSlot(slotId) {
return this.registry.lookup('dashboard:slots', 'default', slotId)?.dashboardId ?? null;
}

/**
* Register widgets to a specific dashboard
* Makes these widgets available for selection on the dashboard
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fleetbase/ember-core",
"version": "0.3.22",
"version": "0.3.23",
"description": "Provides all the core services, decorators and utilities for building a Fleetbase extension for the Console.",
"keywords": [
"fleetbase-core",
Expand Down
62 changes: 62 additions & 0 deletions tests/unit/services/universe/widget-service-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { module, test } from 'qunit';
import { setupTest } from 'dummy/tests/helpers';
import Service from '@ember/service';

class RegistryStubService extends Service {
registries = new Map();

register(section, list, key, value) {
const registryKey = `${section}:${list}`;
const registry = this.registries.get(registryKey) ?? [];
const record = { ...value, _registryKey: key };
const existingIndex = registry.findIndex((item) => item._registryKey === key);

if (existingIndex === -1) {
registry.push(record);
} else {
registry[existingIndex] = record;
}

this.registries.set(registryKey, registry);
}

getRegistry(section, list) {
return this.registries.get(`${section}:${list}`) ?? [];
}

lookup(section, list, key) {
return this.getRegistry(section, list).find((item) => item._registryKey === key) ?? null;
}
}

module('Unit | Service | universe/widget-service', function (hooks) {
setupTest(hooks);

hooks.beforeEach(function () {
this.owner.register('service:universe/registry-service', RegistryStubService);
});

test('it registers multiple system dashboards for a dashboard slot', function (assert) {
const service = this.owner.lookup('service:universe/widget-service');

service.registerDashboardForSlot('console.home', 'dashboard', {
name: 'Default Dashboard',
priority: 0,
});
service.registerDashboardForSlot('console.home', 'alrashd', {
name: 'Al-Rashed KPI Dashboard',
priority: 10,
});
service.setConsoleDashboard('alrashd');

const dashboards = service.getDashboardsForSlot('console.home');

assert.deepEqual(
dashboards.map((dashboard) => dashboard.id),
['alrashd', 'dashboard'],
'slot dashboards are returned by priority'
);
assert.strictEqual(service.getDefaultDashboardForSlot('console.home'), 'alrashd', 'console shortcut sets the console home default');
assert.strictEqual(service.getDashboard('alrashd').name, 'Al-Rashed KPI Dashboard', 'dashboard namespace metadata is registered');
});
});
Loading