UNPKG

sls-dev-tools

Version:

The Dev Tools for the Serverless World

236 lines (202 loc) 7.14 kB
"use strict"; var _index = require("./index"); var _components = require("../components"); var _awsSchema = require("../services/awsSchema"); const blessed = require("blessed"); const createDynamicForm = async (api, parent, closeModal, modalState, updatePageText) => { let properties = {}; properties = await (0, _awsSchema.getProperties)(api, modalState.registry, modalState.schema); if (Object.prototype.hasOwnProperty.call(properties, "type")) { modalState.event.DetailType = properties.type; } if (Object.prototype.hasOwnProperty.call(properties, "source")) { modalState.event.Source = properties.source; } const fields = properties.properties; const fieldNames = Object.keys(fields); if (fieldNames !== []) { fieldNames.forEach(field => { const textboxWithTitle = (0, _components.generateFieldWithTitle)(blessed, parent, field, "", 106); const { textbox } = textboxWithTitle; const { titleBox } = textboxWithTitle; textbox.on("cancel", () => { closeModal(); }); modalState.textboxes.push(textbox); modalState.titles.push(titleBox); modalState.fieldNames.push(field); modalState.fieldTypes.push(fields[field].type); }); // Change focus to first field instead of submit button modalState.currentTextbox = 0; modalState.buttons[0].style.border.fg = "green"; modalState.buttons[0].style.fg = "green"; modalState.buttonSelected = false; modalState.textboxes[0].style.border.fg = "yellow"; // Calculate total number of pages modalState.numPages = Math.ceil(fieldNames.length / 5); // Hide fields after the 5th if (fieldNames.length > 5) { for (let i = 5; i < modalState.textboxes.length; i += 1) { modalState.textboxes[i].hide(); modalState.titles[i].hide(); } } // Update page text updatePageText(); } }; const createDetail = (keys, types, values) => { const detail = {}; for (let i = 0; i < keys.length; i += 1) { if (types[i] === "number") { detail[keys[i]] = Number(values[i]); } else { detail[keys[i]] = values[i]; } } return detail; }; const eventModal = (screen, eventBridge, application, api, registry, schema, injectEvent) => { const eventLayout = new _components.ModalLayout(screen, 112, 35, true); const closeModal = () => { // Store all text to populate modal when next opened application.setIsModalOpen(false); application.returnFocus(); eventLayout.destroy(); }; const modalState = { currentTextbox: 0, currentPage: 1, numPages: 1, textboxes: [], titles: [], buttons: [], buttonSelected: true, fieldNames: [], fieldTypes: [], registry, schema, event: { EventBusName: eventBridge, DetailType: "", Source: "", Detail: "{}" } }; const unselectTextbox = index => { modalState.textboxes[index].style.border.fg = "green"; }; const selectTextbox = index => { modalState.textboxes[index].style.border.fg = "yellow"; }; const setButtonSelected = value => { const color = value === true ? "yellow" : "green"; modalState.buttonSelected = value; modalState.buttons[0].style.border.fg = color; modalState.buttons[0].style.fg = color; }; const togglePage = pageNum => { const lowerBound = (pageNum - 1) * 5; const upperBound = Math.min(lowerBound + 5, modalState.textboxes.length); for (let i = lowerBound; i < upperBound; i += 1) { modalState.textboxes[i].toggle(); modalState.titles[i].toggle(); } }; const nextPage = () => { unselectTextbox(modalState.currentTextbox); togglePage(modalState.currentPage); modalState.currentPage += 1; togglePage(modalState.currentPage); modalState.currentTextbox = (modalState.currentPage - 1) * 5; selectTextbox(modalState.currentTextbox); }; const prevPage = () => { unselectTextbox(modalState.currentTextbox); togglePage(modalState.currentPage); modalState.currentPage -= 1; togglePage(modalState.currentPage); modalState.currentTextbox = (modalState.currentPage - 1) * 5; selectTextbox(modalState.currentTextbox); }; new _components.ModalTitle(eventLayout, 110, `Event Injection - ${schema}`); const currentPageText = new _components.ModalTitle(eventLayout, 110, ""); const updateCurrentPageText = () => { currentPageText.content = `Page ${modalState.currentPage} of ${modalState.numPages}`; }; const fieldLayout = blessed.layout({ parent: eventLayout, top: "center", left: "center", width: 110, height: 22, border: "line", style: { border: { fg: "green" } }, keys: true, grabKeys: true }); const submit = (0, _components.submitButton)(blessed, eventLayout, 110); // Push submit to front of textboxes array to avoid race conditions modalState.buttons.push(submit); setButtonSelected(true); createDynamicForm(api, fieldLayout, closeModal, modalState, updateCurrentPageText); new _components.Box(eventLayout, 110, 5, "Up/Down Arrow keys to select field\n Left/Right arrows keys to change page\nENTER to toggle edit mode | ENTER on Submit to inject event | ESC to close"); fieldLayout.focus(); fieldLayout.key(["right"], () => { if (modalState.currentPage < modalState.numPages) { nextPage(); updateCurrentPageText(); } }); fieldLayout.key(["left"], () => { if (modalState.currentPage > 1) { prevPage(); updateCurrentPageText(); } }); fieldLayout.key(["enter"], () => { // If submit button is in focus if (modalState.buttonSelected === true) { const values = []; modalState.textboxes.forEach(t => values.push(t.getValue())); const detail = JSON.stringify(createDetail(modalState.fieldNames, modalState.fieldTypes, values)); modalState.event.Detail = detail; eventLayout.destroy(); (0, _index.eventInjectionModal)(screen, eventBridge, application, injectEvent, modalState.event); } else { // Edit field modalState.textboxes[modalState.currentTextbox].focus(); } }); fieldLayout.key(["up", "down"], (_, key) => { // Indices of fields at the top and bottom of page const top = (modalState.currentPage - 1) * 5; const bottom = Math.min(modalState.textboxes.length - 1, top + 4); // If submit selected, go to bottom if (modalState.buttonSelected) { if (modalState.textboxes.length > 0) { setButtonSelected(false); modalState.currentTextbox = key.name === "down" ? top : bottom; selectTextbox(modalState.currentTextbox); } } else { unselectTextbox(modalState.currentTextbox); modalState.currentTextbox += key.name === "down" ? 1 : -1; if (modalState.currentTextbox < top || modalState.currentTextbox > bottom) { setButtonSelected(true); } else { selectTextbox(modalState.currentTextbox); } } }); fieldLayout.key(["escape"], () => { // Discard modal closeModal(); }); }; module.exports = { eventModal };