Bunch of fixes for new welcome pages and search fields

This commit is contained in:
frikky
2022-07-21 00:30:17 +02:00
parent ccc4b3f939
commit 66d7cd4e80
19 changed files with 590 additions and 102 deletions
+12
View File
@@ -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())
+33 -29
View File
@@ -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
+2 -1
View File
@@ -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,
}
])
+211
View File
@@ -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 (
<form noValidate action="" role="search">
<TextField
fullWidth
style={{backgroundColor: theme.palette.inputColor, borderRadius: borderRadius, width: "100%",}}
InputProps={{
style:{
color: "white",
fontSize: "1em",
height: 50,
},
startAdornment: (
<InputAdornment position="start">
<SearchIcon style={{marginLeft: 5}}/>
</InputAdornment>
),
}}
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' : ''*/}
</form>
)
//value={currentRefinement}
}
const Hits = ({ hits }) => {
const [mouseHoverIndex, setMouseHoverIndex] = useState(-1)
var counted = 0
return (
<Grid container spacing={0} style={{border: "1px solid rgba(255,255,255,0.2)", maxHeight: 250, minHeight: 250, overflowY: "auto", overflowX: "hidden",}}>
{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 (
<Paper key={index} elevation={0} style={paperStyle} onMouseOver={() => {
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: "",
//})
}}>
<div style={{display: "flex"}}>
<img alt={data.name} src={data.image_url} style={{width: "100%", maxWidth: 30, minWidth: 30, minHeight: 30, maxHeight: 30, display: "block", }} />
<Typography variant="body1" style={{marginTop: 2, marginLeft: 10, }}>
{parsedname}
</Typography>
</div>
</Paper>
)
})}
</Grid>
)
}
const InputHits = ConfiguredHits === undefined ? Hits : ConfiguredHits
const CustomSearchBox = connectSearchBox(SearchBox)
const CustomHits = connectHits(InputHits)
return (
<div style={{width: "100%", textAlign: "center", position: "relative", height: "100%",}}>
<InstantSearch searchClient={searchClient} indexName="appsearch">
{/* showSearch === false ? null :
<div style={{maxWidth: 450, margin: "auto", }}>
<CustomSearchBox />
</div>
*/}
<div style={{maxWidth: 450, margin: "auto", }}>
<CustomSearchBox />
</div>
<CustomHits hitsPerPage={5}/>
</InstantSearch>
</div>
)
}
export default WorkflowSearch;
+27 -5
View File
@@ -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 (
<Paper style={{marginBottom: 15, width: 250, maxHeight: 400, overflow: "hidden", zIndex: 12500, padding: 15, backgroundColor: bgColor, border: "1px solid rgba(255,255,255,0.2)", }} onMouseOver={handleHover} onMouseOut={handleHoverOut}>
@@ -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 (
<div style={{margin: "auto", backgroundColor: theme.palette.surfaceColor, position: "relative", }}>
<div style={{margin: "auto", backgroundColor: bgColor, position: "relative", }}>
{showOptions === false ? null :
<div style={{textAlign: "center",}}>
{Object.keys(usecases).map((data, index) => {
@@ -1568,7 +1590,7 @@ const Framework = (props) => {
{discoveryData.description}
</Typography>
{/*isCloud && defaultSearch !== undefined && defaultSearch.length > 0 ?
{<WorkflowSearch
{<
newSelectedApp={newSelectedApp}
setNewSelectedApp={setNewSelectedApp}
defaultSearch={defaultSearch}
@@ -1601,7 +1623,7 @@ const Framework = (props) => {
</div>
<div style={{marginTop: 10}}>
{selectionOpen ?
<WorkflowSearch
<AppSearch
defaultSearch={defaultSearch}
newSelectedApp={newSelectedApp}
setNewSelectedApp={setNewSelectedApp}
+2 -1
View File
@@ -30,7 +30,7 @@ import {Close as CloseIcon, Folder as FolderIcon, Polymer as PolymerIcon, Librar
const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240")
const DocsGrid = props => {
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,
}
])
+2 -2
View File
@@ -523,7 +523,7 @@ const Header = (props) => {
{!isLoaded ? null :
userdata.chat_disabled === true ? null :
<div style={{flex: 1, marginTop: 5,}}>
<SearchField serverside={false} />
<SearchField serverside={false} userdata={userdata} />
</div>
}
<div style={{ flex: 1, display: "flex", flexDirection: "row-reverse" }}>
@@ -629,7 +629,7 @@ const Header = (props) => {
{!isLoaded ? null :
userdata.chat_disabled === true ? null :
<div style={{flex: 1, marginTop: 5,}}>
<SearchField serverside={false} />
<SearchField serverside={false} userdata={userdata} />
</div>
}
<div
+52 -31
View File
@@ -1318,6 +1318,7 @@ const ParsedAction = (props) => {
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 = (
<TextField
@@ -1564,7 +1587,7 @@ const ParsedAction = (props) => {
</InputAdornment>
),
}}
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}
</span>
) : data.name.startsWith("${") && data.name.endsWith("}") ? (
<span
style={{ color: "white", marginBottom: 5, marginLeft: 5 }}
>
OpenAPI helperfield
</span>
) : null
) : data.name.startsWith("${") && data.name.endsWith("}") ?
null : null
}
onBlur={(event) => {
baseHelperText = calculateHelpertext(event.target.value)
@@ -2173,26 +2191,6 @@ const ParsedAction = (props) => {
</Menu>
);
};
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) => {
>
<Tooltip
color="primary"
title="Read app docs"
title="Find app documentation"
placement="top"
>
<DescriptionIcon style={{ color: "rgba(255,255,255,0.7)" }} />
@@ -2566,6 +2564,7 @@ const ParsedAction = (props) => {
</Tooltip>
</a>
</IconButton>
{/*
<IconButton
style={{
marginTop: "auto",
@@ -2599,6 +2598,28 @@ const ParsedAction = (props) => {
>
<AutoFixHighIcon style={{ color: selectedAction.run_magic_output === undefined || selectedAction.run_magic_output === null || selectedAction.run_magic_output === false ? "rgba(255,255,255,0.7)" : "#f86a3e"}} />
</Tooltip>
</IconButton>
*/}
<IconButton
style={{
marginTop: "auto",
marginBottom: "auto",
height: 30,
marginLeft: 15,
paddingRight: 0,
}}
onClick={() => {
}}
>
<Tooltip
color="primary"
title={"Find related workflows"}
placement="top"
>
<a href={`https://shuffler.io/search?tab=workflows&q=${selectedAction.app_name}`} target="_blank">
<SearchIcon style={{ color: "rgba(255,255,255,0.7)"}} />
</a>
</Tooltip>
</IconButton>
</div>
+3 -1
View File
@@ -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,
}
])
@@ -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 = [
+211
View File
@@ -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 (
<form noValidate action="" role="search">
<TextField
fullWidth
style={{backgroundColor: theme.palette.inputColor, borderRadius: borderRadius, width: "100%",}}
InputProps={{
style:{
color: "white",
fontSize: "1em",
height: 50,
},
startAdornment: (
<InputAdornment position="start">
<SearchIcon style={{marginLeft: 5}}/>
</InputAdornment>
),
}}
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' : ''*/}
</form>
)
//value={currentRefinement}
}
const Hits = ({ hits }) => {
const [mouseHoverIndex, setMouseHoverIndex] = useState(-1)
var counted = 0
return (
<Grid container spacing={0} style={{border: "1px solid rgba(255,255,255,0.2)", maxHeight: 250, minHeight: 250, overflowY: "auto", overflowX: "hidden",}}>
{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 (
<Paper key={index} elevation={0} style={paperStyle} onMouseOver={() => {
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: "",
//})
}}>
<div style={{display: "flex"}}>
{/*<img alt={data.name} src={data.image_url} style={{width: "100%", maxWidth: 30, minWidth: 30, minHeight: 30, maxHeight: 30, display: "block", }} />*/}
<Typography variant="body1" style={{marginTop: 2, marginLeft: 10, }}>
{parsedname}
</Typography>
</div>
</Paper>
)
})}
</Grid>
)
}
const InputHits = ConfiguredHits === undefined ? Hits : ConfiguredHits
const CustomSearchBox = connectSearchBox(SearchBox)
const CustomHits = connectHits(InputHits)
return (
<div style={{width: "100%", textAlign: "center", position: "relative", height: "100%",}}>
<InstantSearch searchClient={searchClient} indexName="workflows">
{/* showSearch === false ? null :
<div style={{maxWidth: 450, margin: "auto", }}>
<CustomSearchBox />
</div>
*/}
<div style={{maxWidth: 450, margin: "auto", }}>
<CustomSearchBox />
</div>
<CustomHits hitsPerPage={5}/>
</InstantSearch>
</div>
)
}
export default WorkflowSearch;
+1
View File
@@ -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",
+2 -5
View File
@@ -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 {
+1 -1
View File
@@ -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",
};
+4 -4
View File
@@ -146,16 +146,16 @@ const Search = (props) => {
/>
</Tabs>
{curTab === 0 ?
<AppGrid maxRows={3} showSuggestion={true} globalUrl={globalUrl} isMobile={isMobile} />
<AppGrid maxRows={3} showSuggestion={true} globalUrl={globalUrl} isMobile={isMobile} userdata={userdata} />
:
curTab === 1 ?
<WorkflowGrid maxRows={3} showSuggestion={true} globalUrl={globalUrl} isMobile={isMobile} />
<WorkflowGrid maxRows={3} showSuggestion={true} globalUrl={globalUrl} isMobile={isMobile} userdata={userdata} />
:
curTab === 2 ?
<DocsGrid maxRows={3} showSuggestion={true} globalUrl={globalUrl} isMobile={isMobile} />
<DocsGrid maxRows={3} showSuggestion={true} globalUrl={globalUrl} isMobile={isMobile} userdata={userdata} />
:
curTab === 3 ?
<CreatorGrid maxRows={3} showSuggestion={true} globalUrl={globalUrl} isMobile={isMobile} />
<CreatorGrid maxRows={3} showSuggestion={true} globalUrl={globalUrl} isMobile={isMobile} userdata={userdata} />
:
null}
</div>
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
)
+4
View File
@@ -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=
+20 -20
View File
@@ -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)
}