UNPKG

kui-shell

Version:

This is the monorepo for Kui, the hybrid command-line/GUI electron-based Kubernetes tool

549 lines 24.9 kB
"use strict"; 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