Added further admin panel fixes

This commit is contained in:
Frikky
2023-09-27 21:25:45 +02:00
parent 29e8106670
commit 787ca47add
12 changed files with 474 additions and 154 deletions
+15 -9
View File
@@ -1,11 +1,12 @@
import os
import ast
import copy
import sys
import re
import copy
import time
import base64
import json
import random
import liquid
import logging
import urllib3
@@ -504,10 +505,12 @@ class AppBase:
except Exception as e:
print(f"[WARNING] Failed adding parameter for logs: {e}")
# FIXME: Adding retries here.
try:
finished = False
for i in range (0, 10):
# Random sleeptime between 0 and 1 second, with 0.1 increments
sleeptime = float(random.randint(0, 10) / 10)
try:
ret = requests.post(url, headers=headers, json=action_result, timeout=10, verify=False)
@@ -516,29 +519,29 @@ class AppBase:
finished = True
break
else:
self.logger.info(f"[ERROR] RESP: {ret.text}")
self.logger.info(f"[ERROR] Bad resp {ret.status_code}: {ret.text}")
except requests.exceptions.RequestException as e:
self.logger.info(f"[DEBUG] Request problem: {e}")
time.sleep(0.1)
time.sleep(sleeptime)
#time.sleep(5)
continue
except TimeoutError as e:
self.logger.info(f"[DEBUG] Timeout or request: {e}")
time.sleep(0.1)
time.sleep(sleeptime)
#time.sleep(5)
continue
except requests.exceptions.ConnectionError as e:
self.logger.info(f"[DEBUG] Connectionerror: {e}")
time.sleep(0.1)
time.sleep(sleeptime)
#time.sleep(5)
continue
except http.client.RemoteDisconnected as e:
self.logger.info(f"[DEBUG] Remote: {e}")
time.sleep(0.1)
time.sleep(sleeptime)
#time.sleep(5)
continue
@@ -555,8 +558,11 @@ class AppBase:
# Not sure why this would work tho :)
action_result["status"] = "FAILURE"
action_result["result"] = json.dumps({"success": False, "reason": "POST error: Failed connecting to %s over 10 retries to the backend" % url})
self.logger.info(f"[DEBUG] Before typeerror stream result - NOT finished after 10 requests")
ret = requests.post("%s%s" % (self.base_url, stream_path), headers=headers, json=action_result, verify=False)
self.logger.info(f"[ERROR] Before typeerror stream result - NOT finished after 10 requests")
#ret = requests.post("%s%s" % (self.base_url, stream_path), headers=headers, json=action_result, verify=False)
self.send_result(action_result, {"Content-Type": "application/json", "Authorization": "Bearer %s" % self.authorization}, "/api/v1/streams")
return
self.logger.info(f"""[DEBUG] Successful request result request: Status= {ret.status_code} & Response= {ret.text}. Action status: {action_result["status"]}""")
except requests.exceptions.ConnectionError as e:
+2 -2
View File
@@ -1,6 +1,6 @@
module shuffle-shared
replace github.com/shuffle/shuffle-shared => ../../../../git/shuffle-shared
//replace github.com/shuffle/shuffle-shared => ../../../../git/shuffle-shared
go 1.19
@@ -19,7 +19,7 @@ require (
github.com/gorilla/mux v1.8.0
github.com/h2non/filetype v1.1.3
github.com/satori/go.uuid v1.2.0
github.com/shuffle/shuffle-shared v0.4.41
github.com/shuffle/shuffle-shared v0.4.47
golang.org/x/crypto v0.9.0
google.golang.org/api v0.125.0
google.golang.org/appengine v1.6.7
+2 -47
View File
@@ -22,10 +22,9 @@ import {
import aa from 'search-insights'
const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240")
const Appsearch = props => {
const { maxRows, showName, showSuggestion, isMobile, globalUrl, parsedXs, newSelectedApp, setNewSelectedApp, defaultSearch, showSearch, ConfiguredHits, userdata, cy, isCreatorPage, actionImageList, setActionImageList} = props
const { maxRows, showName, showSuggestion, isMobile, globalUrl, parsedXs, newSelectedApp, setNewSelectedApp, defaultSearch, showSearch, ConfiguredHits, userdata, cy, isCreatorPage, actionImageList, setActionImageList, setUserSpecialzedApp } = props
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
//const alert = useAlert();
const rowHandler = maxRows === undefined || maxRows === null ? 50 : maxRows
const xs = parsedXs === undefined || parsedXs === null ? 12 : parsedXs
//const theme = useTheme();
@@ -41,45 +40,6 @@ const Appsearch = props => {
const borderRadius = 3
window.title = "Shuffle | Apps | Find and integration any app"
const setUserSpecialzedApp = (user, data) => {
// var data = newfields]
console.log("data value", data)
const appData = {"user_id":user,"specialized_apps":[{}]}
console.log("User Check for appdata:", user)
appData["specialized_apps"][0]["name"] = data["name"]
appData["specialized_apps"][0]["image"] = data["image_url"]
appData["specialized_apps"][0]["category"] = data["categories"].toString()
console.log("AppData:",appData)
console.log("setActionImageList",setActionImageList)
console.log("actionImageList",actionImageList)
const finalData = actionImageList.concat(appData["specialized_apps"])
appData["specialized_apps"]=finalData
fetch(globalUrl + "/api/v1/users/updateuser", {
method: "PUT",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(appData),
credentials: "include",
})
.then((response) => {
if (response.status !== 200) {
console.log("Status not 200 for set creator :O!");
}
toast("Sucessfully updated specialzed app.")
return response.json();
})
.then((responseJson) => {
if (!responseJson.success && responseJson.reason !== undefined) {
toast("Failed updating user: " + responseJson.reason);
}
})
.catch((error) => {
console.log(error);
});
};
// value={currentRefinement}
const SearchBox = ({currentRefinement, refine, isSearchStalled} ) => {
@@ -180,13 +140,8 @@ const Appsearch = props => {
setMouseHoverIndex(-1)
}} onClick={() => {
if(isCreatorPage === true){
console.log("data:",data)
console.log("userdata.id",userdata.id)
console.log("is creator", isCreatorPage)
if (setNewSelectedApp !== undefined) {
// setUserSpecialzedApp = data
if (setNewSelectedApp !== undefined && setUserSpecialzedApp !== undefined) {
setUserSpecialzedApp(userdata.id, data)
//setActionImageList(userdata.id, data)
}
}
if (setNewSelectedApp !== undefined) {
+105 -21
View File
@@ -1,6 +1,7 @@
import React, { useState, useEffect } from "react";
import ReactGA from 'react-ga4';
import theme from "../theme.jsx";
import { ToastContainer, toast } from "react-toastify"
import {
Paper,
@@ -14,22 +15,87 @@ import {
//import { useAlert
const Branding = (props) => {
const { globalUrl, userdata, serverside, billingInfo, stripeKey, selectedOrganization, handleGetOrg, } = props;
//const alert = useAlert();
const [publishingInfo, setPublishingInfo] = useState("");
const { globalUrl, userdata, serverside, billingInfo, stripeKey, selectedOrganization, handleGetOrg, } = props;
//const alert = useAlert();
const [publishingInfo, setPublishingInfo] = useState("");
const [publishRequirements, setPublishRequirements] = useState([])
// Should enable / disable org branding
const handleChangePublishing = () => {
console.log("Handle change publishing");
}
const handleEditOrg = (joinStatus) => {
const data = {
"org_id": selectedOrganization.id,
"creator_config": joinStatus,
};
const url = globalUrl + `/api/v1/orgs/${selectedOrganization.id}`;
fetch(url, {
mode: "cors",
method: "POST",
body: JSON.stringify(data),
credentials: "include",
crossDomain: true,
withCredentials: true,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
})
.then((response) =>
response.json().then((responseJson) => {
if (responseJson["success"] === false) {
toast("Failed updating org: ", responseJson.reason);
} else {
if (joinStatus == "join") {
setPublishingInfo("Your organization is now part of the Creator Incentive Program. You can now create and publish content to your organization's page. You can also create a creator account to manage your organization's content.")
} else {
setPublishingInfo("Your organization is no longer part of the Creator Incentive Program. You can still create a creator account to manage your organization's content.")
}
handleGetOrg(selectedOrganization.id);
}
})
)
.catch((error) => {
toast("Err: " + error.toString());
});
};
// Should enable / disable org branding
const handleChangePublishing = () => {
console.log("Handle change publishing");
if (selectedOrganization.creator_id == "") {
handleEditOrg("join")
} else {
handleEditOrg("leave")
}
}
const isOrganizationReady = () => {
console.log("Is organization ready?")
// A simple checklist to ensure the button shows up properly
if (selectedOrganization.name === selectedOrganization.org) {
const comment = "Change the name of your organization"
if (!publishRequirements.includes(comment)) {
setPublishRequirements([...publishRequirements, comment])
}
return false;
}
// Check if it's a suborg
if (selectedOrganization.creator_org !== "") {
const comment = "Child orgs can't become creators"
if (!publishRequirements.includes(comment)) {
setPublishRequirements([...publishRequirements, comment])
}
return false;
}
if (selectedOrganization.large_image === "" || selectedOrganization.large_image === theme.palette.defaultImage) {
const comment = "Add a logo for your organization"
if (!publishRequirements.includes(comment)) {
setPublishRequirements([...publishRequirements, comment])
}
return false;
}
@@ -38,40 +104,58 @@ const Branding = (props) => {
return (
<div>
<Typography variant="h6" style={{ marginTop: 20, marginBottom: 10 }}>
Branding
</Typography>
<h2>
Branding
</h2>
<Typography variant="body1" color="textSecondary" style={{ marginTop: 20, marginBottom: 10 }}>
You can customize your organization's branding by uploading a logo, changing the color scheme and a lot more.
</Typography>
<Divider style={{marginTop: 50, marginBottom: 50, }} />
<h2>
Creator Network
Creator Incentive Program
</h2>
<div style={{ display: "flex", width: 700, }}>
<div style={{ display: "flex", width: 900, }}>
<div>
<span>
<Typography variant="body1" color="textSecondary">
By changing publishing settings, you agree to our <a href="/docs/terms_of_service" target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}}>Terms of Service</a>, and acknowledge that your organization's non-sensitive data will be turned into a <a target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}} href="https://shuffler.io/creators">creator account</a>. Support: support@shuffler.io
By changing publishing settings, you agree to our <a href="/docs/terms_of_service" target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}}>Terms of Service</a>, and acknowledge that your organization's non-sensitive data will be added as a <a target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}} href="https://shuffler.io/creators">creator account</a>. None of your existing workflows, apps, or other stored data will be published. Any admin in your organization can manage the creator configuration. Becoming a creator organization is reversible.<div/>Support: <a href="mailto:support@shuffler.io"target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}}>support@shuffler.io</a>
</Typography>
{selectedOrganization.creator_id == "" ?
<Typography variant="h6" color="textSecondary" style={{ marginTop: 20, marginBottom: 10, color: "grey", }}>
&nbsp;
</Typography>
:
<Typography variant="h6" color="textSecondary" style={{ marginTop: 20, marginBottom: 10, color: "grey", }}>
<a href={`/creators/${selectedOrganization.creator_id}`} target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}}>Modify your creator organization</a>
</Typography>
}
<Button
style={{ height: 40, marginTop: 10, width: 300, }}
variant="outlined"
color="primary"
disabled={() => {
return isOrganizationReady()
}}
variant={selectedOrganization.creator_id == "" ? "contained" : "outlined"}
color={selectedOrganization.creator_id == "" ? "primary" : "secondary"}
disabled={!isOrganizationReady()}
onClick={() => {
handleChangePublishing();
}}
>
Join Creator Network
{selectedOrganization.creator_id == "" ? "Join" : "Leave"} Creators
</Button>
<Typography variant="body1" color="textSecondary" style={{ marginTop: 20, marginBottom: 10 }}>
<Typography variant="body1" color="textSecondary" style={{ marginTop: 20, marginBottom: 10, color: "white", }}>
{publishingInfo}
</Typography>
<Typography variant="body1" color="textSecondary" style={{ marginTop: 20, marginBottom: 10, color: "grey", }}>
{publishRequirements.map((item) => {
return (
<div>
Required: {item}
</div>
)
})}
</Typography>
</span>
</div>
</div>
-1
View File
@@ -823,7 +823,6 @@ const { globalUrl, setNotifications, notifications, isLoggedIn, removeCookie, ho
color: "white",
height: 45,
width: 85,
zIndex: 14999,
}}
value={userdata.active_org.id}
+1 -1
View File
@@ -70,7 +70,7 @@ const Priority = (props) => {
return (
<div style={{border: priority.active === false ? "1px solid #000000" : priority.severity === 1 ? "1px solid #f85a3e" : "1px solid rgba(255,255,255,0.3)", borderRadius: theme.palette.borderRadius, marginTop: 10, marginBottom: 10, padding: 15, textAlign: "center", height: 95, textAlign: "left", backgroundColor: theme.palette.surfaceColor, display: "flex", }}>
<div style={{border: priority.active === false ? "1px solid #000000" : priority.severity === 1 ? "1px solid #f85a3e" : "1px solid rgba(255,255,255,0.3)", borderRadius: theme.palette.borderRadius, marginTop: 10, marginBottom: 10, padding: 15, textAlign: "center", minHeight: 70, maxHeight: 70, textAlign: "left", backgroundColor: theme.palette.surfaceColor, display: "flex", }}>
<div style={{flex: 2, overflow: "hidden",}}>
<span style={{display: "flex", }}>
{priority.type === "usecase" || priority.type == "apps" ? <AutoFixHighIcon style={{height: 19, width: 19, marginLeft: 3, marginRight: 10, }}/> : null}
+8 -9
View File
@@ -749,7 +749,7 @@ Let me know if you're interested, or set up a call here: https://drift.me/${user
image: image,
defaults: defaults,
sso_config: sso_config,
lead_info: lead_info,
lead_info: lead_info,
};
const url = globalUrl + `/api/v1/orgs/${selectedOrganization.id}`;
@@ -2371,7 +2371,7 @@ Let me know if you're interested, or set up a call here: https://drift.me/${user
*/}
{userdata.support === true ?
<span style={{display: "flex", top: -10, right: 50, position: "absolute"}}>
<span style={{display: "flex", top: -10, right: -50, position: "absolute"}}>
{/*<a href={mailsendingButton(selectedOrganization)} target="_blank" rel="noopener noreferrer" style={{textDecoration: "none"}} disabled={selectedStatus.length !== 0}>*/}
<Button
variant="outlined"
@@ -2468,8 +2468,8 @@ Let me know if you're interested, or set up a call here: https://drift.me/${user
setSelectedOrganization={setSelectedOrganization}
globalUrl={globalUrl}
selectedOrganization={selectedOrganization}
adminTab={adminTab}
handleEditOrg={handleEditOrg}
adminTab={adminTab}
handleEditOrg={handleEditOrg}
/>
) : (
<div
@@ -2517,13 +2517,13 @@ Let me know if you're interested, or set up a call here: https://drift.me/${user
<Tab
disabled={!isCloud}
label=<span>
Billing (Beta)
Billing
</span>
/>
<Tab
disabled={!isCloud || true}
disabled={!isCloud}
label=<span>
Branding
Branding (Beta)
</span>
/>
</Tabs>
@@ -2798,7 +2798,6 @@ Let me know if you're interested, or set up a call here: https://drift.me/${user
globalUrl={globalUrl}
handleGetOrg={handleGetOrg}
selectedOrganization={selectedOrganization}
selectedOrganization={selectedOrganization}
setSelectedOrganization={setSelectedOrganization}
/>
: null
@@ -2995,7 +2994,7 @@ Let me know if you're interested, or set up a call here: https://drift.me/${user
Add, edit, block or change passwords.{" "}
<a
target="_blank"
rel="noopener noreferrer"
rel="noopener noreferrer"
href="/docs/organizations#user_management"
style={{ textDecoration: "none", color: "#f85a3e" }}
>
+299 -29
View File
@@ -22,9 +22,11 @@ import {
Breadcrumbs,
CircularProgress,
Chip,
IconButton,
} from "@mui/material";
import {
Publish as PublishIcon,
LockOpen as LockOpenIcon,
FileCopy as FileCopyIcon,
Delete as DeleteIcon,
@@ -40,10 +42,11 @@ import {
ZoomOutOutlined as ZoomOutOutlinedIcon,
Loop as LoopIcon,
AddPhotoAlternate as AddPhotoAlternateIcon,
CallMerge as CallMergeIcon,
} from "@mui/icons-material";
import { v4 as uuidv4 } from "uuid";
import { Link, useParams } from "react-router-dom";
import { useNavigate, Link, useParams } from "react-router-dom";
import YAML from "yaml";
import { MuiChipsInput } from "mui-chips-input";
//import { useAlert
@@ -360,6 +363,8 @@ const AppCreator = (defaultprops) => {
props.match.params = params
var upload = "";
let navigate = useNavigate();
const increaseAmount = 50;
const actionNonBodyRequest = ["GET", "HEAD", "DELETE", "CONNECT"];
const actionBodyRequest = ["POST", "PUT", "PATCH"];
@@ -422,6 +427,109 @@ const AppCreator = (defaultprops) => {
// and make categories + labels modifyable.
// Categories are the main categories in the App Framework
const [categories, setCategories] = useState(appCategories)
const redirectOpenApi = () => {
navigate(`/apps/new?id=${appValidation}`)
}
const newUpload = React.useRef(null);
const [openApiError, setOpenApiError] = React.useState("");
const [validation, setValidation] = React.useState("");
const [appValidation, setAppValidation] = React.useState("");
const [openApi, setOpenApi] = React.useState("");
const [openApiData, setOpenApiData] = React.useState("");
const [openApiModal, setOpenApiModal] = React.useState(false);
useEffect(() => {
console.log("In useEffect for openApiData: ", openApiData)
}, [openApiData]);
const uploadFile = (e) => {
console.log("In uploadFile")
const isDropzone =
e.dataTransfer === undefined ? false : e.dataTransfer.files.length > 0;
const files = isDropzone ? e.dataTransfer.files : e.target.files;
const reader = new FileReader();
try {
reader.addEventListener("load", (e) => {
const content = e.target.result;
console.log("set openapi data! ", content)
setOpenApiData(content);
setOpenApiModal(true);
});
} catch (e) {
console.log("Error in dropzone: ", e);
}
try {
reader.readAsText(files[0]);
} catch (error) {
toast("Failed to read file");
}
}
const escapeApiData = (apidata) => {
//console.log(apidata)
try {
return JSON.stringify(JSON.parse(apidata));
} catch (error) {
console.log("JSON DECODE ERROR - TRY YAML");
}
try {
const parsed = YAML.parse(YAML.stringify(apidata));
//const parsed = YAML.parse(apidata))
return YAML.stringify(parsed);
} catch (error) {
console.log("YAML DECODE ERROR - TRY SOMETHING ELSE?: " + error);
setOpenApiError("Local error: " + error.toString());
}
return "";
}
const validateOpenApi = (openApidata) => {
var newApidata = escapeApiData(openApidata);
if (newApidata === "") {
// Used to return here
newApidata = openApidata;
return;
}
//console.log(newApidata)
setValidation(true);
fetch(globalUrl + "/api/v1/validate_openapi", {
method: "POST",
headers: {
Accept: "application/json",
},
body: openApidata,
credentials: "include",
})
.then((response) => {
setValidation(false);
return response.json();
})
.then((responseJson) => {
if (responseJson.success) {
setAppValidation(responseJson.id);
} else {
if (responseJson.reason !== undefined) {
setOpenApiError(responseJson.reason);
}
toast("An error occurred in the response");
}
})
.catch((error) => {
setValidation(false);
toast(error.toString());
setOpenApiError(error.toString());
});
};
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
@@ -2084,9 +2192,9 @@ const AppCreator = (defaultprops) => {
},
};
if (queryitem.example !== undefined) {
newitem.example = queryitem.example
}
if (queryitem.example !== undefined) {
newitem.example = queryitem.example
}
if (queryitem.description !== undefined) {
newitem.description = queryitem.description;
@@ -2936,18 +3044,6 @@ const AppCreator = (defaultprops) => {
setOauth2Scopes(chips)
setUpdate(Math.random())
}}
onAdd={(chip) => {
oauth2Scopes.push(chip);
console.log(oauth2Scopes);
setOauth2Scopes(oauth2Scopes);
setUpdate(Math.random());
}}
onDelete={(chip, index) => {
oauth2Scopes.splice(index, 1);
console.log(oauth2Scopes);
setOauth2Scopes(oauth2Scopes);
setUpdate(Math.random());
}}
/>
</div>
) : null;
@@ -4408,16 +4504,7 @@ const AppCreator = (defaultprops) => {
setNewWorkflowTags(chips)
setUpdate("added "+chips)
}}
onAdd={(chip) => {
newWorkflowTags.push(chip);
setNewWorkflowTags(newWorkflowTags);
setUpdate("added" + chip);
}}
onDelete={(chip, index) => {
newWorkflowTags.splice(index, 1);
setNewWorkflowTags(newWorkflowTags);
setUpdate("delete " + chip);
}}
/>
</div>
);
@@ -5360,6 +5447,167 @@ const AppCreator = (defaultprops) => {
</Dialog>
) : null;
const validateRemote = () => {
setValidation(true);
fetch(globalUrl + "/api/v1/get_openapi_uri", {
method: "POST",
headers: {
Accept: "application/json",
},
body: JSON.stringify(openApi),
credentials: "include",
})
.then((response) => {
setValidation(false);
if (response.status !== 200) {
return response.json();
}
return response.text();
})
.then((responseJson) => {
if (typeof responseJson !== "string" && !responseJson.success) {
console.log(responseJson.reason);
if (responseJson.reason !== undefined) {
setOpenApiError(responseJson.reason);
} else {
setOpenApiError("Undefined issue with OpenAPI validation");
}
return;
}
console.log("Validating response!");
validateOpenApi(responseJson);
})
.catch((error) => {
toast(error.toString());
setOpenApiError(error.toString());
});
}
const circularLoader = validation ? (
<CircularProgress color="primary" />
) : null;
const newApimodalView = openApiModal ?
<Dialog
open={openApiModal}
onClose={() => {
setOpenApiModal(false)
}}
PaperProps={{
style: {
backgroundColor: surfaceColor,
color: "white",
minWidth: "800px",
minHeight: "320px",
},
}}
>
<FormControl>
<DialogTitle>
<div style={{ color: "rgba(255,255,255,0.9)" }}>
Merge with another OpenAPI document. You will get to choose Actions before they are merged.
</div>
</DialogTitle>
<DialogContent style={{ color: "rgba(255,255,255,0.65)" }}>
Paste in the URI for the OpenAPI
<TextField
style={{ backgroundColor: inputColor }}
variant="outlined"
margin="normal"
InputProps={{
style: {
color: "white",
height: "50px",
fontSize: "1em",
},
endAdornment: (
<Button
style={{
borderRadius: "0px",
marginTop: "0px",
height: "50px",
}}
variant="contained"
disabled={openApi.length === 0 || appValidation.length > 0}
color="primary"
onClick={() => {
setOpenApiError("");
validateRemote();
}}
>
Validate
</Button>
),
}}
onChange={(e) => {
setOpenApi(e.target.value);
}}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
Must point to a version 2 or 3 OpenAPI specification.
</span>
}
placeholder="OpenAPI URI"
fullWidth
/>
{/*
<div style={{marginTop: "15px"}}/>
Example:
<div />
https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v2.0/json/uber.json
*/}
<p>Or upload a YAML/JSON specification</p>
<input
hidden
type="file"
ref={newUpload}
accept="application/JSON,application/YAML,application/yaml,text/yaml,text/x-yaml,application/x-yaml,application/vnd.yaml,.yml,.yaml"
multiple={false}
onChange={uploadFile}
/>
<Button
variant="contained"
color="primary"
onClick={() => newUpload.current.click()}
>
Upload
</Button>
{errorText}
</DialogContent>
<DialogActions>
{circularLoader}
<Button
style={{ borderRadius: "0px" }}
onClick={() => {
setOpenApiModal(false);
setAppValidation("");
setOpenApiError("");
setOpenApi("");
setOpenApiData("");
}}
color="primary"
>
Cancel
</Button>
<Button
variant="contained"
style={{ borderRadius: "0px" }}
disabled={appValidation.length === 0}
onClick={() => {
redirectOpenApi();
}}
color="primary"
>
Continue
</Button>
</DialogActions>
</FormControl>
</Dialog>
: null
// Random names for type & autoComplete. Didn't research :^)
const landingpageDataBrowser = (
<div style={{ paddingBottom: 100, color: "white" }}>
@@ -5391,9 +5639,30 @@ const AppCreator = (defaultprops) => {
onChange={editHeaderImage}
/>
<Paper style={boxStyle}>
<h2 style={{ marginBottom: "10px", color: "white" }}>
General information
</h2>
<div style={{display: "flex", }}>
<div style={{flex: 1, }}>
<h2 style={{ marginBottom: "10px", color: "white" }}>
General information
</h2>
</div>
<div style={{flex: 1, itemAlign: "right", textAlign: "right",}}>
<Tooltip title="Merge with another API (coming soon)" placement="bottom">
<IconButton
disabled
onClick={() => {
setOpenApiModal(true)
}}
>
<CallMergeIcon
style={{}}
onClick={() => {
setOpenApiModal(true)
}}
/>
</IconButton>
</Tooltip>
</div>
</div>
<a
target="_blank"
href="https://shuffler.io/docs/app_creation#app-creator-instructions"
@@ -5706,6 +5975,7 @@ const AppCreator = (defaultprops) => {
isLoaded && isAppLoaded ? (
<div>
<div style={bodyDivStyle}>{landingpageDataBrowser}</div>
{newApimodalView}
</div>
) : (
<div></div>
+2 -1
View File
@@ -1354,7 +1354,7 @@ const Apps = (props) => {
border: hover ? "1px solid #f85a3e" : "1px solid rgba(255,255,255,0.3)",
cursor: hover ? "pointer" : "default",
textAlign: "center",
height: 150,
height: 125,
}}
>
{icon}
@@ -2556,6 +2556,7 @@ const Apps = (props) => {
const circularLoader = validation ? (
<CircularProgress color="primary" />
) : null;
const appsModalLoad = loadAppsModalOpen ? (
<Dialog
open={loadAppsModalOpen}
+21 -21
View File
@@ -730,28 +730,28 @@ const Settings = (props) => {
</Button>
<h3>{passwordFormMessage}</h3>
<Divider style={{ marginTop: "40px" }} />
<h2>Platform Earnings</h2>
<h2>Creator Incentive Program</h2>
<div style={{ display: runFlex ? "flex" : "", width: "100%" }}>
<div>
{isCloud ?
<span>
<Typography variant="body1" color="textSecondary">
By connecting your Github account, you agree to our <a href="/docs/terms_of_service" target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}}>Terms of Service</a>, and acknowledge that your non-sensitive data will be turned into a <a target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}} href="https://shuffler.io/creators">creator account</a>. This enables you to earn a passive income from Shuffle. This IS reversible. Support: support@shuffler.io
</Typography>
<Button
style={{ height: 40, marginTop: 10 }}
variant="outlined"
color="primary"
fullWidth={true}
onClick={() => {
handleGithubConnection();
}}
>
Connect to Github
</Button>
</span>
: null}
</div>
<div>
{isCloud ?
<span>
<Typography variant="body1" color="textSecondary">
By <a href="/creators" target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}}>joining the Creator Incentive Program</a> and connecting your Github account, you agree to our <a href="/docs/terms_of_service" target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}}>Terms of Service</a>, and acknowledge that your non-sensitive data will be turned into a <a target="_blank" style={{ textDecoration: "none", color: "#f86a3e"}} href="https://shuffler.io/creators">creator account</a>. This enables you to earn a passive income from Shuffle. This IS reversible. Support: support@shuffler.io
</Typography>
<Button
style={{ height: 40, marginTop: 10 }}
variant="outlined"
color="primary"
fullWidth={true}
onClick={() => {
handleGithubConnection();
}}
>
Connect to Github
</Button>
</span>
: null}
</div>
<div style={{ flex: 1, display: "flex" }}>
<div>
{userdata.eth_info !== undefined &&
+17 -11
View File
@@ -638,7 +638,7 @@ const Workflows = (props) => {
window.location.host === "shuffler.io";
const findWorkflow = (filters) => {
console.log("Using filters: ", filters)
console.log("Using filters: ", filters)
if (filters.length === 0) {
setFilteredWorkflows(workflows);
handleKeysetting(allUsecases, workflows)
@@ -656,6 +656,12 @@ const Workflows = (props) => {
);
}
if (curWorkflow.tags !== undefined && curWorkflow.tags !== null && curWorkflow.tags.length > 0) {
// Make them all lowercase
curWorkflow.tags = curWorkflow.tags.map((tag) => tag.toLowerCase())
}
if (found.every((v) => v !== true)) {
found = filters.map((filter) => {
if (filter === undefined || filter === null) {
@@ -666,7 +672,7 @@ const Workflows = (props) => {
if (curWorkflow.name.toLowerCase().includes(filter.toLowerCase())) {
return true;
} else if (curWorkflow.tags !== undefined && curWorkflow.tags !== null && curWorkflow.tags.includes(filter)) {
} else if (curWorkflow.tags !== undefined && curWorkflow.tags !== null && curWorkflow.tags.includes(filter.toLowerCase())) {
return true;
} else if (curWorkflow.owner === filter) {
return true;
@@ -674,17 +680,17 @@ const Workflows = (props) => {
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 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
}
}
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
+2 -2
View File
@@ -224,7 +224,7 @@ func deployServiceWorkers(image string) {
}
if err != nil {
log.Printf("[ERROR] Failed to convert the default MTU to int: %s. Using 1500 instead", err)
log.Printf("[DEBUG] Failed to convert the default MTU to int: %s. Using 1500 instead", err)
mtu = 1500
}
@@ -1601,6 +1601,6 @@ func sendWorkerRequest(workflowExecution shuffle.ExecutionRequest) error {
_ = body
log.Printf("[DEBUG] Ran worker from request with execution ID: %s. Worker URL: %s. DEBUGGING: docker service logs shuffle-workers 2&>1 | grep %s", workflowExecution.ExecutionId, streamUrl, workflowExecution.ExecutionId)
log.Printf("[DEBUG] Ran worker from request with execution ID: %s. Worker URL: %s. DEBUGGING: docker service logs shuffle-workers 2>&1 | grep %s", workflowExecution.ExecutionId, streamUrl, workflowExecution.ExecutionId)
return nil
}