UNPKG

kui-shell

Version:

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

237 lines 9.81 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 js_yaml_1 = require("js-yaml"); const core_1 = require("@kui-shell/core"); const Resources = require("../model/resource"); const strings = core_1.i18n('plugin-k8s'); const debug = debug_1.default('plugin-k8s/view/form'); const update = (parent, path, value) => { const key = path[path.length - 1]; debug('update', key, parent); if (parent) { parent[key] = value; } }; const doSave = (tab, form, yaml, filepath, onSave, button) => () => { if (button) { button.classList.add('yellow-background'); button.classList.add('repeating-pulse'); } setTimeout(() => __awaiter(void 0, void 0, void 0, function* () { const inputs = form.querySelectorAll('.bx--text-input'); for (let idx = 0; idx < inputs.length; idx++) { const input = inputs[idx]; const path = input.__kuiPath; const parent = input.__kuiParent; update(parent, path, input.value); } debug('doSave done extracting values', yaml); const { writeFile } = yield Promise.resolve().then(() => require('fs-extra')); yield writeFile(filepath, js_yaml_1.safeDump(yaml)); debug('doSave done writing file', filepath); if (button) { button.classList.remove('yellow-background'); button.classList.remove('repeating-pulse'); } onSave(js_yaml_1.safeDump(yaml)); }), 0); }; const formGroups = (yaml) => { const groups = []; const push = (group, key, { parent = yaml, path = [key.toString()], skip = {} } = {}) => { const formGroup = groups.find(({ title }) => title === group) || { title: group, choices: [] }; const { choices } = formGroup; if (choices.length === 0) { groups.push(formGroup); } const struct = parent[key]; for (const key in struct) { if (!skip[key]) { const value = struct[key]; const next = path.concat([key]); if (typeof value === 'string' || typeof value === 'boolean' || typeof value === 'number') { choices.push({ key, value, path: next, parent: struct }); } else if (Array.isArray(value)) { if (value.length > 0) { if (typeof value[0] === 'string' || typeof value[0] === 'number' || typeof value[0] === 'boolean') { choices.push({ key, value: value.join(','), path: next, parent: struct }); } else { } } } else { push(key, key, { parent: struct, path: next }); } } } }; push('Resource Definition', 'metadata'); push('Resource Definition', 'spec', { skip: { service: true } }); push('Data Values', 'data'); if (yaml.spec && yaml.spec.params) { yaml.spec.params.forEach((param, idx) => { push(`Parameter #${idx + 1}`, idx, { parent: yaml.spec.params }); }); } if (Resources.isRole(yaml)) { yaml.rules.forEach((rule, idx) => { push('Rules', idx, { parent: yaml.rules }); }); } if (Resources.isRoleBinding(yaml)) { push('Role Reference', 'roleRef'); yaml.subjects.forEach((subject, idx) => { push('Subjects', idx, { parent: yaml.subjects }); }); } if (Resources.isServiceAccount(yaml)) { yaml.secrets.forEach((secrets, idx) => { push('Secret', idx, { parent: yaml.secrets }); }); } return groups; }; exports.generateForm = (tab) => (yaml, filepath, name, kind, onSave) => { const formElements = formGroups(yaml); debug('generate form', formElements); const form = document.createElement('form'); form.className = 'project-config-container padding-content overflow-auto'; const list = document.createElement('ul'); list.className = 'project-config-list'; form.appendChild(list); const buttons = document.createElement('div'); buttons.className = 'project-config-buttons'; form.appendChild(buttons); formElements.forEach(element => { debug('config element', element); const item = document.createElement('li'); item.className = 'project-config-items'; const itemRight = document.createElement('div'); itemRight.className = 'project-config-items-right'; item.appendChild(itemRight); const itemTitleOuter = document.createElement('div'); const itemTitle = document.createElement('div'); itemTitleOuter.className = 'result-table-title-outer'; itemTitle.className = 'result-table-title'; itemTitle.innerText = element.title; itemTitleOuter.appendChild(itemTitle); itemRight.appendChild(itemTitleOuter); const form = document.createElement('div'); form.className = 'form'; itemRight.appendChild(form); const formatChoice = (extraCSS) => (element) => { const row = document.createElement('div'); row.className = 'bx--form-item'; if (extraCSS) row.classList.add(extraCSS); form.appendChild(row); const labelPart = document.createElement('label'); labelPart.className = 'bx--label'; labelPart.appendChild(document.createTextNode(element.key)); row.appendChild(labelPart); if (element.optional) { const optionalPart = document.createElement('span'); optionalPart.className = 'left-pad deemphasize'; optionalPart.innerText = '(optional)'; labelPart.appendChild(optionalPart); } const inputType = typeof element.value; const inputPart = element.key === 'description' ? document.createElement('textarea') : document.createElement('input'); inputPart.className = 'bx--text-input'; inputPart.setAttribute('type', inputType === 'string' ? 'text' : inputType); inputPart.value = element.value.toString(); inputPart.setAttribute('defaultValue', inputPart.value); inputPart.setAttribute('placeholder', element.placeholder || element.key); inputPart.setAttribute('data-typeof', inputType); inputPart.setAttribute('data-form-label', element.key); inputPart.__kuiPath = element.path; inputPart.__kuiParent = element.parent; row.appendChild(inputPart); }; const isLongPattern = /(description|ur[il])/i; const isKeyLike = /key|name/i; const { shortChoices, longChoices } = element.choices.length === 2 && isKeyLike.test(element.choices[0].key) && element.choices[1].key === 'value' && isLongPattern.test(element.choices[0].value.toString()) ? { shortChoices: [element.choices[0]], longChoices: [element.choices[1]] } : element.choices.reduce((groups, choice) => { if (isLongPattern.test(choice.key)) { groups.longChoices.push(choice); } else { groups.shortChoices.push(choice); } return groups; }, { shortChoices: [], longChoices: [] }); shortChoices.forEach(formatChoice()); longChoices.forEach(formatChoice('bx--form-item-wide')); if (form.children.length > 0) { list.appendChild(item); } }); const modes = [ { mode: 'save', label: strings('save'), flush: 'right', actAsButton: true, direct: doSave(tab, form, yaml, filepath, onSave), visibleWhen: 'edit' }, { mode: 'revert', label: strings('revert'), flush: 'right', actAsButton: true, direct: () => form.reset(), visibleWhen: 'edit' } ]; const subtext = document.createElement('span'); subtext.appendChild(document.createTextNode('The provider ')); const strong = document.createElement('strong'); strong.innerText = yaml.apiVersion; subtext.appendChild(strong); subtext.appendChild(document.createTextNode(' offers configuration choices')); return { type: 'custom', prettyType: kind, isEntity: true, name, subtext, content: form, modes, resource: yaml }; }; exports.default = exports.generateForm; //# sourceMappingURL=form.js.map