kui-shell
Version:
This is the monorepo for Kui, the hybrid command-line/GUI electron-based Kubernetes tool
549 lines • 24.9 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const debug_1 = require("debug");
const debug = debug_1.default('webapp/views/sidecar');
debug('loading');
const uuid = require("uuid/v4");
const prettyPrintDuration = require("pretty-ms");
const sidecar_core_1 = require("./sidecar-core");
exports.getSidecar = sidecar_core_1.getSidecar;
const sidecar_present_1 = require("./sidecar-present");
const custom_content_1 = require("./custom-content");
exports.isCustomSpec = custom_content_1.isCustomSpec;
const badge_1 = require("./badge");
const popup_core_1 = require("../popup-core");
const tab_1 = require("../tab");
const sidecar_visibility_1 = require("./sidecar-visibility");
exports.isVisible = sidecar_visibility_1.isVisible;
exports.toggle = sidecar_visibility_1.toggle;
exports.show = sidecar_visibility_1.show;
exports.hide = sidecar_visibility_1.hide;
exports.clearSelection = sidecar_visibility_1.clearSelection;
exports.currentSelection = sidecar_visibility_1.currentSelection;
exports.setMaximization = sidecar_visibility_1.setMaximization;
exports.toggleMaximization = sidecar_visibility_1.toggleMaximization;
exports.remove = sidecar_visibility_1.remove;
const events_1 = require("../../core/events");
const dom_1 = require("../util/dom");
const time_1 = require("../util/time");
const bottom_stripe_1 = require("../bottom-stripe");
const show_options_1 = require("./show-options");
const toolbar_text_1 = require("./toolbar-text");
const presentation_1 = require("./presentation");
const entity_1 = require("../../models/entity");
exports.isMetadataBearingByReference = entity_1.isMetadataBearingByReference;
const badges_1 = require("./registrar/badges");
const editors_1 = require("./registrar/editors");
const types_1 = require("../../util/types");
debug('finished loading modules');
exports.beautify = (kind, code) => {
return code;
};
exports.maybeHideEntity = (tab, entity) => {
const sidecar = sidecar_core_1.getSidecar(tab);
const entityMatchesSelection = sidecar.entity && sidecar.entity.name === entity.name && sidecar.entity.namespace === entity.namespace;
debug('maybeHideEntity', entityMatchesSelection, entity, sidecar.entity);
if (entityMatchesSelection) {
sidecar_visibility_1.clearSelection(tab);
return true;
}
};
exports.getActiveView = (tab) => {
const sidecar = sidecar_core_1.getSidecar(tab);
const activeView = sidecar.getAttribute('data-active-view');
const container = sidecar.querySelector(`.sidecar-content-container ${activeView}`);
return container;
};
function isHTML(content) {
return typeof content !== 'string' && content.nodeName !== undefined;
}
exports.linkify = (dom) => {
const attrs = dom.querySelectorAll('.hljs-attr');
for (let idx = 0; idx < attrs.length; idx++) {
const attr = attrs[idx];
if (attr.innerText.indexOf('http') === 0) {
const link = document.createElement('a');
link.href = attr.innerText;
link.innerText = attr.innerText.substring(attr.innerText.lastIndexOf('/') + 1);
link.target = '_blank';
attr.innerText = '';
attr.appendChild(link);
}
}
};
exports.addVersionBadge = (tab, entity, { clear = false, badgesDom = undefined } = {}) => {
if (clear) {
badge_1.clearBadges(tab);
}
if (entity_1.isMetadataBearing(entity)) {
const version = entity.metadata.generation;
if (version) {
badge_1.addBadge(tab, /^v/.test(version) ? version : `v${version}`, { badgesDom }).classList.add('version');
return;
}
}
const version = entity.version || (entity_1.isMetadataBearingByReference(entity) && entity.resource.metadata.generation);
if (version) {
badge_1.addBadge(tab, /^v/.test(version) ? version : `v${version}`, { badgesDom }).classList.add('version');
}
};
exports.addSidecarHeaderIconText = (viewName, sidecar) => {
debug('addSidecarHeaderIconText', viewName);
const iconDom = dom_1.element('.sidecar-header-icon', sidecar);
if (viewName) {
let iconText = viewName.replace(/s$/, '');
const A = iconText.split(/(?=[A-Z])/).filter(x => x);
if (iconText.length > 12 && A.length > 1) {
iconText = A.map(_ => _.charAt(0)).join('');
}
iconDom.innerText = iconText;
}
else {
iconDom.innerText = '';
}
};
const createdOn = (resource, entity) => {
const startTime = resource.metadata.creationTimestamp;
const prefixText = entity.createdOnString
? `${entity.createdOnString} `
: 'Created on ';
if (!startTime) {
return;
}
const message = document.createElement('div');
const datePart = document.createElement('span');
message.appendChild(document.createTextNode(prefixText));
message.appendChild(datePart);
try {
datePart.appendChild(time_1.prettyPrintTime(Date.parse(startTime)));
}
catch (err) {
debug('error trying to parse this creationTimestamp', resource);
console.error('error parsing creationTimestamp', err);
datePart.innerText = resource.metadata.creationTimestamp;
}
return message;
};
exports.addNameToSidecarHeader = (sidecar, name, packageName = '', onclick, viewName, subtext, entity) => __awaiter(void 0, void 0, void 0, function* () {
debug('addNameToSidecarHeader', name, entity_1.isMetadataBearingByReference(entity), entity);
const metadataBearer = entity_1.isMetadataBearingByReference(entity) ? entity.resource : entity_1.isMetadataBearing(entity) && entity;
if (metadataBearer) {
const maybeName = name || (metadataBearer.spec && metadataBearer.spec.displayName) || metadataBearer.metadata.name;
if (maybeName) {
name = maybeName;
}
if (metadataBearer.metadata.namespace) {
packageName = metadataBearer.metadata.namespace;
}
if (metadataBearer.kind) {
viewName = metadataBearer.kind;
}
}
const header = sidecar.querySelector('.sidecar-header');
const footer = sidecar.querySelector('.sidecar-bottom-stripe');
const nameDom = header.querySelector('.sidecar-header-name-content');
nameDom.className = nameDom.getAttribute('data-base-class');
dom_1.element('.package-prefix', footer).innerText = packageName;
if (custom_content_1.isCustomSpec(entity) && entity.isREPL) {
header.querySelector('.sidecar-header-text').classList.add('is-repl-like');
}
else {
header.querySelector('.sidecar-header-text').classList.remove('is-repl-like');
}
if (typeof name === 'string') {
if (custom_content_1.isCustomSpec(entity) && entity.isREPL) {
}
else {
const nameContainer = dom_1.element('.entity-name', nameDom);
nameContainer.innerText = name;
}
}
else if (name) {
const nameContainer = nameDom.querySelector('.entity-name');
dom_1.removeAllDomChildren(nameContainer);
nameContainer.appendChild(name);
}
if (onclick) {
const clickable = dom_1.element('.entity-name', nameDom);
clickable.classList.add('clickable');
clickable.onclick = onclick;
}
exports.addSidecarHeaderIconText(viewName, sidecar);
if (!subtext && metadataBearer) {
const maybe = createdOn(metadataBearer, custom_content_1.isCustomSpec(entity) && entity);
if (maybe) {
subtext = maybe;
}
}
if (subtext && !toolbar_text_1.isToolbarText(subtext) && custom_content_1.isCustomSpec(entity) && entity.toolbarText) {
const subtextContainer = sidecar.querySelector('.sidecar-header-secondary-content .custom-header-content');
dom_1.removeAllDomChildren(subtextContainer);
Promise.resolve(subtext).then(subtext => {
if (typeof subtext === 'string') {
subtextContainer.innerText = subtext;
}
else {
subtextContainer.appendChild(subtext);
}
});
}
const toolbarTextSpec = toolbar_text_1.isToolbarText(subtext)
? subtext
: custom_content_1.isCustomSpec(entity) &&
(entity.toolbarText || (entity_1.isMetadataBearingByReference(entity) && entity.resource.toolbarText));
const toolbarTextContainer = dom_1.element('.sidecar-bottom-stripe-toolbar .sidecar-toolbar-text', sidecar);
const toolbarTextContent = dom_1.element('.sidecar-toolbar-text-content', toolbarTextContainer);
dom_1.removeAllDomChildren(toolbarTextContent);
if (toolbarTextSpec) {
if (toolbar_text_1.isRefreshableToolbarText(toolbarTextSpec)) {
toolbarTextSpec.attach(sidecar).refresh();
}
else {
new toolbar_text_1.ToolbarTextImpl(toolbarTextSpec.type, toolbarTextSpec.text).attach(sidecar).refresh();
}
}
else if (subtext && !toolbar_text_1.isToolbarText(subtext)) {
const text = yield Promise.resolve(subtext);
toolbarTextContainer.setAttribute('data-type', 'info');
if (text instanceof Element) {
toolbarTextContent.appendChild(text);
}
else {
toolbarTextContent.innerText = text;
}
}
else {
toolbarTextContent.innerText = '';
toolbarTextContainer.removeAttribute('data-type');
}
return nameDom;
});
exports.isFullscreen = (tab) => {
return tab.classList.contains('sidecar-full-screen');
};
exports.showCustom = (tab, custom, options, resultDom) => __awaiter(void 0, void 0, void 0, function* () {
if (!custom || custom.content === undefined)
return;
debug('showCustom', custom, options, resultDom);
const sidecar = sidecar_core_1.getSidecar(tab);
sidecar_visibility_1.enableTabIndex(sidecar);
if (sidecar.entity || sidecar.uuid) {
events_1.default.emit('/sidecar/replace', sidecar.uuid || sidecar.entity);
}
sidecar.uuid = custom.uuid || uuid();
const hashDom = dom_1.element('.sidecar-header-name .entity-name-hash', sidecar);
hashDom.innerText = '';
const viewProviderDesiresFullscreen = custom.presentation === presentation_1.default.SidecarFullscreen ||
(popup_core_1.isPopup() &&
(custom.presentation === presentation_1.default.SidecarFullscreenForPopups ||
custom.presentation === presentation_1.default.FixedSize));
if (!custom.presentation && !popup_core_1.isPopup()) {
sidecar_present_1.default(tab, presentation_1.default.Default);
}
else if (custom.presentation ||
popup_core_1.isPopup() ||
(viewProviderDesiresFullscreen ? !exports.isFullscreen(tab) : exports.isFullscreen(tab))) {
const presentation = custom.presentation ||
(viewProviderDesiresFullscreen
? presentation_1.default.SidecarFullscreenForPopups
: custom.presentation !== undefined
? custom.presentation
: presentation_1.default.SidecarFullscreen);
sidecar_present_1.default(tab, presentation);
if (viewProviderDesiresFullscreen) {
sidecar_visibility_1.setMaximization(tab);
}
}
else {
sidecar_present_1.default(tab, presentation_1.default.Default);
}
if (custom.controlHeaders === true) {
}
else if (!custom.controlHeaders) {
const customHeaders = sidecar.querySelectorAll('.custom-header-content');
for (let idx = 0; idx < customHeaders.length; idx++) {
dom_1.removeAllDomChildren(customHeaders[idx]);
}
}
else {
custom.controlHeaders.forEach((_) => {
const customHeaders = sidecar.querySelectorAll(`${_} .custom-header-content`);
for (let idx = 0; idx < customHeaders.length; idx++) {
dom_1.removeAllDomChildren(customHeaders[idx]);
}
});
}
const customContent = sidecar.querySelector('.custom-content');
if (custom.noZoom) {
customContent.classList.remove('zoomable');
}
else {
customContent.classList.add('zoomable');
}
sidecar.setAttribute('data-active-view', '.custom-content > div');
const modes = custom.modes;
if (!options || !options.leaveBottomStripeAlone) {
bottom_stripe_1.addModeButtons(tab, modes, custom, options);
sidecar.setAttribute('class', `${sidecar.getAttribute('data-base-class')} custom-content`);
}
else {
sidecar.classList.add('custom-content');
}
sidecar_visibility_1.setVisibleClass(sidecar);
if (custom.sidecarHeader === false) {
sidecar.classList.add('no-sidecar-header');
}
if (custom.displayOptions) {
custom.displayOptions.forEach(option => {
sidecar.classList.add(option.replace(/\s/g, '-'));
});
}
const { badgesDomContainer, badgesDom } = badge_1.getBadgesDomContainer(sidecar);
if (custom && (custom.isEntity || entity_1.isMetadataBearing(custom) || entity_1.isMetadataBearingByReference(custom))) {
const entity = custom;
sidecar.entity = entity;
if (sidecar.entity.viewName) {
sidecar.entity.type = sidecar.entity.viewName;
}
const prettyName = (entity.prettyName || entity_1.isMetadataBearingByReference(custom) ? custom.resource.prettyName : undefined) ||
entity.name;
hashDom.innerText =
(entity.nameHash !== undefined
? entity.nameHash
: entity_1.isMetadataBearingByReference(custom)
? custom.resource.nameHash
: undefined) || '';
exports.addNameToSidecarHeader(sidecar, prettyName, entity.packageName || entity.namespace, undefined, entity.prettyType || entity.type || entity.kind, entity.subtext, entity);
exports.addVersionBadge(tab, entity, { clear: true, badgesDom });
if (custom.duration) {
const duration = document.createElement('div');
duration.classList.add('activation-duration');
duration.innerText = prettyPrintDuration(custom.duration);
badgesDomContainer.appendChild(duration);
}
}
if (custom && custom.badges) {
custom.badges.forEach(badge => badge_1.addBadge(tab, badge, { badgesDom }));
}
if (entity_1.isMetadataBearing(custom) || entity_1.isMetadataBearingByReference(custom)) {
const badgeOptions = {
badgesDom: sidecar.querySelector('.sidecar-header .custom-header-content .badges')
};
badges_1.apply(tab, entity_1.isMetadataBearingByReference(custom) ? custom : { resource: custom }, badgeOptions);
}
const replView = tab.querySelector('.repl');
replView.className = `sidecar-visible ${(replView.getAttribute('class') || '').replace(/sidecar-visible/g, '')}`;
const container = resultDom || sidecar.querySelector('.custom-content');
dom_1.removeAllDomChildren(container);
if (types_1.isPromise(custom.content)) {
container.appendChild(yield custom.content);
}
else if (custom.contentType) {
const projection = custom.content;
if (isHTML(projection)) {
container.appendChild(projection);
}
else if (custom.contentType === 'text/html') {
if (typeof projection === 'string') {
const padding = document.createElement('div');
padding.classList.add('padding-content', 'scrollable', 'page-content');
const inner = document.createElement('div');
padding.appendChild(inner);
inner.innerHTML = projection;
container.appendChild(padding);
}
else {
debug('WARNING: you said you were giving me html-formatted text, but instead gave me an object');
container.appendChild(document.createTextNode(JSON.stringify(projection, undefined, 2)));
}
}
else if (custom.contentType === 'text/markdown') {
if (typeof projection === 'string') {
const Marked = yield Promise.resolve().then(() => require('marked'));
const renderer = new Marked.Renderer();
const marked = (_) => Marked(_, { renderer });
renderer.link = (href, title, text) => {
return `<a class='bx--link' target='_blank' title="${title}" href="${href}">${text}</a>`;
};
const markdownContainer = document.createElement('div');
markdownContainer.classList.add('padding-content', 'scrollable', 'marked-content', 'page-content');
markdownContainer.innerHTML = marked(projection);
container.appendChild(markdownContainer);
}
else {
debug('WARNING: you said you were giving me markdown-formatted text, but instead gave me an object');
container.appendChild(document.createTextNode(JSON.stringify(projection, undefined, 2)));
}
}
else {
const tryToUseEditor = true;
if (tryToUseEditor) {
try {
const { content, presentation } = yield editors_1.tryOpenWithEditor(tab, custom, options);
customContent.classList.remove('zoomable');
container.appendChild(content);
sidecar_present_1.default(tab, presentation_1.default.FixedSize);
return presentation;
}
catch (err) {
console.error('error loading editor', err);
}
}
const scrollWrapper = document.createElement('div');
const pre = document.createElement('pre');
const code = document.createElement('code');
container.appendChild(scrollWrapper);
scrollWrapper.appendChild(pre);
pre.appendChild(code);
if (typeof projection === 'string') {
code.innerText = projection;
}
else {
code.innerText = JSON.stringify(projection, undefined, 2);
}
scrollWrapper.style.flex = '1';
scrollWrapper.classList.add('scrollable');
scrollWrapper.classList.add('scrollable-auto');
if (custom.contentType) {
const contentType = `language-${custom.contentType}`;
code.classList.add(contentType);
code.classList.remove(code.getAttribute('data-content-type'));
code.setAttribute('data-content-type', contentType);
code.classList.remove('json');
setTimeout(() => {
setTimeout(() => exports.linkify(code), 100);
}, 0);
}
}
}
else if (isHTML(custom.content)) {
container.appendChild(custom.content);
}
else if (typeof custom.content === 'string') {
const padding = document.createElement('div');
padding.classList.add('padding-content', 'scrollable');
const pre = document.createElement('pre');
pre.classList.add('pre-wrap', 'sans-serif');
pre.appendChild(document.createTextNode(custom.content));
padding.appendChild(pre);
container.appendChild(padding);
}
else {
console.error('content type not specified for custom content', custom);
}
});
exports.getEnclosingTab = (sidecar) => {
return tab_1.getTabFromTarget(sidecar);
};
var SidecarState;
(function (SidecarState) {
SidecarState[SidecarState["NotShown"] = 0] = "NotShown";
SidecarState[SidecarState["Minimized"] = 1] = "Minimized";
SidecarState[SidecarState["Open"] = 2] = "Open";
SidecarState[SidecarState["FullScreen"] = 3] = "FullScreen";
})(SidecarState = exports.SidecarState || (exports.SidecarState = {}));
exports.getSidecarState = (tab) => {
const sidecar = sidecar_core_1.getSidecar(tab);
if (tab.classList.contains('sidecar-full-screen')) {
return SidecarState.FullScreen;
}
else if (sidecar.classList.contains('visible')) {
return SidecarState.Open;
}
else if (sidecar.classList.contains('minimized')) {
return SidecarState.Minimized;
}
else {
return SidecarState.NotShown;
}
};
exports.showGenericEntity = (tab, entity, options = new show_options_1.DefaultShowOptions()) => {
debug('showGenericEntity', entity, options);
const sidecar = sidecar_core_1.getSidecar(tab);
events_1.default.emit('/sidecar/replace', sidecar.entity);
const hashDom = dom_1.element('.sidecar-header-name .entity-name-hash', sidecar);
hashDom.innerText = '';
sidecar.setAttribute('data-active-view', '.sidecar-content');
const customHeaders = sidecar.querySelectorAll('.custom-header-content');
for (let idx = 0; idx < customHeaders.length; idx++) {
dom_1.removeAllDomChildren(customHeaders[idx]);
}
const modes = entity.modes || (options && options.modes);
if (!options || !options.leaveBottomStripeAlone) {
bottom_stripe_1.addModeButtons(tab, modes, entity, options);
}
if (!options || options.echo !== false)
sidecar.entity = entity;
sidecar.setAttribute('class', `${sidecar.getAttribute('data-base-class')} entity-is-${entity.prettyType} entity-is-${entity.type}`);
sidecar_visibility_1.setVisibleClass(sidecar);
const replView = tab.querySelector('.repl');
replView.className = `sidecar-visible ${(replView.getAttribute('class') || '').replace(/sidecar-visible/g, '')}`;
const viewProviderDesiresFullscreen = document.body.classList.contains('subwindow');
if (viewProviderDesiresFullscreen ? !exports.isFullscreen(tab) : exports.isFullscreen(tab)) {
sidecar_visibility_1.toggleMaximization(tab);
sidecar_present_1.default(tab, presentation_1.default.SidecarFullscreen);
}
else {
sidecar_present_1.default(tab, presentation_1.default.Default);
}
const viewName = entity.prettyType || entity.type;
const nameDom = exports.addNameToSidecarHeader(sidecar, entity.name, entity.packageName, undefined, viewName);
badge_1.clearBadges(tab);
exports.addVersionBadge(tab, entity);
return sidecar;
};
const registeredEntityViews = {};
exports.registerEntityView = (kind, handler) => {
registeredEntityViews[kind] = handler;
};
exports.showEntity = (tab, entity, options = new show_options_1.DefaultShowOptions()) => {
if (custom_content_1.isCustomSpec(entity)) {
return exports.showCustom(tab, entity, options);
}
const sidecar = exports.showGenericEntity(tab, entity, options);
debug('done with showGenericEntity');
const renderer = registeredEntityViews[entity.type || entity.kind];
if (renderer) {
debug('dispatching to registered view handler %s', entity.type || entity.kind, renderer);
return renderer(tab, entity, sidecar, options);
}
else {
try {
const serialized = JSON.stringify(entity, undefined, 2);
const container = dom_1.element('.action-source', sidecar);
sidecar.classList.add('entity-is-actions');
container.innerText = serialized;
debug('displaying generic JSON');
}
catch (err) {
console.error(err);
}
return true;
}
};
exports.insertView = (tab) => (view) => {
debug('insertView', view);
const container = exports.getActiveView(tab);
debug('insertView.container', container);
dom_1.removeAllDomChildren(container);
container.appendChild(view);
sidecar_present_1.default(tab, presentation_1.default.Default);
};
exports.insertCustomContent = (tab, view) => {
debug('insertCustomContent', view);
const container = sidecar_core_1.getSidecar(tab).querySelector('.custom-content');
debug('insertCustomContent.container', container);
dom_1.removeAllDomChildren(container);
container.appendChild(view);
sidecar_present_1.default(tab, presentation_1.default.Default);
};
//# sourceMappingURL=sidecar.js.map