dashboard/shell/plugins/plugin.js

75 lines
2.3 KiB
JavaScript

// This plugin loads any UI Plugins at app load time
import { allHashSettled } from '@shell/utils/promise';
import { shouldLoadPlugin, UI_PLUGIN_BASE_URL } from '@shell/config/uiplugins';
const META_NAME_PREFIX = 'app-autoload-';
export default async(context) => {
// UI Plugins declared in the HTML head
const meta = context.app?.head?.meta || [];
const hash = {};
meta.forEach((m) => {
const metaName = m.name || '';
if (metaName.indexOf(META_NAME_PREFIX) === 0) {
const name = metaName.substr(META_NAME_PREFIX.length);
hash[name] = context.$plugin.loadAsync(name, m.content);
}
});
// Provide a mechanism to load the UI without the plugins loaded - in case there is a problem
let loadPlugins = true;
if (context.route?.path.endsWith('/safeMode')) {
loadPlugins = false;
console.warn('Safe Mode - plugins will not be loaded'); // eslint-disable-line no-console
}
if (loadPlugins) {
const { store, $plugin } = context;
// Fetch list of installed plugins from endpoint
try {
const res = await store.dispatch('management/request', {
url: `${ UI_PLUGIN_BASE_URL }/index.json`,
headers: { accept: 'application/json' }
});
if (res) {
const entries = res.entries || res.Entries || {};
Object.values(entries).forEach((plugin) => {
if (shouldLoadPlugin(plugin)) {
let url;
if (plugin?.metadata?.['direct'] === 'true') {
url = plugin.endpoint;
}
hash[plugin.name] = $plugin.loadAsyncByNameAndVersion(plugin.name, plugin.version, url);
}
});
}
} catch (e) {
console.error('Could not load UI Plugin list', e); // eslint-disable-line no-console
}
// Load all of the plugins
const pluginLoads = await allHashSettled(hash);
// Some pluigns may have failed to load - store this
Object.keys(pluginLoads).forEach((name) => {
const res = pluginLoads[name];
if (res?.status === 'rejected') {
console.error(`Failed to load plugin: ${ name }`); // eslint-disable-line no-console
// Record error in the uiplugins store, so that we can show this to the user
context.store.dispatch('uiplugins/setError', { name, error: true });
}
});
}
};