/* * QQQ - Low-code Application Framework for Engineers. * Copyright (C) 2021-2022. Kingsrook, LLC * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States * contact@kingsrook.com * https://github.com/Kingsrook/ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ import {QJobError} from "@kingsrook/qqq-frontend-core/lib/model/processes/QJobError"; import {ToggleButton, ToggleButtonGroup, Typography} from "@mui/material"; import Alert from "@mui/material/Alert"; import Box from "@mui/material/Box"; import Card from "@mui/material/Card"; import Grid from "@mui/material/Grid"; import Snackbar from "@mui/material/Snackbar"; import TextField from "@mui/material/TextField"; import FormData from "form-data"; import React, {useReducer, useState} from "react"; import AceEditor from "react-ace"; import {QCancelButton, QSaveButton} from "qqq/components/buttons/DefaultButtons"; import Client from "qqq/utils/qqq/Client"; import DataBagPreview from "./DataBagPreview"; export interface DataBagDataEditorProps { title: string; dataBagId: number; data: string; closeCallback: any; } const qController = Client.getInstance(); function DataBagDataEditor({title, dataBagId, data, closeCallback}: DataBagDataEditorProps): JSX.Element { const [closing, setClosing] = useState(false); const [updatedCode, setUpdatedCode] = useState(data) const [commitMessage, setCommitMessage] = useState("") const [openTool, setOpenTool] = useState(null); const [errorAlert, setErrorAlert] = useState("") const [, forceUpdate] = useReducer((x) => x + 1, 0); const changeOpenTool = (event: React.MouseEvent, newValue: string | null) => { setOpenTool(newValue); // need this to make Ace recognize new height. setTimeout(() => { window.dispatchEvent(new Event("resize")) }, 100); }; const saveClicked = () => { try { JSON.parse(updatedCode) } catch(e) { setErrorAlert("Cannot save Data Bag Contents. Invalid json: " + e); return; } setClosing(true); (async () => { const formData = new FormData(); formData.append("dataBagId", dataBagId); formData.append("data", updatedCode); formData.append("commitMessage", commitMessage); ////////////////////////////////////////////////////////////////// // we don't want this job to go async, so, pass a large timeout // ////////////////////////////////////////////////////////////////// formData.append("_qStepTimeoutMillis", 60 * 1000); const formDataHeaders = { "content-type": "multipart/form-data; boundary=--------------------------320289315924586491558366", }; const processResult = await qController.processInit("storeDataBagVersion", formData, formDataHeaders); if (processResult instanceof QJobError) { const jobError = processResult as QJobError closeCallback(null, "failed", jobError.userFacingError ?? jobError.error); } console.log("process result"); console.log(processResult); closeCallback(null, "saved", "Saved New Data Bag Version"); })(); } const cancelClicked = () => { setClosing(true); closeCallback(null, "cancelled"); } const updateCode = (value: string, event: any) => { console.log("Updating code") setUpdatedCode(value); forceUpdate(); } const updateCommitMessage = (event: React.ChangeEvent) => { setCommitMessage(event.target.value); } return ( { if (reason === "clickaway") { return; } setErrorAlert("") }} anchorOrigin={{vertical: "top", horizontal: "center"}}> setErrorAlert("")}> {errorAlert} {title} Tools: Preview { openTool && { openTool == "preview" && } } ); } export default DataBagDataEditor;