From 8f7823150ab05bebf26cf3ba3ae01a14441f447b Mon Sep 17 00:00:00 2001 From: frikky Date: Tue, 18 Oct 2022 20:12:13 +0200 Subject: [PATCH] Fixed app generation and usage problems with quotes and dollarsigns --- frontend/src/components/ParsedAction.jsx | 16 +- frontend/src/views/AngularWorkflow.jsx | 15 +- frontend/src/views/AppCreator.jsx | 17 +- frontend/src/views/Workflows.jsx | 212 ++++++++++++++++++----- 4 files changed, 205 insertions(+), 55 deletions(-) diff --git a/frontend/src/components/ParsedAction.jsx b/frontend/src/components/ParsedAction.jsx index 76327db0..455c0e57 100644 --- a/frontend/src/components/ParsedAction.jsx +++ b/frontend/src/components/ParsedAction.jsx @@ -572,7 +572,7 @@ const ParsedAction = (props) => { } } - console.log("New found: ", new_occurences)) + console.log("New found: ", new_occurences) found = new_occurences.valueOf() } @@ -632,10 +632,12 @@ const ParsedAction = (props) => { ); if (paramcheck !== undefined) { // Escapes all double quotes - const toReplace = event.target.value - .trim() - .replaceAll('\\"', '"') - .replaceAll('"', '\\"'); + var toReplace = event.target.value.trim() + + + if (!toReplace.startsWith("{") && !toReplace.startsWith("[")) { + toReplace = toReplace.replaceAll('\\"', '"').replaceAll('"', '\\"') + } console.log("REPLACE WITH: ", toReplace); if ( @@ -1459,7 +1461,9 @@ const ParsedAction = (props) => { if (found === null || !hideBody) { if (found === null) { setActivateHidingBodyButton(true); - } + } else { + console.log("In found: ", found, hideBody) + } } else { //console.log("SHOW BUTTON"); diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index c11c9f8e..f10240dd 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -14,6 +14,7 @@ import { useAlert } from "react-alert"; import theme from '../theme'; import { isMobile } from "react-device-detect" import aa from 'search-insights' +import Drift from "react-driftjs"; import { InstantSearch, Configure, connectSearchBox, connectHits, Index } from 'react-instantsearch-dom'; import algoliasearch from 'algoliasearch/lite'; @@ -6336,7 +6337,7 @@ const AngularWorkflow = (defaultprops) => { window.open(parsedUrl, '_blank') }, 2000) } else { - alert.info(`Activating ${name} and refreshing apps.`) + alert.info(`Activating ${name}`) } console.log("CLICK: ", hit) @@ -8176,7 +8177,8 @@ const AngularWorkflow = (defaultprops) => { `https%3A%2F%2F${window.location.host}%2Fapi%2Fv1%2Ftriggers%2Foutlook%2Fregister` //const client_id = "fd55c175-aa30-4fa6-b303-09a29fb3f750" - const client_id = "bb4bff85-0d0b-4f5d-8a69-3cee8029b11a"; + //const client_id = "bb4bff85-0d0b-4f5d-8a69-3cee8029b11a"; + const client_id = "efe4c3fe-84a1-4821-a84f-23a6cfe8e72d"; const username = userdata.id; console.log(redirectUri); @@ -8392,6 +8394,15 @@ const AngularWorkflow = (defaultprops) => { {outlookButton} {gmailButton} + + If you have trouble using this trigger, please { + if (window.drift !== undefined) { + window.drift.api.startInteraction({ interactionId: 340043 }) + } else { + console.log("Couldn't find drift in window.drift and not .drift-open-chat with querySelector: ", window.drift) + } + }}>contact us to get access + ); diff --git a/frontend/src/views/AppCreator.jsx b/frontend/src/views/AppCreator.jsx index 39caf622..954dace9 100644 --- a/frontend/src/views/AppCreator.jsx +++ b/frontend/src/views/AppCreator.jsx @@ -1982,7 +1982,7 @@ const AppCreator = (defaultprops) => { item.body !== null && item.body.length > 0 ) { - console.log("GOT BODY: ", item.url, item.method) + console.log("GOT BODY: ", item.url, item.method, item.body) // Replacing dollarsign insertions that aren't escaped // This is to stop it from messing with systems in Shuffle. @@ -1994,8 +1994,11 @@ const AppCreator = (defaultprops) => { if (item.body[key] === "$") { if (key > 0) { //console.log("Found: ", item.body[key-1]) - if (item.body[key-1] !== "\\") { - newbody += "\\" + const newkey = parseInt(key, 10) + if (item.body[newkey-1] !== "\\") { + if (item.body[newkey+1] !== "\{") { + newbody += "\\" + } } newbody += item.body[key] @@ -2009,8 +2012,8 @@ const AppCreator = (defaultprops) => { } } + console.log("New body: ", newbody) if (newbody !== item.body) { - //console.log("New body: ", newbody) item.body = newbody } @@ -3272,7 +3275,7 @@ const AppCreator = (defaultprops) => { margin="normal" variant="outlined" multiline - rows="5" + minRows="5" defaultValue={currentAction["body"]} onChange={(e) => { setActionField("body", e.target.value); @@ -3310,7 +3313,7 @@ const AppCreator = (defaultprops) => { margin="normal" variant="outlined" multiline - rows="2" + minRows="2" defaultValue={currentAction["example_response"]} onChange={(e) => setActionField("example_response", e.target.value)} helperText={ @@ -3990,7 +3993,7 @@ const AppCreator = (defaultprops) => { id="standard-required" defaultValue={currentAction["headers"]} multiline - rows="2" + minRows="2" onChange={(e) => setActionField("headers", e.target.value)} helperText={ diff --git a/frontend/src/views/Workflows.jsx b/frontend/src/views/Workflows.jsx index b8f2c62a..6611be2b 100644 --- a/frontend/src/views/Workflows.jsx +++ b/frontend/src/views/Workflows.jsx @@ -1,10 +1,12 @@ import React, { useEffect, useContext } from "react"; +import ReactDOM from "react-dom" import { makeStyles } from "@material-ui/core/styles"; import { useTheme } from "@material-ui/core/styles"; import { Navigate } from "react-router-dom"; //import { Redirect } from "react-router-dom"; import SecurityFramework from '../components/SecurityFramework.jsx'; +import EditWorkflow from "../components/EditWorkflow.jsx" import { ShepherdTour, ShepherdTourContext } from 'react-shepherd' import { isMobile } from "react-device-detect" @@ -406,6 +408,13 @@ export const validateJson = (showResult) => { } } + if (showResult[0] === "\"") { + return { + valid: false, + result: showResult, + } + } + var jsonvalid = true try { if (!showResult.includes("{") && !showResult.includes("[")) { @@ -523,6 +532,7 @@ const Workflows = (props) => { const [exportData, setExportData] = React.useState(""); const [modalOpen, setModalOpen] = React.useState(false); + const [isEditing, setIsEditing] = React.useState(true); const [newWorkflowName, setNewWorkflowName] = React.useState(""); const [newWorkflowDescription, setNewWorkflowDescription] = React.useState(""); @@ -545,12 +555,14 @@ const Workflows = (props) => { const [firstLoad, setFirstLoad] = React.useState(true); const [showMoreClicked, setShowMoreClicked] = React.useState(false); const [usecases, setUsecases] = React.useState([]); + const [appFramework, setAppFramework] = React.useState({}); const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io"; const findWorkflow = (filters) => { + console.log("Using filters: ", filters) if (filters.length === 0) { setFilteredWorkflows(workflows); return; @@ -565,27 +577,44 @@ const Workflows = (props) => { found = filters.map((filter) => curWorkflow.name.toLowerCase().includes(filter) ); - } else { + } + + if (found.every((v) => v !== true)) { found = filters.map((filter) => { - const newfilter = filter.toLowerCase(); - if (filter === undefined) { + if (filter === undefined || filter === null) { return false; } + const newfilter = filter.toLowerCase(); + if (curWorkflow.name.toLowerCase().includes(filter.toLowerCase())) { return true; - } else if (curWorkflow.tags.includes(filter)) { + } else if (curWorkflow.tags !== undefined && curWorkflow.tags !== null && curWorkflow.tags.includes(filter)) { return true; } else if (curWorkflow.owner === filter) { return true; } else if (curWorkflow.org_id === filter) { return true; + } else if (curWorkflow.usecase_ids !== undefined && curWorkflow.usecase_ids !== null && curWorkflow.usecase_ids.length > 0) { + // Check if the usecase is the right category + for (var key in usecases) { + if (usecases[key].name.toLowerCase() !== newfilter) { + continue + } + + for (var subkey in usecases[key].list) { + if (curWorkflow.usecase_ids.includes(usecases[key].list[subkey].name)) { + return true + } + } + } } else if ( curWorkflow.actions !== null && curWorkflow.actions !== undefined ) { for (var key in curWorkflow.actions) { const action = curWorkflow.actions[key]; + if ( action.app_name.toLowerCase() === newfilter || action.app_name.toLowerCase().includes(newfilter) @@ -593,7 +622,7 @@ const Workflows = (props) => { return true; } } - } + } return false; }); @@ -612,14 +641,17 @@ const Workflows = (props) => { const addFilter = (data) => { if (data === null || data === undefined) { + console.log("No filter data") return; } if (data.includes("<") && data.includes(">")) { + console.log("Filter includes < or >") return; } if (filters.includes(data) || filters.includes(data.toLowerCase())) { + console.log("Filter already has the data") return; } @@ -886,6 +918,39 @@ const Workflows = (props) => { } }, [isDropzone]); + const getFramework = () => { + fetch(globalUrl + "/api/v1/apps/frameworkConfiguration", { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + console.log("Status not 200 for framework!"); + } + + return response.json(); + }) + .then((responseJson) => { + if (responseJson.success === false) { + setAppFramework({}) + if (responseJson.reason !== undefined) { + //alert.error("Failed loading: " + responseJson.reason) + } else { + //alert.error("Failed to load framework for your org.") + } + } else { + setAppFramework(responseJson) + } + }) + .catch((error) => { + console.log("err in framework: ", error.toString()); + }) + } + const getAvailableWorkflows = () => { fetch(globalUrl + "/api/v1/workflows", { method: "GET", @@ -904,7 +969,6 @@ const Workflows = (props) => { } alert.info("Failed getting workflows."); - setWorkflowDone(true); return; } @@ -922,7 +986,7 @@ const Workflows = (props) => { newarray.push(wf) } - setWorkflows(newarray); + // Workflows are set in here fetchUsecases(newarray) var setProdFilter = false @@ -965,7 +1029,6 @@ const Workflows = (props) => { } // Ensures the zooming happens only once per load - setWorkflowDone(true); setTimeout(() => { setFirstLoad(false) }, 100) @@ -1001,6 +1064,7 @@ const Workflows = (props) => { if (workflow.usecase_ids !== undefined && workflow.usecase_ids !== null) { for (var usecasekey in workflow.usecase_ids) { + if (workflow.usecase_ids[usecasekey].toLowerCase() === subcategory.name.toLowerCase()) { //console.log("Got match: ", workflow.usecase_ids[usecasekey]) @@ -1027,6 +1091,8 @@ const Workflows = (props) => { } else { setUsecases(categorydata) } + setWorkflows(workflows); + setWorkflowDone(true); } const fetchUsecases = (workflows) => { @@ -1048,11 +1114,16 @@ const Workflows = (props) => { .then((responseJson) => { if (responseJson.success !== false) { handleKeysetting(responseJson, workflows) + } else { + setWorkflows(workflows); + setWorkflowDone(true); } }) .catch((error) => { //alert.error("ERROR: " + error.toString()); console.log("ERROR: " + error.toString()); + setWorkflows(workflows); + setWorkflowDone(true); }); }; @@ -1065,6 +1136,7 @@ const Workflows = (props) => { } getAvailableWorkflows(); + getFramework() } }, []) @@ -1452,7 +1524,10 @@ const Workflows = (props) => { setModalOpen(true)} + onClick={() => { + setModalOpen(true) + setIsEditing(false) + }} onMouseOver={() => { setHover(true); }} @@ -1505,7 +1580,7 @@ const Workflows = (props) => { } if (!data.previously_saved) { - boxColor = "#f85a3e"; + boxColor = "#f86a3e"; } const menuClick = (event) => { @@ -1539,25 +1614,27 @@ const Workflows = (props) => { > { - setModalOpen(true); - setEditingWorkflow(JSON.parse(JSON.stringify(data))); - setNewWorkflowName(data.name); - setNewWorkflowDescription(data.description); - setDefaultReturnValue(data.default_return_value); - if (data.tags !== undefined && data.tags !== null) { - setNewWorkflowTags(JSON.parse(JSON.stringify(data.tags))); - } + onClick={(event) => { + event.stopPropagation() + ReactDOM.unstable_batchedUpdates(() => { + setModalOpen(true); + setEditingWorkflow(JSON.parse(JSON.stringify(data))); + setNewWorkflowName(data.name); + setNewWorkflowDescription(data.description); + setDefaultReturnValue(data.default_return_value); + if (data.tags !== undefined && data.tags !== null) { + setNewWorkflowTags(JSON.parse(JSON.stringify(data.tags))); + } - console.log("Editing: ", data) - if (data.usecase_ids !== undefined && data.usecase_ids !== null && data.usecase_ids.length > 0) { - setSelectedUsecases(data.usecase_ids) - } + if (data.usecase_ids !== undefined && data.usecase_ids !== null && data.usecase_ids.length > 0) { + setSelectedUsecases(data.usecase_ids) + } + }) }} key={"change"} > - {"Change details"} + {"Edit details"} { } } + var selectedCategory = "" + if (data.usecase_ids !== undefined && data.usecase_ids !== null && data.usecase_ids.length > 0 && usecases !== null && usecases !== undefined && usecases.length > 0) { + const oldcolor = boxColor.valueOf() + + // Find the first usecase and use that ones' ID + for (var key in usecases) { + var category = usecases[key] + category.matches = [] + + for (var subcategorykey in category.list) { + var subcategory = category.list[subcategorykey] + subcategory.matches = [] + + for (var usecasekey in data.usecase_ids) { + if (data.usecase_ids[usecasekey].toLowerCase() === subcategory.name.toLowerCase()) { + boxColor = category.color + break + } + } + + if (boxColor !== oldcolor) { + break + } + } + + if (boxColor !== oldcolor) { + selectedCategory = category.name + break + } + } + } + return (
-
+ {selectedCategory !== "" ? + +
{ + addFilter(selectedCategory) + }} + /> + + : null} { return } - if (method === "POST" && redirect) { - window.location.pathname = "/workflows/" + responseJson["id"]; - setModalOpen(false); + if (redirect) { + //window.location.pathname = "/workflows/" + responseJson["id"]; + navigate("/workflows/" + responseJson["id"]) + //setModalOpen(false); } else if (!redirect) { // Update :) setTimeout(() => { @@ -2034,7 +2152,7 @@ const Workflows = (props) => { setImportLoading(false); setModalOpen(false); } else { - alert.info("Successfully changed basic info for workflow"); + //alert.info("Successfully changed basic info for workflow"); setModalOpen(false); } @@ -3498,11 +3616,25 @@ const Workflows = (props) => { > - {modalView} + {/*modalView*/} {deleteModal} {exportVerifyModal} {publishModal} {workflowDownloadModalOpen} + + {modalOpen === true ? + + : null} {/*
Need assistance? Ask our support team (it's free!).