From e22074cc13f65c093d3b227659b8640a00ec51d9 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 24 Feb 2023 15:14:31 -0600 Subject: [PATCH] Initial checkin - record scripts WIP --- src/qqq/components/scripts/ScriptEditor.tsx | 210 ++++++++++ .../components/widgets/misc/ScriptViewer.tsx | 394 ++++++++++++++++++ .../tests/AssociatedRecordScriptTest.java | 65 +++ .../tests/ScriptTableTest.java | 66 +++ .../fixtures/data/person/developer.json | 276 ++++++++++++ .../resources/fixtures/data/script/1.json | 20 + .../fixtures/metaData/table/script.json | 139 ++++++ .../fixtures/widget/scriptViewer.json | 7 + 8 files changed, 1177 insertions(+) create mode 100644 src/qqq/components/scripts/ScriptEditor.tsx create mode 100644 src/qqq/components/widgets/misc/ScriptViewer.tsx create mode 100755 src/test/java/com/kingsrook/qqq/materialdashboard/tests/AssociatedRecordScriptTest.java create mode 100755 src/test/java/com/kingsrook/qqq/materialdashboard/tests/ScriptTableTest.java create mode 100644 src/test/resources/fixtures/data/person/developer.json create mode 100644 src/test/resources/fixtures/data/script/1.json create mode 100644 src/test/resources/fixtures/metaData/table/script.json create mode 100644 src/test/resources/fixtures/widget/scriptViewer.json diff --git a/src/qqq/components/scripts/ScriptEditor.tsx b/src/qqq/components/scripts/ScriptEditor.tsx new file mode 100644 index 0000000..a12b4a3 --- /dev/null +++ b/src/qqq/components/scripts/ScriptEditor.tsx @@ -0,0 +1,210 @@ +/* + * 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"; + +export interface ScriptEditorProps +{ + title: string; + scriptId: number; + contents: string; + closeCallback: any; +} + + +const qController = Client.getInstance(); + +function ScriptEditor({title, scriptId, contents, closeCallback}: ScriptEditorProps): JSX.Element +{ + const [closing, setClosing] = useState(false); + const [updatedCode, setUpdatedCode] = useState(contents) + 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 = () => + { + setClosing(true); + + (async () => + { + const formData = new FormData(); + formData.append("scriptId", scriptId); + formData.append("contents", 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", + }; + + try + { + const processResult = await qController.processInit("storeScriptRevision", formData, formDataHeaders); + console.log("process result"); + console.log(processResult); + + if (processResult instanceof QJobError) + { + const jobError = processResult as QJobError + setErrorAlert(jobError.userFacingError ?? jobError.error) + setClosing(false); + return; + } + + closeCallback(null, "saved", "Saved New Script Version"); + } + catch(e) + { + // @ts-ignore + setErrorAlert(e.message ?? "Unexpected error saving script") + setClosing(false); + } + })(); + } + + 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 ScriptEditor; diff --git a/src/qqq/components/widgets/misc/ScriptViewer.tsx b/src/qqq/components/widgets/misc/ScriptViewer.tsx new file mode 100644 index 0000000..b4a6668 --- /dev/null +++ b/src/qqq/components/widgets/misc/ScriptViewer.tsx @@ -0,0 +1,394 @@ +/* + * 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 {QException} from "@kingsrook/qqq-frontend-core/lib/exceptions/QException"; +import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord"; +import {QCriteriaOperator} from "@kingsrook/qqq-frontend-core/lib/model/query/QCriteriaOperator"; +import {QFilterCriteria} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterCriteria"; +import {QFilterOrderBy} from "@kingsrook/qqq-frontend-core/lib/model/query/QFilterOrderBy"; +import {QQueryFilter} from "@kingsrook/qqq-frontend-core/lib/model/query/QQueryFilter"; +import Alert from "@mui/material/Alert"; +import Avatar from "@mui/material/Avatar"; +import Box from "@mui/material/Box"; +import Button from "@mui/material/Button"; +import Chip from "@mui/material/Chip"; +import Divider from "@mui/material/Divider"; +import Grid from "@mui/material/Grid"; +import Icon from "@mui/material/Icon"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import ListItemAvatar from "@mui/material/ListItemAvatar"; +import ListItemText from "@mui/material/ListItemText"; +import Modal from "@mui/material/Modal"; +import Snackbar from "@mui/material/Snackbar"; +import Tab from "@mui/material/Tab"; +import Tabs from "@mui/material/Tabs"; +import Typography from "@mui/material/Typography"; +import React, {useReducer, useState} from "react"; +import AceEditor from "react-ace"; +import TabPanel from "qqq/components/misc/TabPanel"; +import ScriptEditor, {ScriptEditorProps} from "qqq/components/scripts/ScriptEditor"; +import CustomWidthTooltip from "qqq/components/tooltips/CustomWidthTooltip"; +import {LoadingState} from "qqq/models/LoadingState"; +import DeveloperModeUtils from "qqq/utils/DeveloperModeUtils"; +import Client from "qqq/utils/qqq/Client"; +import ValueUtils from "qqq/utils/qqq/ValueUtils"; + +import "ace-builds/src-noconflict/mode-java"; +import "ace-builds/src-noconflict/mode-javascript"; +import "ace-builds/src-noconflict/mode-json"; +import "ace-builds/src-noconflict/theme-github"; +import "ace-builds/src-noconflict/ext-language_tools"; + +const qController = Client.getInstance(); + +// Declaring props types for ViewForm +interface Props +{ + scriptId: number +} + +ScriptViewer.defaultProps = + { + }; + +export default function ScriptViewer({scriptId}: Props): JSX.Element +{ + const [scriptRecord, setScriptRecord] = useState(null as QRecord); + const [asyncLoadInited, setAsyncLoadInited] = useState(false); + const [versionRecordList, setVersionRecordList] = useState(null as QRecord[]); + const [selectedVersionRecord, setSelectedVersionRecord] = useState(null as QRecord); + const [currentVersionId , setCurrentVersionId] = useState(null as number); + const [notFoundMessage, setNotFoundMessage] = useState(null); + const [selectedTab, setSelectedTab] = useState(0); + const [editorProps, setEditorProps] = useState(null as ScriptEditorProps); + const [successText, setSuccessText] = useState(null as string); + const [failText, setFailText] = useState(null as string) + const [, forceUpdate] = useReducer((x) => x + 1, 0); + + const [loadingSelectedVersion, _] = useState(new LoadingState(forceUpdate, "loading")); + + if (!asyncLoadInited) + { + setAsyncLoadInited(true); + + (async () => + { + try + { + const scriptRecord = await qController.get("script", scriptId); + setScriptRecord(scriptRecord); + + const criteria = [new QFilterCriteria("scriptId", QCriteriaOperator.EQUALS, [scriptId])]; + const orderBys = [new QFilterOrderBy("sequenceNo", false)]; + const filter = new QQueryFilter(criteria, orderBys); + const versions = await qController.query("scriptRevision", filter, 25, 0); + console.log("Fetched versions:"); + console.log(versions); + setVersionRecordList(versions); + + if(versions && versions.length > 0) + { + setCurrentVersionId(versions[0].values.get("id")); + const latestVersion = await qController.get("scriptRevision", versions[0].values.get("id")); + console.log("Fetched latestVersion:"); + console.log(latestVersion); + setSelectedVersionRecord(latestVersion); + loadingSelectedVersion.setNotLoading(); + forceUpdate(); + } + } + catch (e) + { + if (e instanceof QException) + { + if ((e as QException).status === "404") + { + setNotFoundMessage("Script code could not be found."); + return; + } + } + setNotFoundMessage("Error loading Script code: " + e); + } + })(); + } + + const editData = (contents: string) => + { + const editorProps = {} as ScriptEditorProps; + editorProps.title = (contents ? "Editing Code for Script: " : "Initializing Code for Script: ") + scriptRecord?.values?.get("name"); + editorProps.contents = contents; + editorProps.scriptId = scriptId; + setEditorProps(editorProps); + }; + + const closeEditingScript = (event: object, reason: string, alert: string = null) => + { + if (reason === "backdropClick" || reason === "escapeKeyDown") + { + return; + } + + if (reason === "saved") + { + setAsyncLoadInited(false); + forceUpdate(); + + if (alert) + { + setSuccessText(alert); + } + } + else if (reason === "failed") + { + setAsyncLoadInited(false); + forceUpdate(); + + if (alert) + { + setFailText(alert); + } + } + + setEditorProps(null); + }; + + const changeTab = (newValue: number) => + { + setSelectedTab(newValue); + forceUpdate(); + }; + + const selectVersion = (version: QRecord) => + { + (async () => + { + // fetch the full version + setSelectedVersionRecord(version); + loadingSelectedVersion.setLoading(); + + const selectedVersion = await qController.get("scriptVersion", version.values.get("id")); + console.log("Fetched selectedVersion:"); + console.log(selectedVersion); + setSelectedVersionRecord(selectedVersion); + loadingSelectedVersion.setNotLoading(); + forceUpdate(); + })(); + }; + + function getVersionsList(versionRecordList: QRecord[], selectedVersionRecord: QRecord) + { + return + { + (versionRecordList == null || versionRecordList.length == 0) ? + + There are not any versions of this script. + + : <> + } + { + versionRecordList?.map((version: any) => ( + + selectVersion(version)}> + + {`${version.values.get("sequenceNo")}`} + + + {currentVersionId == version?.values?.get("id") && } + {version.values.get("commitMessage")} + + } + secondary={ + <> + {ValueUtils.formatDateTime(version.values.get("createDate"))} +
+ {version.values.get("author")} + + } + /> +
+ +
+ )) + } +
; + } + + let editButtonTooltip = ""; + let editButtonText = "Create New Version"; + if (currentVersionId) + { + if (currentVersionId === selectedVersionRecord?.values?.get("id")) + { + editButtonTooltip = "If you make any changes to this script, a new version will be created when you hit Save."; + editButtonText = "Edit"; + } + else + { + editButtonTooltip = "If you want to make this previous version active, bring up the Edit window, make any changes " + + "to the old version if they are needed, then click Save. A new version will be created, and set as current."; + editButtonText = "Edit and Activate"; + } + } + + return ( + + + + { + notFoundMessage + ? + {notFoundMessage} + : + + { + successText ? ( + setSuccessText(null)} anchorOrigin={{vertical: "top", horizontal: "center"}}> + setSuccessText(null)}> + {successText} + + + ) : ("") + } + { + failText ? ( + setFailText(null)} anchorOrigin={{vertical: "top", horizontal: "center"}}> + setFailText(null)}> + {failText} + + + ) : ("") + } + + + + <> + + + changeTab(newValue)} + variant="standard" + > + + + + + + + + + + Versions + + {getVersionsList(versionRecordList, selectedVersionRecord)} + + + + + { + selectedVersionRecord ? + + Version {selectedVersionRecord.values.get("sequenceNo")} + { + currentVersionId === selectedVersionRecord.values.get("id") + ? (<> (Current)) + : <> + } + + : <> + } + + + + + { + loadingSelectedVersion.isNotLoading() && selectedVersionRecord && selectedVersionRecord.values.get("contents") ? ( + <> + + + ) : null + } + { + loadingSelectedVersion.isLoadingSlow() && Loading... + } + + + + {/* + + + + + Versions + + {getVersionsList(versionRecordList, selectedVersionRecord)} + + + + Data Preview (Version {selectedVersionRecord?.values?.get("sequenceNo")}) + + + {loadingSelectedVersion.isNotLoading() && selectedTab == 1 && selectedVersionRecord?.values?.get("data") && } + {loadingSelectedVersion.isLoadingSlow() && Loading...} + + + + + */} + + + + + { + editorProps && + closeEditingScript(event, reason)}> + + + } + + + } + + + + ); +} diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AssociatedRecordScriptTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AssociatedRecordScriptTest.java new file mode 100755 index 0000000..737d32a --- /dev/null +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/AssociatedRecordScriptTest.java @@ -0,0 +1,65 @@ +/* + * 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 . + */ + +package com.kingsrook.qqq.materialdashboard.tests; + + +import com.kingsrook.qqq.materialdashboard.lib.QBaseSeleniumTest; +import com.kingsrook.qqq.materialdashboard.lib.javalin.QSeleniumJavalin; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/******************************************************************************* + ** Test for Associated Record Scripts functionality. + *******************************************************************************/ +public class AssociatedRecordScriptTest extends QBaseSeleniumTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + protected void addJavalinRoutes(QSeleniumJavalin qSeleniumJavalin) + { + super.addJavalinRoutes(qSeleniumJavalin); + qSeleniumJavalin.withRouteToFile("/data/person/1", "data/person/1701.json"); + qSeleniumJavalin.withRouteToFile("/data/person/1/developer", "data/person/1701.json"); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testNavigatingBackAndForth() + { + qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/peopleApp/greetingsApp/person/1", "John Doe"); + qSeleniumLib.waitForSelectorContaining("BUTTON", "actions").click(); + + qSeleniumLib.waitForSelectorContaining("LI", "Developer Mode").click(); + assertTrue(qSeleniumLib.driver.getCurrentUrl().endsWith("/1/dev")); + + qSeleniumLib.waitForever(); + } + +} diff --git a/src/test/java/com/kingsrook/qqq/materialdashboard/tests/ScriptTableTest.java b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/ScriptTableTest.java new file mode 100755 index 0000000..0f3f85b --- /dev/null +++ b/src/test/java/com/kingsrook/qqq/materialdashboard/tests/ScriptTableTest.java @@ -0,0 +1,66 @@ +/* + * 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 . + */ + +package com.kingsrook.qqq.materialdashboard.tests; + + +import com.kingsrook.qqq.materialdashboard.lib.QBaseSeleniumTest; +import com.kingsrook.qqq.materialdashboard.lib.javalin.QSeleniumJavalin; +import org.junit.jupiter.api.Test; + + +/******************************************************************************* + ** Test for the scripts table + *******************************************************************************/ +public class ScriptTableTest extends QBaseSeleniumTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + protected void addJavalinRoutes(QSeleniumJavalin qSeleniumJavalin) + { + super.addJavalinRoutes(qSeleniumJavalin); + qSeleniumJavalin + .withRouteToFile("/data/script/1", "data/script/1.json") + .withRouteToFile("/metaData/table/script", "metaData/table/script.json") + .withRouteToFile("/widget/scriptViewer", "widget/scriptViewer.json") + ; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void test() + { + qSeleniumLib.gotoAndWaitForBreadcrumbHeader("/developer/script/1", "Hello, Script"); + + qSeleniumLib.waitForSelectorContaining("span", "uh, script"); + + qSeleniumLib.takeScreenshotToFile(); + // qSeleniumLib.waitForever(); + } + +} diff --git a/src/test/resources/fixtures/data/person/developer.json b/src/test/resources/fixtures/data/person/developer.json new file mode 100644 index 0000000..3efcb82 --- /dev/null +++ b/src/test/resources/fixtures/data/person/developer.json @@ -0,0 +1,276 @@ +{ + "record": { + "tableName": "client", + "recordLabel": "John Doe", + "values": { + "name": "John Doe", + "id": 120, + "deposcoOrderOptimizationCoolingScriptId": 2, + "createDate": "2022-08-30T00:31:00Z", + "modifyDate": "2023-02-19T01:28:30Z", + "isFulfillmentCenter": false, + "infoplusLobId": 18698, + "deposcoBusinessUnitName": "TRIFECTA", + "deposcoBusinessUnitId": 77, + "optimizationConfigId": 1, + "nfCode": "Client 224" + }, + "displayValues": { + "optimizationConfigId": "Client: 120", + "name": "John Doe", + "id": "120", + "deposcoOrderOptimizationCoolingScriptId": "2", + "createDate": "2022-08-30T00:31:00Z", + "modifyDate": "2023-02-19T01:28:30Z", + "isFulfillmentCenter": "No", + "infoplusLobId": "18698", + "deposcoBusinessUnitName": "TRIFECTA", + "deposcoBusinessUnitId": "77", + "nfCode": "Client 224" + } + }, + "associatedScripts": [ + { + "testInputFields": [ + { + "name": "selectedTimeInTransitDays", + "label": "Selected Time In Transit Days", + "type": "INTEGER", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + }, + { + "name": "standardTimeInTransitDays", + "label": "Standard Time In Transit Days", + "type": "INTEGER", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + } + ], + "scriptType": { + "tableName": "scriptType", + "values": { + "name": "Deposco Order Optimization Cooling", + "id": 2, + "createDate": "2022-10-31T19:06:50Z", + "modifyDate": "2022-10-31T19:06:50Z" + } + }, + "scriptRevisions": [ + { + "tableName": "scriptRevision", + "values": { + "id": 1, + "contents": "1;", + "createDate": "2023-02-19T01:28:30Z", + "modifyDate": "2023-02-19T01:28:30Z", + "scriptId": 2, + "sequenceNo": 1, + "commitMessage": "Initial version", + "author": "Darin Kelkhoff" + } + } + ], + "testOutputFields": [ + { + "name": "sku", + "label": "Sku", + "type": "STRING", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + }, + { + "name": "quantityPerCarton", + "label": "Quantity Per Carton", + "type": "INTEGER", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + }, + { + "name": "useClientProvidedCoolingSolution", + "label": "Use Client Provided Cooling Solution", + "type": "BOOLEAN", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + }, + { + "name": "reason", + "label": "Reason", + "type": "STRING", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + } + ], + "script": { + "tableName": "script", + "values": { + "name": "John Doe - Deposco Order Optimization Cooling", + "id": 2, + "scriptTypeId": 2, + "createDate": "2023-02-19T01:28:30Z", + "modifyDate": "2023-02-19T01:28:30Z", + "currentScriptRevisionId": 1 + } + }, + "associatedScript": { + "fieldName": "deposcoOrderOptimizationCoolingScriptId", + "scriptTypeId": 2, + "scriptTester": { + "name": "com.nutrifresh.one.processes.deposco.RunDeposcoOrderOptimizationCoolingScript", + "codeType": "JAVA", + "codeUsage": "SCRIPT_TESTER" + } + } + }, + { + "testInputFields": [ + { + "name": "selectedTimeInTransitDays", + "label": "Selected Time In Transit Days", + "type": "INTEGER", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + }, + { + "name": "standardTimeInTransitDays", + "label": "Standard Time In Transit Days", + "type": "INTEGER", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + }, + { + "name": "runtimeWeekday", + "label": "Runtime Weekday", + "type": "INTEGER", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + } + ], + "scriptType": { + "tableName": "scriptType", + "values": { + "name": "Deposco Order Optimization Batch Name", + "id": 1, + "createDate": "2022-10-31T19:06:50Z", + "modifyDate": "2022-10-31T19:06:50Z" + } + }, + "testOutputFields": [ + { + "name": "batchName", + "label": "Batch Name", + "type": "STRING", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + }, + { + "name": "reason", + "label": "Reason", + "type": "STRING", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + } + ], + "associatedScript": { + "fieldName": "deposcoOrderOptimizationBatchNameScriptId", + "scriptTypeId": 1, + "scriptTester": { + "name": "com.nutrifresh.one.processes.deposco.RunDeposcoOrderOptimizationBatchNameScript", + "codeType": "JAVA", + "codeUsage": "SCRIPT_TESTER" + } + } + }, + { + "testInputFields": [ + { + "name": "selectedTimeInTransitDays", + "label": "Selected Time In Transit Days", + "type": "INTEGER", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + }, + { + "name": "standardTimeInTransitDays", + "label": "Standard Time In Transit Days", + "type": "INTEGER", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + }, + { + "name": "runtimeWeekday", + "label": "Runtime Weekday", + "type": "INTEGER", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + } + ], + "scriptType": { + "tableName": "scriptType", + "values": { + "name": "Deposco Order Optimization Batch Name", + "id": 1, + "createDate": "2022-10-31T19:06:50Z", + "modifyDate": "2022-10-31T19:06:50Z" + } + }, + "testOutputFields": [ + { + "name": "batchName", + "label": "Batch Name", + "type": "STRING", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + }, + { + "name": "reason", + "label": "Reason", + "type": "STRING", + "isRequired": false, + "isEditable": true, + "isHeavy": false, + "displayFormat": "%s" + } + ], + "associatedScript": { + "fieldName": "deposcoOrderOptimizationCartonizationScriptId", + "scriptTypeId": 1, + "scriptTester": { + "name": "com.nutrifresh.one.processes.deposco.RunDeposcoOrderOptimizationBatchNameScript", + "codeType": "JAVA", + "codeUsage": "SCRIPT_TESTER" + } + } + } + ] +} \ No newline at end of file diff --git a/src/test/resources/fixtures/data/script/1.json b/src/test/resources/fixtures/data/script/1.json new file mode 100644 index 0000000..59a8d1b --- /dev/null +++ b/src/test/resources/fixtures/data/script/1.json @@ -0,0 +1,20 @@ +{ + "tableName": "script", + "recordLabel": "Hello, Script", + "values": { + "name": "Hello, Script", + "id": 1, + "tableName": "client", + "createDate": "2023-02-18T00:47:51Z", + "modifyDate": "2023-02-18T00:47:51Z", + "scriptTypeId": 1 + }, + "displayValues": { + "tableName": "Client", + "scriptTypeId": "Unknown", + "name": "Hello, Script", + "id": "1", + "createDate": "2023-02-18T00:47:51Z", + "modifyDate": "2023-02-18T00:47:51Z" + } +} \ No newline at end of file diff --git a/src/test/resources/fixtures/metaData/table/script.json b/src/test/resources/fixtures/metaData/table/script.json new file mode 100644 index 0000000..e4b664f --- /dev/null +++ b/src/test/resources/fixtures/metaData/table/script.json @@ -0,0 +1,139 @@ +{ + "table": { + "name": "script", + "label": "Script", + "isHidden": false, + "primaryKeyField": "id", + "iconName": "data_object", + "fields": { + "modifyDate": { + "name": "modifyDate", + "label": "Modify Date", + "type": "DATE_TIME", + "isRequired": false, + "isEditable": false, + "displayFormat": "%s" + }, + "name": { + "name": "name", + "label": "Name", + "type": "STRING", + "isRequired": false, + "isEditable": true, + "displayFormat": "%s" + }, + "currentScriptRevisionId": { + "name": "currentScriptRevisionId", + "label": "Current Script Revision", + "type": "INTEGER", + "isRequired": false, + "isEditable": true, + "possibleValueSourceName": "scriptRevision", + "displayFormat": "%s", + "adornments": [ + { + "type": "LINK", + "values": { + "toRecordFromTable": "scriptRevision" + } + } + ] + }, + "id": { + "name": "id", + "label": "Id", + "type": "INTEGER", + "isRequired": false, + "isEditable": false, + "displayFormat": "%s" + }, + "tableName": { + "name": "tableName", + "label": "Table Name", + "type": "STRING", + "isRequired": false, + "isEditable": true, + "possibleValueSourceName": "tables", + "displayFormat": "%s" + }, + "createDate": { + "name": "createDate", + "label": "Create Date", + "type": "DATE_TIME", + "isRequired": false, + "isEditable": false, + "displayFormat": "%s" + }, + "scriptTypeId": { + "name": "scriptTypeId", + "label": "Script Type", + "type": "INTEGER", + "isRequired": false, + "isEditable": true, + "possibleValueSourceName": "scriptType", + "displayFormat": "%s", + "adornments": [ + { + "type": "LINK", + "values": { + "toRecordFromTable": "scriptType" + } + } + ] + } + }, + "sections": [ + { + "name": "identity", + "label": "Identity", + "tier": "T1", + "fieldNames": [ + "id", + "name", + "scriptTypeId", + "tableName", + "currentScriptRevisionId" + ], + "icon": { + "name": "badge" + }, + "isHidden": false + }, + { + "name": "contents", + "label": "Contents", + "tier": "T2", + "widgetName": "scriptViewer", + "icon": { + "name": "data_object" + }, + "isHidden": false + }, + { + "name": "dates", + "label": "Dates", + "tier": "T3", + "fieldNames": [ + "createDate", + "modifyDate" + ], + "icon": { + "name": "calendar_month" + }, + "isHidden": false + } + ], + "capabilities": [ + "TABLE_COUNT", + "TABLE_GET", + "TABLE_QUERY", + "TABLE_INSERT", + "TABLE_DELETE", + "TABLE_UPDATE" + ], + "readPermission": true, + "insertPermission": true, + "editPermission": true, + "deletePermission": true + } +} \ No newline at end of file diff --git a/src/test/resources/fixtures/widget/scriptViewer.json b/src/test/resources/fixtures/widget/scriptViewer.json new file mode 100644 index 0000000..12f33aa --- /dev/null +++ b/src/test/resources/fixtures/widget/scriptViewer.json @@ -0,0 +1,7 @@ +{ + "type": "scriptViewer", + "queryParams": { + "id": "1", + "tableName": "script" + } +} \ No newline at end of file