ui: add community overlay slots
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
(function() {
|
||||
var manifestPromise = null;
|
||||
var loadedScripts = Object.create(null);
|
||||
|
||||
function overlayBasePath() {
|
||||
return (window.APP_BASE || '/') + 'overlay/';
|
||||
}
|
||||
|
||||
function fetchManifest() {
|
||||
return fetch(overlayBasePath() + 'manifest.json', { cache: 'no-store' })
|
||||
.then(function(response) {
|
||||
if (response.status === 404) {
|
||||
return null;
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error('overlay manifest request failed');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.catch(function() {
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
function loadScript(path) {
|
||||
if (loadedScripts[path]) {
|
||||
return loadedScripts[path];
|
||||
}
|
||||
loadedScripts[path] = new Promise(function(resolve, reject) {
|
||||
var script = document.createElement('script');
|
||||
script.src = overlayBasePath() + path.replace(/^\/+/, '');
|
||||
script.async = false;
|
||||
script.onload = function() { resolve(); };
|
||||
script.onerror = function() { reject(new Error('overlay script load failed')); };
|
||||
document.head.appendChild(script);
|
||||
}).catch(function() {
|
||||
return null;
|
||||
});
|
||||
return loadedScripts[path];
|
||||
}
|
||||
|
||||
function load() {
|
||||
if (manifestPromise) {
|
||||
return manifestPromise;
|
||||
}
|
||||
manifestPromise = fetchManifest().then(function(manifest) {
|
||||
if (!(manifest && manifest.slots && window.CrankUiSlots)) {
|
||||
return null;
|
||||
}
|
||||
var tasks = Object.entries(manifest.slots)
|
||||
.filter(function(entry) {
|
||||
return window.CrankUiSlots.isAllowed(entry[0]) && typeof entry[1] === 'string';
|
||||
})
|
||||
.map(function(entry) {
|
||||
return loadScript(entry[1]);
|
||||
});
|
||||
return Promise.all(tasks).then(function() {
|
||||
return manifest;
|
||||
});
|
||||
});
|
||||
return manifestPromise;
|
||||
}
|
||||
|
||||
async function render(root, context) {
|
||||
await load();
|
||||
if (window.CrankUiSlots) {
|
||||
window.CrankUiSlots.renderAll(root, context);
|
||||
}
|
||||
}
|
||||
|
||||
window.CrankOverlay = {
|
||||
load: load,
|
||||
render: render,
|
||||
};
|
||||
}());
|
||||
+22
-4
@@ -193,6 +193,19 @@ async function loadCapabilities() {
|
||||
}
|
||||
}
|
||||
|
||||
async function renderOverlaySlots() {
|
||||
if (!window.CrankOverlay || typeof window.CrankOverlay.render !== 'function') {
|
||||
return;
|
||||
}
|
||||
|
||||
await (window.whenWorkspacesReady ? window.whenWorkspacesReady() : Promise.resolve());
|
||||
await window.CrankOverlay.render(document, {
|
||||
workspace: window.getCurrentWorkspace ? window.getCurrentWorkspace() : null,
|
||||
capabilities: settingsCapabilities,
|
||||
locale: localStorage.getItem('crank_lang') || 'en',
|
||||
});
|
||||
}
|
||||
|
||||
function bindProfileSave() {
|
||||
var button = document.getElementById('settings-profile-save-btn');
|
||||
if (!button || button.dataset.bound === 'true') {
|
||||
@@ -418,12 +431,17 @@ async function loadWorkspaceSettings() {
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
async function initSettingsPage() {
|
||||
injectLanguageSwitcher();
|
||||
bindSectionNavigation();
|
||||
loadProfile();
|
||||
loadCapabilities();
|
||||
await loadProfile();
|
||||
await loadCapabilities();
|
||||
bindProfileSave();
|
||||
bindPasswordSave();
|
||||
loadWorkspaceSettings();
|
||||
await loadWorkspaceSettings();
|
||||
await renderOverlaySlots();
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
void initSettingsPage();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
(function() {
|
||||
var allowedSlots = {
|
||||
'settings.sso_panel': true,
|
||||
'settings.totp_panel': true,
|
||||
'settings.audit_panel': true,
|
||||
'settings.billing_panel': true,
|
||||
'wizard.protocol_cards.graphql': true,
|
||||
'wizard.protocol_cards.grpc': true,
|
||||
'wizard.protocol_cards.soap': true,
|
||||
'wizard.protocol_cards.websocket': true,
|
||||
};
|
||||
|
||||
var handlers = Object.create(null);
|
||||
|
||||
function noop() {}
|
||||
|
||||
function isAllowed(slotId) {
|
||||
return !!allowedSlots[slotId];
|
||||
}
|
||||
|
||||
function register(slotId, render) {
|
||||
if (!isAllowed(slotId) || typeof render !== 'function') {
|
||||
return false;
|
||||
}
|
||||
handlers[slotId] = render;
|
||||
return true;
|
||||
}
|
||||
|
||||
function renderInto(target, slotId, context) {
|
||||
if (!(target && slotId && isAllowed(slotId))) {
|
||||
return;
|
||||
}
|
||||
var handler = handlers[slotId] || noop;
|
||||
handler(target, context || {});
|
||||
}
|
||||
|
||||
function renderAll(root, context) {
|
||||
var scope = root || document;
|
||||
scope.querySelectorAll('[data-slot]').forEach(function(target) {
|
||||
renderInto(target, target.getAttribute('data-slot'), context);
|
||||
});
|
||||
}
|
||||
|
||||
function knownSlots() {
|
||||
return Object.keys(allowedSlots);
|
||||
}
|
||||
|
||||
window.CrankUiSlots = {
|
||||
isAllowed: isAllowed,
|
||||
knownSlots: knownSlots,
|
||||
register: register,
|
||||
renderAll: renderAll,
|
||||
renderInto: renderInto,
|
||||
};
|
||||
}());
|
||||
@@ -86,9 +86,16 @@ async function initWizardPage() {
|
||||
await loadProtocolCapabilities();
|
||||
|
||||
await loadWizardPanels([1, 2, 3, 4, 5]);
|
||||
applyEditionProtocolVisibility(editionCapabilities);
|
||||
if (window.CrankOverlay && typeof window.CrankOverlay.render === 'function') {
|
||||
await window.CrankOverlay.render(document, {
|
||||
workspace: workspace,
|
||||
capabilities: editionCapabilities,
|
||||
locale: localStorage.getItem('crank_lang') || 'en',
|
||||
});
|
||||
}
|
||||
await loadWizardAuthResources();
|
||||
bindProtocolCards();
|
||||
applyEditionProtocolVisibility(editionCapabilities);
|
||||
bindWizardLiveActions();
|
||||
updateUpstreamAuthUi();
|
||||
renderEditionCapabilityHints(editionCapabilities);
|
||||
|
||||
Reference in New Issue
Block a user