new extension injector component for installed extensions from registry bridge WIP, need to figure out mounted extensions

This commit is contained in:
Ronald A. Richardson
2024-06-20 17:30:25 +08:00
parent cd5a7370b9
commit 6338820372
7 changed files with 97 additions and 27 deletions

View File

@@ -0,0 +1 @@
{{yield}}

View File

@@ -0,0 +1,95 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { isArray } from '@ember/array';
import { getOwner } from '@ember/application';
import { task, timeout } from 'ember-concurrency';
import loadExtensions from '@fleetbase/ember-core/utils/load-extensions';
export default class ExtensionInjectorComponent extends Component {
@service fetch;
@service notifications;
@service universe;
@tracked engines = [];
@tracked packages = [];
constructor () {
super(...arguments);
this.loadInstalledEngines.perform();
}
@task *loadInstalledEngines () {
yield timeout(300);
try {
const engines = yield this.fetch.get('load-installed-engines', {}, { namespace: '~registry/v1' });
if (isArray(engines)) {
engines.forEach(extensionId => {
this.loadExtensionFromManifest.perform(extensionId);
});
}
} catch (error) {
this.notifications.serverError(error);
}
}
@task *loadExtensionFromManifest (extensionId) {
try {
const assets = yield this.fetch.get(`load-engine-manifest/${extensionId}`, {}, { namespace: '~registry/v1' });
if (isArray(assets)) {
assets.forEach(asset => {
this.inject(asset);
});
}
} catch (error) {
this.notifications.serverError(error);
}
this.initializeExtensions();
}
initializeExtensions () {
const owner = getOwner(this);
this.packages.forEach(packageJson => {
this.universe.loadEngine(packageJson.name).then(engineInstance => {
if (engineInstance.base && engineInstance.base.setupExtension) {
engineInstance.base.setupExtension(owner, engineInstance, this.universe);
}
});
});
}
inject ({ type, content }) {
switch (type) {
case 'package':
this.packages.pushObject(content);
return;
case 'css':
return this.injectStylesheet(content);
case 'js':
default:
return this.injectScript(content);
}
}
injectScript (content) {
const script = document.createElement('script');
script.type = 'application/javascript';
script.text = content;
document.head.appendChild(script);
}
injectStylesheet (content) {
const style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
// This is required for IE8 and below.
style.styleSheet.cssText = content;
} else {
// For most browsers
style.appendChild(document.createTextNode(content));
}
document.head.appendChild(style);
}
}

View File

@@ -1,3 +0,0 @@
import Route from '@ember/routing/route';
export default class ConsoleExtensionsRoute extends Route {}

View File

@@ -16,3 +16,4 @@
</Layout::Container>
<ChatContainer />
<ConsoleWormhole />
<ExtensionInjector />

View File

@@ -1,12 +0,0 @@
{{page-title "Extensions"}}
<Layout::Section::Body class="overflow-y-scroll h-full pt-6">
<div class="container mx-auto h-screen space-y-4">
<div class="flex flex-col items-center justify-center pt-14 px-40">
<FaIcon @icon="shapes" @size="4x" class="mb-6 text-blue-500" />
<h1 class="dark:text-gray-100 text-black text-4xl font-bold mb-4">{{t "console.extensions.title"}}</h1>
<p class="dark:text-gray-300 text-black text-lg">
{{t "console.extensions.message"}}
</p>
</div>
</div>
</Layout::Section::Body>

View File

@@ -23,7 +23,6 @@ Router.map(function () {
});
this.route('console', { path: '/' }, function () {
this.route('home', { path: '/' });
this.route('extensions');
this.route('notifications');
this.route('account', function () {
this.route('virtual', { path: '/:slug/:view' });

View File

@@ -1,11 +0,0 @@
import { module, test } from 'qunit';
import { setupTest } from '@fleetbase/console/tests/helpers';
module('Unit | Route | console/extensions', function (hooks) {
setupTest(hooks);
test('it exists', function (assert) {
let route = this.owner.lookup('route:console/extensions');
assert.ok(route);
});
});