UNPKG

kui-shell

Version:

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

411 lines 21.3 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 dom_1 = require("./util/dom"); const table_1 = require("./models/table"); const table_2 = require("./views/table"); const sidecar_1 = require("./views/sidecar"); const sidecar_selector_1 = require("./views/sidecar-selector"); const modes_1 = require("./views/registrar/modes"); const exec_1 = require("../repl/exec"); const types_1 = require("../util/types"); const entity_1 = require("../models/entity"); const types_2 = require("../models/mmr/types"); const content_types_1 = require("../models/mmr/content-types"); const debug = debug_1.default('webapp/picture-in-picture'); function isDirectViewEntity(direct) { return sidecar_1.isCustomSpec(direct); } function isToggle(result) { return result && Array.isArray(result.toggle); } const callDirect = (tab, makeView, entity, execOptions) => __awaiter(void 0, void 0, void 0, function* () { if (typeof makeView === 'string') { debug('makeView as string'); if (execOptions && execOptions.exec === 'pexec') { return exec_1.pexec(makeView, execOptions); } else if (execOptions && execOptions.exec === 'rexec') { return exec_1.rexec(makeView, execOptions); } else { return exec_1.qexec(makeView, undefined, undefined, Object.assign({}, execOptions, { rethrowErrors: true })); } } else if (typeof makeView === 'function') { debug('makeView as function'); return Promise.resolve(makeView(tab, entity)); } else if (isDirectViewEntity(makeView)) { const combined = Object.assign({}, entity, makeView); return combined; } else { const provider = yield Promise.resolve().then(() => require('@kui-shell/plugin-' + makeView.plugin)); try { return provider[makeView.operation](tab, makeView.parameters, entity); } catch (err) { console.error('could not render mode', makeView.operation, err); } } }); function isHighLevelMode(mode) { return types_2.isButton(mode) || content_types_1.hasContent(mode); } function isSidecarMode(entity) { const mode = entity; return mode.mode !== undefined && (isHighLevelMode(mode) || mode.direct !== undefined || mode.command !== undefined); } exports.isSidecarMode = isSidecarMode; exports.rawCSS = { buttons: '.sidecar-top-stripe .sidecar-bottom-stripe-left-bits' }; exports.css = { buttons: (tab) => sidecar_selector_1.default(tab, exports.rawCSS.buttons), backContainer: (tab) => sidecar_selector_1.default(tab, '.sidecar-bottom-stripe .sidecar-bottom-stripe-left-bits .sidecar-bottom-stripe-back-bits'), backButton: (tab) => sidecar_selector_1.default(tab, '.sidecar-bottom-stripe .sidecar-bottom-stripe-left-bits .sidecar-bottom-stripe-back-button'), button: 'sidecar-bottom-stripe-button', tab: ['bx--tabs__nav-item', 'sidecar-bottom-stripe-button'], buttonAction: 'bx--tabs__nav-link', buttonActingAsButton: 'sidecar-bottom-stripe-button-as-button', buttonActingAsRadioButton: 'sidecar-bottom-stripe-button-as-radio-button', modeContainer: (tab) => sidecar_selector_1.default(tab, '.sidecar-top-stripe .sidecar-bottom-stripe-left-bits .sidecar-bottom-stripe-mode-bits .bx--tabs__nav'), bottomContainer: (tab) => sidecar_selector_1.default(tab, '.sidecar-bottom-stripe-toolbar .sidecar-bottom-stripe-mode-bits'), active: 'bx--tabs__nav-item--selected', selected: 'selected', hidden: 'hidden' }; const _addModeButton = (tab, modeStripe, bottomStripe, opts, entity, show) => { const { mode, label, defaultMode } = opts; const isTab = (content_types_1.hasContent(opts) && !types_2.isButton(opts)) || (!isHighLevelMode(opts) && !(opts.flush === 'right' || opts.flush === 'weak')); const button = document.createElement(isTab ? 'li' : 'a'); const buttonAction = document.createElement(isTab ? 'a' : 'span'); button.appendChild(buttonAction); button.setAttribute('role', 'presentation'); buttonAction.setAttribute('role', 'tab'); if (isTab) { buttonAction.setAttribute('href', '#'); buttonAction.classList.add('kui--tab-navigatable', 'kui--notab-when-sidecar-hidden'); } else { button.setAttribute('href', '#'); button.classList.add('kui--tab-navigatable', 'kui--notab-when-sidecar-hidden'); } if (!isHighLevelMode(opts)) { if (opts.visibleWhen && opts.visibleWhen !== show) { return; } else if (opts.visibleWhen) { button.setAttribute('data-visible-when', opts.visibleWhen); } if (opts.actAsButton) { button.classList.add(exports.css.buttonActingAsButton); if (opts.radioButton) { button.classList.add(exports.css.buttonActingAsRadioButton); } if (opts.selected) { button.classList.add(exports.css.selected); } if (opts.selectionController) { opts.selectionController.on('change', (selected) => { const op = selected ? 'add' : 'remove'; button.classList[op](exports.css.selected); }); } } if (opts.data) { for (const attr in opts.data) { button.setAttribute(attr, opts.data[attr]); } } } if ((((!show || show === 'default') && defaultMode) || show === mode) && (isHighLevelMode(opts) || !opts.actAsButton)) { button.classList.add(exports.css.active); } button.setAttribute('data-mode', mode); const fontawesome = !isHighLevelMode(opts) && opts.fontawesome; if (fontawesome) { const iconContainer = document.createElement('span'); const icon = document.createElement('i'); if (/trash/.test(fontawesome)) { icon.innerHTML = '<svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"><path d="M6 6h1v6H6zm3 0h1v6H9z"></path><path d="M2 3v1h1v10c0 .6.4 1 1 1h8c.6 0 1-.4 1-1V4h1V3H2zm2 11V4h8v10H4zM6 1h4v1H6z"></path></svg>'; } else if (/fa-unlock/.test(fontawesome)) { icon.innerHTML = '<svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"><path d="M12 7H6V4c0-1.1.9-2 2-2s2 .9 2 2h1c0-1.7-1.3-3-3-3S5 2.3 5 4v3H4c-.6 0-1 .4-1 1v6c0 .6.4 1 1 1h8c.6 0 1-.4 1-1V8c0-.6-.4-1-1-1zm0 7H4V8h8v6z"></path></svg>'; } else if (/fa-exclamation/.test(fontawesome)) { icon.innerHTML = '<svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" aria-hidden="true"><path d="M10 1c-5 0-9 4-9 9s4 9 9 9 9-4 9-9-4-9-9-9zm-.8 4h1.5v7H9.2V5zm.8 11c-.6 0-1-.4-1-1s.4-1 1-1 1 .4 1 1-.4 1-1 1z"></path><path d="M9.2 5h1.5v7H9.2V5zm.8 11c-.6 0-1-.4-1-1s.4-1 1-1 1 .4 1 1-.4 1-1 1z" data-icon-path="inner-path" opacity="0"></path></svg>'; } else if (/search-plus/.test(fontawesome)) { icon.innerHTML = '<svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 32 32" aria-hidden="true"><path d="M19 13h-4V9h-2v4H9v2h4v4h2v-4h4v-2z"></path><path d="M22.45 21A10.87 10.87 0 0 0 25 14a11 11 0 1 0-11 11 10.87 10.87 0 0 0 7-2.55L28.59 30 30 28.59zM14 23a9 9 0 1 1 9-9 9 9 0 0 1-9 9z"></path></svg>'; } else if (/search-minus/.test(fontawesome)) { icon.innerHTML = '<svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 32 32" aria-hidden="true"><path d="M9 13h10v2H9z"></path><path d="M22.45 21A10.87 10.87 0 0 0 25 14a11 11 0 1 0-11 11 10.87 10.87 0 0 0 7-2.55L28.59 30 30 28.59zM14 23a9 9 0 1 1 9-9 9 9 0 0 1-9 9z"></path></svg>'; } else if (/chart-bar/.test(fontawesome)) { icon.innerHTML = '<svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 32 32" aria-hidden="true"><path d="M27 28V6h-8v22h-4V14H7v14H4V2H2v26a2 2 0 0 0 2 2h26v-2zm-14 0H9V16h4zm12 0h-4V8h4z"></path></svg>'; } else if (/^fas fa-th$/.test(fontawesome)) { icon.innerHTML = '<svg focusable="false" preserveAspectRatio="xMidYMid meet" style="will-change: transform;" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 32 32" aria-hidden="true"><path d="M12 4H6a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 8H6V6h6zm14-8h-6a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 8h-6V6h6zm-14 6H6a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2zm0 8H6v-6h6zm14-8h-6a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2zm0 8h-6v-6h6z"></path></svg>'; } else { icon.className = fontawesome; } button.classList.add('graphical-icon'); button.appendChild(iconContainer); iconContainer.appendChild(icon); iconContainer.classList.add('icon-container'); if (!isHighLevelMode(opts) && opts.labelBelow) { const labelContainer = document.createElement('div'); labelContainer.classList.add('deemphasize'); labelContainer.innerText = label; iconContainer.appendChild(labelContainer); } } else { buttonAction.innerText = label || mode; } let container = modeStripe; if (!isTab) { let fillContainer = bottomStripe.querySelector('.fill-container.flush-right[role="tablist"]'); if (!fillContainer) { fillContainer = document.createElement('div'); fillContainer.className = 'fill-container flush-right'; fillContainer.setAttribute('role', 'tablist'); } button.classList.add(exports.css.button); bottomStripe.appendChild(fillContainer); container = fillContainer; } else { if (Array.isArray(exports.css.tab)) { exports.css.tab.forEach(_ => button.classList.add(_)); } else { button.classList.add(exports.css.tab); } buttonAction.classList.add(exports.css.buttonAction); } container.appendChild(button); if (!isHighLevelMode(opts) && opts.balloon) { button.setAttribute('data-balloon', opts.balloon); button.setAttribute('data-balloon-pos', !isTab ? 'down-right' : 'down'); if (opts.balloonLength) { button.setAttribute('data-balloon-length', opts.balloonLength); } else { button.setAttribute('data-balloon-length', 'medium'); } } if (entity.type !== 'custom') { sidecar_1.getSidecar(tab).entity = entity; } const url = !isHighLevelMode(opts) && opts.url; if (url) { button.onclick = () => window.open(url); } else if (isHighLevelMode(opts) || opts.command || opts.direct) { button.onclick = () => __awaiter(void 0, void 0, void 0, function* () { const leaveBottomStripeAlone = isHighLevelMode(opts) || opts.leaveBottomStripeAlone; const actAsButton = !isHighLevelMode(opts) && opts.actAsButton; const changeActiveButton = () => { const radioButton = !isHighLevelMode(opts) && opts.radioButton; const selected = !isHighLevelMode(opts) && opts.selected; if (!actAsButton) { const currentActive = modeStripe.querySelector(`.${exports.css.active}`); if (currentActive) { currentActive.classList.remove(exports.css.active); } button.classList.add(exports.css.active); const visibleWhens = bottomStripe.querySelectorAll('.sidecar-bottom-stripe-button[data-visible-when]'); for (let idx = 0; idx < visibleWhens.length; idx++) { const otherButton = visibleWhens[idx]; const when = otherButton.getAttribute('data-visible-when'); if (when === mode) { otherButton.classList.remove('not-displayed'); } else { otherButton.classList.add('not-displayed'); } } } else if (actAsButton && selected !== undefined) { if (radioButton) { button.classList.toggle(exports.css.selected); } else { const currentSelected = bottomStripe.querySelector(`.${exports.css.selected}`); if (currentSelected) { currentSelected.classList.remove(exports.css.selected); } button.classList.add(exports.css.selected); } } }; const present = (view) => { if (typeof view === 'string') { const dom = document.createElement('div'); dom.classList.add('padding-content', 'scrollable', 'scrollable-auto'); dom.innerText = view; sidecar_1.insertCustomContent(tab, dom); } else if (content_types_1.isStringWithOptionalContentType(view) && entity_1.isMetadataBearing(entity)) { sidecar_1.showCustom(tab, { type: 'custom', resource: entity, content: view.content, contentType: view.contentType }, { leaveBottomStripeAlone: true }); } else if (types_1.isHTML(view)) { const dom = document.createElement('div'); dom.classList.add('padding-content', 'scrollable', 'scrollable-auto'); dom.appendChild(view); sidecar_1.insertCustomContent(tab, dom); } else if (sidecar_1.isCustomSpec(view)) { sidecar_1.showCustom(tab, view, { leaveBottomStripeAlone: leaveBottomStripeAlone }); } else if (table_1.isTable(view) || table_1.isMultiTable(view)) { const dom1 = document.createElement('div'); const dom2 = document.createElement('div'); dom1.classList.add('scrollable', 'scrollable-auto'); dom2.classList.add('result-as-table', 'repl-result'); dom1.appendChild(dom2); table_2.formatTable(tab, view, dom2, { usePip: true }); sidecar_1.insertCustomContent(tab, dom1); } }; if (!isHighLevelMode(opts) && opts.direct) { try { if (isDirectViewEntity(opts.direct) || leaveBottomStripeAlone) { changeActiveButton(); } const view = yield callDirect(tab, opts.direct, entity, opts.execOptions); if (actAsButton && isToggle(view)) { view.toggle.forEach(({ mode, disabled }) => { const button = modeStripe.querySelector(`.sidecar-bottom-stripe-button[data-mode="${mode}"]`); if (button) { if (disabled) { button.classList.add('disabled'); } else { button.classList.remove('disabled'); } } }); changeActiveButton(); } else if (view && !actAsButton && !isToggle(view)) { if (table_1.isTable(view) || content_types_1.isStringWithOptionalContentType(view)) { changeActiveButton(); } present(view); } else if (!isToggle(view) && sidecar_1.isCustomSpec(view)) { sidecar_1.showCustom(tab, view, { leaveBottomStripeAlone: leaveBottomStripeAlone }); } else if (!leaveBottomStripeAlone) { changeActiveButton(); } } catch (err) { console.error(err); } } else if (!isHighLevelMode(opts) && opts.command) { try { const { echo, noHistory, replSilence } = opts; yield exec_1.pexec(opts.command(entity), { echo, noHistory, replSilence }); if (leaveBottomStripeAlone) { changeActiveButton(); } } catch (err) { console.error(err); } } else if (content_types_1.hasContent(opts)) { const { format } = yield Promise.resolve().then(() => require('../models/mmr/show')); const view = yield format(tab, entity, opts); changeActiveButton(); present(view); } }); } return button; }; exports.addModeButton = (tab, mode, entity) => { const modeStripe = exports.css.modeContainer(tab); const bottomStripe = exports.css.bottomContainer(tab); return _addModeButton(tab, modeStripe, bottomStripe, mode, entity, undefined); }; exports.addModeButtons = (tab, modesUnsorted = [], entity, options) => { const command = ''; if (entity_1.isMetadataBearing(entity)) { modes_1.apply(tab, modesUnsorted, command, { resource: entity }); } else if (entity_1.isMetadataBearingByReference(entity)) { modes_1.apply(tab, modesUnsorted, command, entity); } const modes = modesUnsorted.sort((a, b) => { const aFlush = isHighLevelMode(a) ? undefined : a.flush; const bFlush = isHighLevelMode(b) ? undefined : b.flush; if (aFlush === bFlush || (aFlush === 'weak' && bFlush === 'right') || (aFlush === 'right' && bFlush === 'weak')) { return (a.order || 0) - (b.order || 0); } else { if (aFlush === 'right' || aFlush === 'weak') { return 1; } else { return -1; } } }); const addModeButtons = (tab, modes, entity, show) => { const modeStripe = exports.css.modeContainer(tab); const bottomStripe = exports.css.bottomContainer(tab); dom_1.removeAllDomChildren(modeStripe); dom_1.removeAllDomChildren(bottomStripe); if (modes) { modes.forEach(mode => { _addModeButton(tab, modeStripe, bottomStripe, mode, entity, show); }); } bottomStripe.capture = () => { const currentSelection = modeStripe.querySelector(`.${exports.css.active}`); const currentShow = currentSelection && currentSelection.getAttribute('data-mode'); const show = currentShow || (options && options.show); dom_1.removeAllDomChildren(bottomStripe); return () => addModeButtons(tab, modes, entity, show); }; }; const defaultMode = modes && (modes.find(({ defaultMode }) => defaultMode) || modes.find(_ => isHighLevelMode(_) || !_.flush)); const show = (options && options.show) || (defaultMode && (defaultMode.mode || defaultMode.label)); addModeButtons(tab, modes, entity, show); if (!options || !options.preserveBackButton) { const backContainer = exports.css.backContainer(tab); backContainer.classList.remove('has-back-button'); } }; //# sourceMappingURL=bottom-stripe.js.map