From 66d7cd4e80ec50ff325cf15a187d80f2db9a3a8e Mon Sep 17 00:00:00 2001 From: frikky Date: Thu, 21 Jul 2022 00:30:17 +0200 Subject: [PATCH] Bunch of fixes for new welcome pages and search fields --- backend/app_sdk/app_base.py | 12 + docker-compose.yml | 62 ++--- frontend/src/components/AppGrid.jsx | 3 +- frontend/src/components/Appsearch.jsx | 211 ++++++++++++++++++ .../src/components/DetectionFramework.jsx | 32 ++- frontend/src/components/DocsGrid.jsx | 3 +- frontend/src/components/Header.js | 4 +- frontend/src/components/ParsedAction.jsx | 83 ++++--- frontend/src/components/Searchfield.js | 4 +- frontend/src/components/ShuffleCodeEditor.jsx | 1 + frontend/src/components/Workflowsearch.jsx | 211 ++++++++++++++++++ frontend/src/theme.js | 1 + frontend/src/views/AngularWorkflow.jsx | 7 +- frontend/src/views/AppCreator.jsx | 2 +- frontend/src/views/Search.jsx | 8 +- functions/onprem/orborus/build.sh | 2 +- functions/onprem/orborus/go.mod | 2 +- functions/onprem/orborus/go.sum | 4 + functions/onprem/orborus/orborus.go | 40 ++-- 19 files changed, 590 insertions(+), 102 deletions(-) create mode 100644 frontend/src/components/Appsearch.jsx diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index 164b515b..db34e0e2 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -127,12 +127,24 @@ def json_escape(a): a = str(a) return a.replace("\\\'", "\'", -1).replace("\\\"", "\"", -1).replace("'", "\\\\\'", -1).replace("\"", "\\\\\"", -1) +@shuffle_filters.register +def escape_json(a): + a = str(a) + return a.replace("\\\'", "\'", -1).replace("\\\"", "\"", -1).replace("'", "\\\\\'", -1).replace("\"", "\\\\\"", -1) + # By default using json escape to add all backslashes @shuffle_filters.register def escape(a): a = str(a) return json_escape(a) +@shuffle_filters.register +def flatten(a): + a = list(a) + + flat_list = [a for xs in xss for a in xs] + return flat_list + #print(standard_filter_manager.filters) #print(shuffle_filters.filters) #print(Liquid("{{ '10' | plus: 1}}", filters=shuffle_filters.filters).render()) diff --git a/docker-compose.yml b/docker-compose.yml index 57eecc46..35a921e8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,12 +26,13 @@ services: networks: - shuffle volumes: - - /var/run/docker.sock:/var/run/docker.sock + #- /var/run/docker.sock:/var/run/docker.sock - ${SHUFFLE_APP_HOTLOAD_LOCATION}:/shuffle-apps:z - ${SHUFFLE_FILE_LOCATION}:/shuffle-files:z #- ${SHUFFLE_OPENSEARCH_CERTIFICATE_FILE}:/shuffle-files/es_certificate env_file: .env environment: + - DOCKER_HOST=tcp://docker-socket-proxy:2375 - SHUFFLE_APP_HOTLOAD_FOLDER=/shuffle-apps - SHUFFLE_FILE_LOCATION=/shuffle-files restart: unless-stopped @@ -39,14 +40,15 @@ services: #- opensearch #Not necessary because dependancy is handled within the backend itself instead #- database orborus: - image: ghcr.io/frikky/shuffle-orborus:latest + image: ghcr.io/frikky/shuffle-orborus:nightly container_name: shuffle-orborus hostname: shuffle-orborus networks: - shuffle - volumes: - - /var/run/docker.sock:/var/run/docker.sock + #volumes: + # - /var/run/docker.sock:/var/run/docker.sock environment: + - DOCKER_HOST=tcp://docker-socket-proxy:2375 - SHUFFLE_WORKER_VERSION=latest - ENVIRONMENT_NAME=${ENVIRONMENT_NAME} - BASE_URL=http://${OUTER_HOSTNAME}:5001 @@ -91,31 +93,33 @@ services: networks: - shuffle restart: unless-stopped - #docker-socket-proxy: - # image: tecnativa/docker-socket-proxy - # container_name: shuffle-frontend - # privileged: true - # environment: - # - SERVICES=1 - # - TASKS=1 - # - NETWORKS=1 - # - NODES=1 - # - BUILD=1 - # - IMAGES=1 - # - GRPC=1 - # - CONTAINERS=1 - # - PLUGINS=1 - # - SYSTEM=1 - # - VOLUMES=1 - # - INFO=1 - # - DISTRIBUTION=1 - # - POST=1 - # - AUTH=1 - # - SECRETS=1 - # volumes: - # - /var/run/docker.sock:/var/run/docker.sock - # networks: - # - shuffle + docker-socket-proxy: + image: tecnativa/docker-socket-proxy + container_name: shuffle-frontend + hostname: docker-socket-proxy + privileged: true + environment: + - SERVICES=1 + - TASKS=1 + - NETWORKS=1 + - NODES=1 + - BUILD=1 + - IMAGES=1 + - GRPC=1 + - CONTAINERS=1 + - PLUGINS=1 + - SYSTEM=1 + - VOLUMES=1 + - INFO=1 + - DISTRIBUTION=1 + - POST=1 + - AUTH=1 + - SECRETS=1 + - SWARM=1 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + networks: + - shuffle networks: shuffle: driver: bridge diff --git a/frontend/src/components/AppGrid.jsx b/frontend/src/components/AppGrid.jsx index 77800d17..4a197d24 100644 --- a/frontend/src/components/AppGrid.jsx +++ b/frontend/src/components/AppGrid.jsx @@ -26,7 +26,7 @@ import { const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240") //const searchClient = algoliasearch("L55H18ZINA", "a19be455e7e75ee8f20a93d26b9fc6d6") const AppGrid = props => { - const { maxRows, showName, showSuggestion, isMobile, globalUrl, parsedXs } = props + const { maxRows, showName, showSuggestion, isMobile, globalUrl, parsedXs, userdata } = props const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io"; @@ -225,6 +225,7 @@ const AppGrid = props => { timestamp: timestamp, queryID: data.__queryID, positions: [data.__position], + userToken: userdata === undefined || userdata === null || userdata.id === undefined ? "unauthenticated" : userdata.id, } ]) diff --git a/frontend/src/components/Appsearch.jsx b/frontend/src/components/Appsearch.jsx new file mode 100644 index 00000000..430382fe --- /dev/null +++ b/frontend/src/components/Appsearch.jsx @@ -0,0 +1,211 @@ +import React, { useState, useEffect } from 'react'; + +import ReactGA from 'react-ga'; +import { useTheme } from '@material-ui/core/styles'; +import {Link} from 'react-router-dom'; + +import { Search as SearchIcon, CloudQueue as CloudQueueIcon, Code as CodeIcon } from '@material-ui/icons'; + +//import algoliasearch from 'algoliasearch/lite'; +import algoliasearch from 'algoliasearch'; +import { InstantSearch, connectSearchBox, connectHits } from 'react-instantsearch-dom'; +import { Grid, Paper, TextField, ButtonBase, InputAdornment, Typography, Button, Tooltip} from '@material-ui/core'; + +const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240") +const WorkflowSearch = props => { + const { maxRows, showName, showSuggestion, isMobile, globalUrl, parsedXs, newSelectedApp, setNewSelectedApp, defaultSearch, showSearch, ConfiguredHits } = props + const rowHandler = maxRows === undefined || maxRows === null ? 50 : maxRows + const xs = parsedXs === undefined || parsedXs === null ? 12 : parsedXs + const theme = useTheme(); + //const [apps, setApps] = React.useState([]); + //const [filteredApps, setFilteredApps] = React.useState([]); + const [formMail, setFormMail] = React.useState(""); + const [message, setMessage] = React.useState(""); + const [formMessage, setFormMessage] = React.useState(""); + const [selectedApp, setSelectedApp] = React.useState({}); + + const buttonStyle = {borderRadius: 30, height: 50, width: 220, margin: isMobile ? "15px auto 15px auto" : 20, fontSize: 18,} + + const innerColor = "rgba(255,255,255,0.65)" + const borderRadius = 3 + window.title = "Shuffle | Apps | Find and integration any app" + + const submitContact = (email, message) => { + const data = { + "firstname": "", + "lastname": "", + "title": "", + "companyname": "", + "email": email, + "phone": "", + "message": message, + } + + const errorMessage = "Something went wrong. Please contact frikky@shuffler.io directly." + + fetch(globalUrl+"/api/v1/contact", { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + }) + .then(response => response.json()) + .then(response => { + if (response.success === true) { + setFormMessage(response.reason) + //alert.info("Thanks for submitting!") + } else { + setFormMessage(errorMessage) + } + + setFormMail("") + setMessage("") + }) + .catch(error => { + setFormMessage(errorMessage) + console.log(error) + }); + } + + // value={currentRefinement} + const SearchBox = ({currentRefinement, refine, isSearchStalled} ) => { + useEffect(() => { + //console.log("FIRST LOAD ONLY? RUN REFINEMENT: !", currentRefinement) + if (defaultSearch !== undefined && defaultSearch !== null) { + refine(defaultSearch) + } + }, []) + + return ( +
+ + + + ), + }} + autoComplete='on' + type="search" + color="primary" + defaultValue={defaultSearch} + placeholder={`Find ${defaultSearch} Apps...`} + id="shuffle_workflow_search_field" + onChange={(event) => { + refine(event.currentTarget.value) + }} + limit={5} + /> + {/*isSearchStalled ? 'My search is stalled' : ''*/} + + ) + //value={currentRefinement} + } + + const Hits = ({ hits }) => { + const [mouseHoverIndex, setMouseHoverIndex] = useState(-1) + var counted = 0 + + return ( + + {hits.map((data, index) => { + const paperStyle = { + backgroundColor: index === mouseHoverIndex ? "rgba(255,255,255,0.8)" : theme.palette.inputColor, + color: index === mouseHoverIndex ? theme.palette.inputColor : "rgba(255,255,255,0.8)", + border: newSelectedApp.objectID !== data.objectID ? `1px solid rgba(255,255,255,0.2)` : "2px solid #f86a3e", + textAlign: "left", + padding: 10, + cursor: "pointer", + position: "relative", + overflow: "hidden", + width: "100%", + } + + if (counted === 12/xs*rowHandler) { + return null + } + + counted += 1 + var parsedname = "" + for (var key = 0; key < data.name.length; key++) { + var character = data.name.charAt(key) + if (character === character.toUpperCase()) { + //console.log(data.name[key], data.name[key+1]) + if (data.name.charAt(key+1) !== undefined && data.name.charAt(key+1) === data.name.charAt(key+1).toUpperCase()) { + } else { + parsedname += " " + } + } + + parsedname += character + } + + parsedname = (parsedname.charAt(0).toUpperCase()+parsedname.substring(1)).replaceAll("_", " ") + + return ( + { + setMouseHoverIndex(index) + /* + ReactGA.event({ + category: "app_grid_view", + action: `search_bar_click`, + label: "", + }) + */ + }} onMouseOut={() => { + setMouseHoverIndex(-1) + }} onClick={() => { + setNewSelectedApp(data) + //if (data.objectID !== data.objectID) { + //} + + //ReactGA.event({ + // category: "app_search", + // action: `app_${parsedname}_${data.id}_click`, + // label: "", + //}) + }}> +
+ {data.name} + + {parsedname} + +
+
+ ) + })} +
+ ) + } + + const InputHits = ConfiguredHits === undefined ? Hits : ConfiguredHits + const CustomSearchBox = connectSearchBox(SearchBox) + const CustomHits = connectHits(InputHits) + + return ( +
+ + {/* showSearch === false ? null : +
+ +
+ */} +
+ +
+ +
+
+ ) +} + +export default WorkflowSearch; diff --git a/frontend/src/components/DetectionFramework.jsx b/frontend/src/components/DetectionFramework.jsx index f4144cdc..c05726ce 100644 --- a/frontend/src/components/DetectionFramework.jsx +++ b/frontend/src/components/DetectionFramework.jsx @@ -3,7 +3,7 @@ import React, { useState, useEffect } from 'react'; import { securityFramework } from "./LandingpageUsecases.jsx"; import CytoscapeComponent from 'react-cytoscapejs'; import frameworkStyle from '../frameworkStyle.jsx'; -import WorkflowSearch from './Workflowsearch.jsx'; +import AppSearch from './Appsearch.jsx'; import { v4 as uuidv4 } from "uuid"; import theme from '../theme'; import { useAlert } from "react-alert"; @@ -518,7 +518,8 @@ export const usecases = { } const Framework = (props) => { - const { globalUrl, isLoaded, showOptions, selectedOption, rolling, frameworkData, size, inputUsecase, isLoggedIn, color } = props; + const { globalUrl, isLoaded, showOptions, selectedOption, rolling, frameworkData, size, inputUsecase, isLoggedIn, color, discoveryWrapper, setDiscoveryWrapper} = props; + const [cy, setCy] = React.useState() const [edgesStarted, setEdgesStarted] = React.useState(false) const [graphDone, setGraphDone] = React.useState(false) @@ -532,6 +533,24 @@ const Framework = (props) => { const alert = useAlert() + useEffect(() => { + console.log("DISCWRAP CHANG: ", discoveryWrapper) + + if (discoveryWrapper === undefined || discoveryWrapper.id === "SHUFFLE" || discoveryWrapper.id === undefined || cy === undefined) { + return + } + + // Find the node and click it? + const nodes = cy.nodes().jsons() + for (var key in nodes) { + const node = nodes[key] + console.log("NOD: ", node) + + //cy.getElementById(node.data.id).click(); + } + //setDiscoveryData(discoveryWrapper) + }, [discoveryWrapper]) + const setUsecaseItem = (inputUsecase) => { var parsedUsecase = inputUsecase const edges = cy.edges().jsons() @@ -1372,6 +1391,7 @@ const Framework = (props) => { } const bgColor = color === undefined || color === null || color.length === 0 ? theme.palette.surfaceColor : color + console.log("BGCOLOR: ", bgColor) return ( @@ -1443,8 +1463,10 @@ const Framework = (props) => { //autounselectify={true} var usecasediff = -100 + const bgColor = color === undefined || color === null || color.length === 0 ? theme.palette.surfaceColor : color + return ( -
+
{showOptions === false ? null :
{Object.keys(usecases).map((data, index) => { @@ -1568,7 +1590,7 @@ const Framework = (props) => { {discoveryData.description} {/*isCloud && defaultSearch !== undefined && defaultSearch.length > 0 ? - { {
{selectionOpen ? - { - const { maxRows, showName, showSuggestion, isMobile, globalUrl, parsedXs } = props + const { maxRows, showName, showSuggestion, isMobile, globalUrl, parsedXs, userdata, } = props const rowHandler = maxRows === undefined || maxRows === null ? 50 : maxRows const xs = parsedXs === undefined || parsedXs === null ? isMobile ? 6 : 2 : parsedXs const theme = useTheme(); @@ -212,6 +212,7 @@ const DocsGrid = props => { timestamp: timestamp, queryID: data.__queryID, positions: [data.__position], + userToken: userdata === undefined || userdata === null || userdata.id === undefined ? "unauthenticated" : userdata.id, } ]) diff --git a/frontend/src/components/Header.js b/frontend/src/components/Header.js index 82696474..b6f0299f 100644 --- a/frontend/src/components/Header.js +++ b/frontend/src/components/Header.js @@ -523,7 +523,7 @@ const Header = (props) => { {!isLoaded ? null : userdata.chat_disabled === true ? null :
- +
}
@@ -629,7 +629,7 @@ const Header = (props) => { {!isLoaded ? null : userdata.chat_disabled === true ? null :
- +
}
{ const paramcheck = selectedAction.parameters.find( (param) => param.name === "body" ); + if (paramcheck !== undefined && paramcheck !== null) { if ( paramcheck["value_replace"] !== undefined && @@ -1459,7 +1460,7 @@ const ParsedAction = (props) => { description: openApiFieldDesc, example: "", id: "", - multiline: false, + multiline: true, name: tmpitem, options: null, required: false, @@ -1507,6 +1508,28 @@ const ParsedAction = (props) => { if (data !== undefined && data !== null && data.value !== undefined && data.value !== null && data.value.length > 0) { baseHelperText = calculateHelpertext(data.value) } + + + var tmpitem = data.name.valueOf(); + if (data.name.startsWith("${") && data.name.endsWith("}")) { + tmpitem = tmpitem.slice(2, data.name.length - 1); + } + + if (tmpitem === "from_shuffle") { + tmpitem = "from" + } + + tmpitem = ( + tmpitem.charAt(0).toUpperCase() + tmpitem.substring(1) + ).replaceAll("_", " "); + + if (tmpitem === "Username basic") { + tmpitem = "Username" + } else if (tmpitem === "Password basic") { + tmpitem = "Password" + } + + multiline = data.name.startsWith("${") && data.name.endsWith("}") ? true : multiline var datafield = ( { ), }} - multiline={multiline} + multiline={data.name.startsWith("${") && data.name.endsWith("}") ? true : multiline} helperText={returnHelperText(data.name, data.value)} onClick={() => { console.log("Clicked field: ", clickedFieldId, data.name) @@ -1597,7 +1620,7 @@ const ParsedAction = (props) => { } }} id={clickedFieldId} - rows={rows} + rows={data.name.startsWith("${") && data.name.endsWith("}") ? 2 : rows} color="primary" defaultValue={data.value} //value={data.value} @@ -1631,13 +1654,8 @@ const ParsedAction = (props) => { > {openApiHelperText} - ) : data.name.startsWith("${") && data.name.endsWith("}") ? ( - - OpenAPI helperfield - - ) : null + ) : data.name.startsWith("${") && data.name.endsWith("}") ? + null : null } onBlur={(event) => { baseHelperText = calculateHelpertext(event.target.value) @@ -2173,26 +2191,6 @@ const ParsedAction = (props) => { ); }; - - var tmpitem = data.name.valueOf(); - if (data.name.startsWith("${") && data.name.endsWith("}")) { - tmpitem = tmpitem.slice(2, data.name.length - 1); - } - - if (tmpitem === "from_shuffle") { - tmpitem = "from" - } - - tmpitem = ( - tmpitem.charAt(0).toUpperCase() + tmpitem.substring(1) - ).replaceAll("_", " "); - - if (tmpitem === "Username basic") { - tmpitem = "Username" - } else if (tmpitem === "Password basic") { - tmpitem = "Password" - } - const description = data.description === undefined ? "" : data.description; @@ -2535,7 +2533,7 @@ const ParsedAction = (props) => { > @@ -2566,6 +2564,7 @@ const ParsedAction = (props) => { + {/* { > + + */} + { + }} + > + + + + +
diff --git a/frontend/src/components/Searchfield.js b/frontend/src/components/Searchfield.js index 24867a35..f145cbbb 100644 --- a/frontend/src/components/Searchfield.js +++ b/frontend/src/components/Searchfield.js @@ -37,7 +37,8 @@ const chipStyle = { const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240") const SearchField = props => { - const { serverside, } = props + const { serverside, userdata } = props + const theme = useTheme(); let navigate = useNavigate(); const borderRadius = 3 @@ -227,6 +228,7 @@ const SearchField = props => { timestamp: timestamp, queryID: hit.__queryID, positions: [hit.__position], + userToken: userdata === undefined || userdata === null || userdata.id === undefined ? "unauthenticated" : userdata.id, } ]) diff --git a/frontend/src/components/ShuffleCodeEditor.jsx b/frontend/src/components/ShuffleCodeEditor.jsx index 38469353..0c3ccdb5 100644 --- a/frontend/src/components/ShuffleCodeEditor.jsx +++ b/frontend/src/components/ShuffleCodeEditor.jsx @@ -43,6 +43,7 @@ const liquidFilters = [ {"name": "Size", "value": "size", "example": ""}, {"name": "Date", "value": `date: "%Y%M%d"`, "example": `{{ "now" | date: "%s" }}`}, {"name": "Escape String", "value": `{{ \"\"\"'string with weird'" quotes\"\"\" | escape_string }}`, "example": ``}, + {"name": "Flatten", "value": `flatten`, "example": `{{ [1, [1, 2], [2, 3, 4]] | flatten }}`}, ] const mathFilters = [ diff --git a/frontend/src/components/Workflowsearch.jsx b/frontend/src/components/Workflowsearch.jsx index e69de29b..3c26db69 100644 --- a/frontend/src/components/Workflowsearch.jsx +++ b/frontend/src/components/Workflowsearch.jsx @@ -0,0 +1,211 @@ +import React, { useState, useEffect } from 'react'; + +import ReactGA from 'react-ga'; +import { useTheme } from '@material-ui/core/styles'; +import {Link} from 'react-router-dom'; + +import { Search as SearchIcon, CloudQueue as CloudQueueIcon, Code as CodeIcon } from '@material-ui/icons'; + +//import algoliasearch from 'algoliasearch/lite'; +import algoliasearch from 'algoliasearch'; +import { InstantSearch, connectSearchBox, connectHits } from 'react-instantsearch-dom'; +import { Grid, Paper, TextField, ButtonBase, InputAdornment, Typography, Button, Tooltip} from '@material-ui/core'; + +const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240") +const WorkflowSearch = props => { + const { maxRows, showName, showSuggestion, isMobile, globalUrl, parsedXs, newSelectedApp, setNewSelectedApp, defaultSearch, showSearch, ConfiguredHits } = props + const rowHandler = maxRows === undefined || maxRows === null ? 50 : maxRows + const xs = parsedXs === undefined || parsedXs === null ? 12 : parsedXs + const theme = useTheme(); + //const [apps, setApps] = React.useState([]); + //const [filteredApps, setFilteredApps] = React.useState([]); + const [formMail, setFormMail] = React.useState(""); + const [message, setMessage] = React.useState(""); + const [formMessage, setFormMessage] = React.useState(""); + const [selectedApp, setSelectedApp] = React.useState({}); + + const buttonStyle = {borderRadius: 30, height: 50, width: 220, margin: isMobile ? "15px auto 15px auto" : 20, fontSize: 18,} + + const innerColor = "rgba(255,255,255,0.65)" + const borderRadius = 3 + window.title = "Shuffle | Apps | Find and integration any app" + + const submitContact = (email, message) => { + const data = { + "firstname": "", + "lastname": "", + "title": "", + "companyname": "", + "email": email, + "phone": "", + "message": message, + } + + const errorMessage = "Something went wrong. Please contact frikky@shuffler.io directly." + + fetch(globalUrl+"/api/v1/contact", { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(data), + }) + .then(response => response.json()) + .then(response => { + if (response.success === true) { + setFormMessage(response.reason) + //alert.info("Thanks for submitting!") + } else { + setFormMessage(errorMessage) + } + + setFormMail("") + setMessage("") + }) + .catch(error => { + setFormMessage(errorMessage) + console.log(error) + }); + } + + // value={currentRefinement} + const SearchBox = ({currentRefinement, refine, isSearchStalled} ) => { + useEffect(() => { + //console.log("FIRST LOAD ONLY? RUN REFINEMENT: !", currentRefinement) + if (defaultSearch !== undefined && defaultSearch !== null) { + refine(defaultSearch) + } + }, []) + + return ( +
+ + + + ), + }} + autoComplete='on' + type="search" + color="primary" + defaultValue={defaultSearch} + placeholder={`Find ${defaultSearch} Apps...`} + id="shuffle_workflow_search_field" + onChange={(event) => { + refine(event.currentTarget.value) + }} + limit={5} + /> + {/*isSearchStalled ? 'My search is stalled' : ''*/} + + ) + //value={currentRefinement} + } + + const Hits = ({ hits }) => { + const [mouseHoverIndex, setMouseHoverIndex] = useState(-1) + var counted = 0 + + return ( + + {hits.map((data, index) => { + const paperStyle = { + backgroundColor: index === mouseHoverIndex ? "rgba(255,255,255,0.8)" : theme.palette.inputColor, + color: index === mouseHoverIndex ? theme.palette.inputColor : "rgba(255,255,255,0.8)", + border: newSelectedApp.objectID !== data.objectID ? `1px solid rgba(255,255,255,0.2)` : "2px solid #f86a3e", + textAlign: "left", + padding: 10, + cursor: "pointer", + position: "relative", + overflow: "hidden", + width: "100%", + } + + if (counted === 12/xs*rowHandler) { + return null + } + + counted += 1 + var parsedname = "" + for (var key = 0; key < data.name.length; key++) { + var character = data.name.charAt(key) + if (character === character.toUpperCase()) { + //console.log(data.name[key], data.name[key+1]) + if (data.name.charAt(key+1) !== undefined && data.name.charAt(key+1) === data.name.charAt(key+1).toUpperCase()) { + } else { + parsedname += " " + } + } + + parsedname += character + } + + parsedname = (parsedname.charAt(0).toUpperCase()+parsedname.substring(1)).replaceAll("_", " ") + + return ( + { + setMouseHoverIndex(index) + /* + ReactGA.event({ + category: "app_grid_view", + action: `search_bar_click`, + label: "", + }) + */ + }} onMouseOut={() => { + setMouseHoverIndex(-1) + }} onClick={() => { + setNewSelectedApp(data) + //if (data.objectID !== data.objectID) { + //} + + //ReactGA.event({ + // category: "app_search", + // action: `app_${parsedname}_${data.id}_click`, + // label: "", + //}) + }}> +
+ {/*{data.name}*/} + + {parsedname} + +
+
+ ) + })} +
+ ) + } + + const InputHits = ConfiguredHits === undefined ? Hits : ConfiguredHits + const CustomSearchBox = connectSearchBox(SearchBox) + const CustomHits = connectHits(InputHits) + + return ( +
+ + {/* showSearch === false ? null : +
+ +
+ */} +
+ +
+ +
+
+ ) +} + +export default WorkflowSearch; diff --git a/frontend/src/theme.js b/frontend/src/theme.js index 73d23933..ad6ca44e 100644 --- a/frontend/src/theme.js +++ b/frontend/src/theme.js @@ -15,6 +15,7 @@ const theme = createMuiTheme({ type: "dark", surfaceColor: "#27292d", inputColor: "#383B40", + platformColor: "#1F2023", borderRadius: 5, defaultBorder: "1px solid rgba(255,255,255,0.3)", jsonTheme: "brewer", diff --git a/frontend/src/views/AngularWorkflow.jsx b/frontend/src/views/AngularWorkflow.jsx index 723c1390..fc160e5e 100644 --- a/frontend/src/views/AngularWorkflow.jsx +++ b/frontend/src/views/AngularWorkflow.jsx @@ -6080,10 +6080,8 @@ const AngularWorkflow = (defaultprops) => { // Simmple action swap autocompleter if (selectedAction.parameters !== undefined && newSelectedAction.parameters !== undefined && selectedAction.id === newSelectedAction.id) { - console.log("IN ACTION SWAPP") for (var paramkey in selectedAction.parameters) { const param = selectedAction.parameters[paramkey]; - console.log("PARAM: ", param.name, param.value) if (param.value === null || param.value === undefined || param.value.length === 0) { continue @@ -6095,7 +6093,7 @@ const AngularWorkflow = (defaultprops) => { } if (param.name === "headers") { - console.log("Swap header?") + console.log("Swap header? For now, yes") //newSelectedAction.parameters[newParamIndex].value = param.value } @@ -6105,7 +6103,6 @@ const AngularWorkflow = (defaultprops) => { if (newParamIndex < 0) { continue } - console.log("xisting value: ", newSelectedAction.parameters[newParamIndex].value) newSelectedAction.parameters[newParamIndex].value = param.value newSelectedAction.parameters[newParamIndex].autocompleted = true @@ -10853,7 +10850,7 @@ const AngularWorkflow = (defaultprops) => { objectIDs: [workflow.id], timestamp: timestamp, queryID: queryID, - userToken: userdata === undefined || userdata === null || userdata.id === undefined ? "" : userdata.id, + userToken: userdata === undefined || userdata === null || userdata.id === undefined ? "unauthenticated" : userdata.id, } ]) } else { diff --git a/frontend/src/views/AppCreator.jsx b/frontend/src/views/AppCreator.jsx index 127f719a..c2fe3564 100644 --- a/frontend/src/views/AppCreator.jsx +++ b/frontend/src/views/AppCreator.jsx @@ -1660,7 +1660,7 @@ const AppCreator = (defaultprops) => { data.info["contact"] = basedata.info.contact; } else if (contact === "") { data.info["contact"] = { - name: "@shuffle_platform", + name: "@Anonymous Shuffle User", url: "https://twitter.com/shuffleio", email: "support@shuffler.io", }; diff --git a/frontend/src/views/Search.jsx b/frontend/src/views/Search.jsx index 8ee8a186..da2e3bb5 100644 --- a/frontend/src/views/Search.jsx +++ b/frontend/src/views/Search.jsx @@ -146,16 +146,16 @@ const Search = (props) => { /> {curTab === 0 ? - + : curTab === 1 ? - + : curTab === 2 ? - + : curTab === 3 ? - + : null}
diff --git a/functions/onprem/orborus/build.sh b/functions/onprem/orborus/build.sh index 3256a1ed..aede53b4 100644 --- a/functions/onprem/orborus/build.sh +++ b/functions/onprem/orborus/build.sh @@ -1,5 +1,5 @@ NAME=shuffle-orborus -VERSION=1.0.1 +VERSION=1.0.5 echo "Running docker build with $NAME:$VERSION" #docker rmi frikky/shuffle:$NAME --force diff --git a/functions/onprem/orborus/go.mod b/functions/onprem/orborus/go.mod index 3d8716d3..b1766e3d 100644 --- a/functions/onprem/orborus/go.mod +++ b/functions/onprem/orborus/go.mod @@ -8,5 +8,5 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/mackerelio/go-osstat v0.2.1 github.com/satori/go.uuid v1.2.0 - github.com/shuffle/shuffle-shared v0.2.41 + github.com/shuffle/shuffle-shared v0.2.64 ) diff --git a/functions/onprem/orborus/go.sum b/functions/onprem/orborus/go.sum index 282522ce..73452a10 100644 --- a/functions/onprem/orborus/go.sum +++ b/functions/onprem/orborus/go.sum @@ -788,6 +788,10 @@ github.com/shuffle/shuffle-shared v0.2.27 h1:YT9MtXyMSxIGMpNovjp9pCKFyt2gk40EdAX github.com/shuffle/shuffle-shared v0.2.27/go.mod h1:YuMle0RjwXb3hxR5PdaOOD9e+hUyK34OABS0UbrT/Sk= github.com/shuffle/shuffle-shared v0.2.41 h1:1TBP/47Xzh7ysi6I++wJxRxKpZYp7NBe7YF1DrFL2mA= github.com/shuffle/shuffle-shared v0.2.41/go.mod h1:YuMle0RjwXb3hxR5PdaOOD9e+hUyK34OABS0UbrT/Sk= +github.com/shuffle/shuffle-shared v0.2.63 h1:IF82o5WS4+6wEIirqAd1qEm/pBCuQMbn2CJeuAt2qFI= +github.com/shuffle/shuffle-shared v0.2.63/go.mod h1:YuMle0RjwXb3hxR5PdaOOD9e+hUyK34OABS0UbrT/Sk= +github.com/shuffle/shuffle-shared v0.2.64 h1:WpCKiL5tNt7wTJaHkf1zXhjeUB5ltFap1dXgU6ijKq4= +github.com/shuffle/shuffle-shared v0.2.64/go.mod h1:YuMle0RjwXb3hxR5PdaOOD9e+hUyK34OABS0UbrT/Sk= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= diff --git a/functions/onprem/orborus/orborus.go b/functions/onprem/orborus/orborus.go index 9b2468b5..c0e8bf03 100644 --- a/functions/onprem/orborus/orborus.go +++ b/functions/onprem/orborus/orborus.go @@ -285,31 +285,31 @@ func deployServiceWorkers(image string) { if len(os.Getenv("DOCKER_HOST")) > 0 { log.Printf("[DEBUG] Deploying docker socket proxy to the network %s as the DOCKER_HOST variable is set", networkName) + //if err == nil { + containers, err := dockercli.ContainerList(ctx, types.ContainerListOptions{ + All: true, + }) + if err == nil { - containers, err := dockercli.ContainerList(ctx, types.ContainerListOptions{ - All: true, - }) - - if err == nil { - for _, container := range containers { - if strings.Contains(strings.ToLower(container.Image), "docker-socket-proxy") { - networkConfig := &network.EndpointSettings{} - err := dockercli.NetworkConnect(ctx, networkName, container.ID, networkConfig) - if err != nil { - log.Printf("[ERROR] Failed connecting Docker socket proxy to docker network %s: %s", networkName, err) - } else { - log.Printf("[INFO] Attached the docker socket proxy to the execution network") - } - - break + for _, container := range containers { + if strings.Contains(strings.ToLower(container.Image), "docker-socket-proxy") { + networkConfig := &network.EndpointSettings{} + err := dockercli.NetworkConnect(ctx, networkName, container.ID, networkConfig) + if err != nil { + log.Printf("[ERROR] Failed connecting Docker socket proxy to docker network %s: %s", networkName, err) + } else { + log.Printf("[INFO] Attached the docker socket proxy to the execution network") } + + break } - } else { - log.Printf("[WARNING] Failed listing containers when deploying socket proxy on swarm: %s", err) } } else { - log.Printf("[WARNING] Failed listing and finding the right image for docker socket proxy: %s", err) + log.Printf("[ERROR] Failed listing containers when deploying socket proxy on swarm: %s", err) } + //} else { + // log.Printf("[ERROR] Failed listing and finding the right image for docker socket proxy: %s", err) + //} } //serviceOptions := types.ServiceCreateOptions{} @@ -689,7 +689,7 @@ func initializeImages() { ctx := context.Background() if appSdkVersion == "" { - appSdkVersion = "0.8.97" + appSdkVersion = "1.0.0" log.Printf("[WARNING] SHUFFLE_APP_SDK_VERSION not defined. Defaulting to %s", appSdkVersion) }