kui-shell
Version:
This is the monorepo for Kui, the hybrid command-line/GUI electron-based Kubernetes tool
237 lines • 9.81 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 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