Lightmode/Darkmode merge including many fixes since 2.0.2

This commit is contained in:
Frikky
2025-05-19 00:04:37 +02:00
parent 7bc246c003
commit a4ebf3e558
59 changed files with 5931 additions and 2961 deletions
+10 -5
View File
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import AdminNavBar from '../components/AdminNavBar.jsx';
import { toast } from "react-toastify";
import { Context } from '../context/ContextApi.jsx';
const Admin2 = (props) => {
// Destructure props if needed
@@ -10,13 +11,15 @@ const Admin2 = (props) => {
const [selectedOrganization, setSelectedOrganization] = useState({});
const [organizationFeatures, setOrganizationFeatures] = useState({});
const [orgRequest, setOrgRequest] = React.useState(true);
const [isOrgLoaded, setIsOrgLoaded] = React.useState(false);
const {brandName} = useContext(Context)
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
if (document !== undefined) {
if (selectedOrganization?.name !== undefined) {
document.title = selectedOrganization?.name + " - Admin - Shuffle"
if (selectedOrganization?.name !== undefined) {
document.title = brandName?.length > 0 ? selectedOrganization?.name + ` - Admin - ${brandName}` : selectedOrganization?.name + ` - Admin - Shuffle`;
} else {
document.title = "Admin - Shuffle"
document.title = brandName?.length > 0 ? `Admin - ${brandName}` : `Admin - Shuffle`;
}
}
@@ -151,6 +154,8 @@ const Admin2 = (props) => {
.catch((error) => {
console.log("Error getting org: ", error);
toast("Error getting current organization");
}).finally(() => {
setIsOrgLoaded(true)
});
};
@@ -330,7 +335,7 @@ const Admin2 = (props) => {
return (
<div style={{ display: 'flex', justifyContent: 'center', paddingTop: 29, zoom: 0.9}}>
<AdminNavBar userdata={userdata} isLoaded={isLoaded} selectedStatus={selectedStatus} setSelectedStatus={setSelectedStatus} selectedTab={selectedTab} orgId={selectedOrganization.id} handleStatusChange={handleStatusChange} handleEditOrg={handleEditOrg} handleGetOrg={handleGetOrg} setSelectedOrganization={setSelectedOrganization} selectedOrganization={selectedOrganization} setNotifications={setNotifications} stripeKey={stripeKey} notifications={notifications} checkLogin={checkLogin} globalUrl={globalUrl} isCloud={isCloud}/>
<AdminNavBar userdata={userdata} isLoaded={isLoaded} isOrgLoaded={isOrgLoaded} selectedStatus={selectedStatus} setSelectedStatus={setSelectedStatus} selectedTab={selectedTab} orgId={selectedOrganization.id} handleStatusChange={handleStatusChange} handleEditOrg={handleEditOrg} handleGetOrg={handleGetOrg} setSelectedOrganization={setSelectedOrganization} selectedOrganization={selectedOrganization} setNotifications={setNotifications} stripeKey={stripeKey} notifications={notifications} checkLogin={checkLogin} globalUrl={globalUrl} isCloud={isCloud}/>
</div>
);
};
File diff suppressed because it is too large Load Diff
+5 -4
View File
@@ -59,6 +59,7 @@ const ApiExplorer = React.lazy(() => import("../components/ApiExplorer.jsx"));
const ApiExplorerWrapper = (props) => {
const { globalUrl, serverside, userdata, isLoggedIn, isLoaded} = props;
const { supportEmail } = useContext(Context);
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io"
const location = useLocation();
const navigate = useNavigate();
@@ -165,7 +166,7 @@ const ApiExplorerWrapper = (props) => {
}
if (!found) {
toast.error(`Failed to get API data for '${appname}' (1). Contact support@shuffler.io if this persists.`, {
toast.error(`Failed to get API data for '${appname}' (1). Contact ${supportEmail} if this persists.`, {
"autoClose": 10000,
})
@@ -174,7 +175,7 @@ const ApiExplorerWrapper = (props) => {
},3000)
}
} else {
toast.error(`Failed to get API data for '${appname}' (2). Contact support@shuffler.io if this persists.`, {
toast.error(`Failed to get API data for '${appname}' (2). Contact ${supportEmail} if this persists.`, {
"autoClose": 10000,
})
setTimeout(()=>{
@@ -539,7 +540,7 @@ const ApiExplorerWrapper = (props) => {
}else if (openapi?.id?.length > 0) {
appid = openapi?.id;
}else{
toast.error("App id is missing and we can't run the API. Please contact support@shuffler.io if this persists.");
toast.error(`App id is missing and we can't run the API. Please contact ${supportEmail} if this persists.`);
return;
}
@@ -673,7 +674,7 @@ const ApiExplorerWrapper = (props) => {
if (data.result.includes("custom_action doesn't exist")) {
// No timeout error
toast.info("This API is being rebuilt due to missing functionality. Please wait a minute or two, then try again. If this persists, please report to support@shuffler.io", {
toast.info(`This API is being rebuilt due to missing functionality. Please wait a minute or two, then try again. If this persists, please report to ${supportEmail}`, {
"autoClose": 90000,
})
} else if (data.result.includes("authentication") && data.result.includes("Oauth2")) {
+170 -142
View File
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useContext } from "react";
import { makeStyles } from "@mui/styles";
import { BrowserView, MobileView } from "react-device-detect";
import theme from '../theme.jsx';
import { getTheme } from '../theme.jsx';
import {
Paper,
@@ -57,6 +57,7 @@ import { ToastContainer, toast } from "react-toastify"
import words from "shellwords";
import AvatarEditor from "react-avatar-editor";
import { Context } from "../context/ContextApi.jsx";
const surfaceColor = "#27292D";
const inputColor = "#383B40";
@@ -67,33 +68,7 @@ const bodyDivStyle = {
zoom: 0.8,
};
const actionListStyle = {
paddingLeft: "10px",
paddingRight: "10px",
paddingBottom: "10px",
paddingTop: "10px",
marginTop: "5px",
display: "flex",
color: "white",
position: "relative",
backgroundColor: theme.palette.platformColor,
};
const boxStyle = {
color: "white",
flex: "1",
marginLeft: "10px",
marginRight: "10px",
paddingLeft: "30px",
paddingRight: "30px",
paddingBottom: "30px",
paddingTop: "30px",
display: "flex",
flexDirection: "column",
backgroundColor: theme.palette.backgroundColor,
};
const dividerStyle = {
marginBottom: "10px",
@@ -427,9 +402,40 @@ const AppCreator = (defaultprops) => {
const [actionAmount, setActionAmount] = useState(increaseAmount);
const [newAppGroup, setNewAppGroup] = useState("")
const { themeMode, supportEmail, brandColor } = useContext(Context);
const theme = getTheme(themeMode, brandColor);
const [oauth2Scopes, setOauth2Scopes] = useState([]);
const [oauth2Type, setOauth2Type] = useState("delegated");
const actionListStyle = {
paddingLeft: "10px",
paddingRight: "10px",
paddingBottom: "10px",
paddingTop: "10px",
marginTop: "5px",
display: "flex",
color: theme.palette.text.primary,
position: "relative",
backgroundColor: theme.palette.platformColor,
};
const boxStyle = {
color: theme.palette.text.primary,
flex: "1",
marginLeft: "10px",
marginRight: "10px",
paddingLeft: "30px",
paddingRight: "30px",
paddingBottom: "30px",
paddingTop: "30px",
display: "flex",
flexDirection: "column",
backgroundColor: theme.palette.platformColor,
};
//client_credentials
const [oauth2GrantType, setOauth2GrantType] = useState("");
const defaultAuth = {
@@ -2626,7 +2632,7 @@ const AppCreator = (defaultprops) => {
if (response.status === 403) {
var urlParams = new URLSearchParams(window.location.search)
if (urlParams.has("id")) {
toast.error("Please log in to build this app. If this error persists, please contact support@shuffler.io")
toast.error(`Please log in to build this app. If this error persists, please contact ${supportEmail}`)
} else {
toast.error("Failed to save the app as you are not the owner. Redirecting you to the forking page. When there, save again.")
if (props.match.params.appid !== undefined && props.match.params.appid !== null && props.match.params.appid.length > 0) {
@@ -2678,12 +2684,12 @@ const AppCreator = (defaultprops) => {
const bearerAuth =
authenticationOption === "Bearer auth" ? (
<div style={{ color: "white" }}>
<div style={{ color: theme.palette.text.primary }}>
<h4>
<a
target="_blank"
href="https://swagger.io/docs/specification/authentication/bearer-authentication/"
style={{ textDecoriation: "none", color: "#f85a3e" }}
style={{ textDecoriation: "none", color: theme.palette.linkColor }}
>
Bearer auth
</a>
@@ -2696,12 +2702,12 @@ const AppCreator = (defaultprops) => {
// Basicauth
const basicAuth =
authenticationOption === "Basic auth" ? (
<div style={{ color: "white" }}>
<div style={{ color: theme.palette.text.primary }}>
<h4>
<a
target="_blank"
href="https://swagger.io/docs/specification/authentication/basic-authentication/"
style={{ textDecoriation: "none", color: "#f85a3e" }}
style={{ textDecoriation: "none", color: theme.palette.linkColor }}
>
Basic authentication
</a>
@@ -2795,7 +2801,7 @@ const AppCreator = (defaultprops) => {
flex: 2,
marginTop: 0,
marginBottom: 0,
backgroundColor: inputColor,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
marginRight: 5,
}}
fullWidth={true}
@@ -2813,7 +2819,8 @@ const AppCreator = (defaultprops) => {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
color: theme.palette.textFieldStyle.color,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
minHeight: 50,
marginLeft: 5,
maxWidth: "95%",
@@ -2828,7 +2835,7 @@ const AppCreator = (defaultprops) => {
marginTop: 0,
marginBottom: 0,
flex: 2,
backgroundColor: inputColor,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
marginRight: 5,
}}
fullWidth={true}
@@ -2843,7 +2850,8 @@ const AppCreator = (defaultprops) => {
}}
InputProps={{
style: {
color: "white",
color: theme.palette.textFieldStyle.color,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
minHeight: 50,
marginLeft: 5,
maxWidth: "95%",
@@ -2861,9 +2869,9 @@ const AppCreator = (defaultprops) => {
value={extraAuth[index].type}
style={{
flex: 1,
backgroundColor: inputColor,
backgroundColor: theme.palette.backgroundColor,
paddingLeft: "10px",
color: "white",
color: theme.palette.text.primary,
height: 50,
borderRadius: theme.shape.borderRadius,
}}
@@ -2874,14 +2882,14 @@ const AppCreator = (defaultprops) => {
>
<MenuItem
key={index}
style={{ backgroundColor: inputColor, color: "white" }}
style={{ backgroundColor: theme.palette.backgroundColor, color: theme.palette.text.primary }}
value={"header"}
>
Header
</MenuItem>
<MenuItem
key={index}
style={{ backgroundColor: inputColor, color: "white" }}
style={{ backgroundColor: theme.palette.backgroundColor, color: theme.palette.text.primary }}
value={"query"}
>
Query
@@ -2929,7 +2937,7 @@ const AppCreator = (defaultprops) => {
const jwtAuth =
authenticationOption === "JWT" ? (
<div style={{ color: "white", marginTop: 20 }}>
<div style={{ color: theme.palette.text.primary, marginTop: 20 }}>
<Typography variant="body1">JWT authentication</Typography>
<Typography
variant="body2"
@@ -2948,7 +2956,7 @@ const AppCreator = (defaultprops) => {
variant="outlined"
defaultValue={parameterName}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
<span style={{ color: theme.palette.text.primary, marginBottom: "2px" }}>
Must start with / and be a valid path
</span>
}
@@ -2958,7 +2966,7 @@ const AppCreator = (defaultprops) => {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
color: theme.palette.text.primary,
},
}}
/>
@@ -2979,7 +2987,7 @@ const AppCreator = (defaultprops) => {
variant="outlined"
defaultValue={parameterName}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
<span style={{ color: theme.palette.text.primary, marginBottom: "2px" }}>
Must use 'key=value&key=value' format
</span>
}
@@ -2991,7 +2999,7 @@ const AppCreator = (defaultprops) => {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
color: theme.palette.text.primary,
},
}}
/>
@@ -3001,7 +3009,7 @@ const AppCreator = (defaultprops) => {
const oauth2Auth =
authenticationOption === "Oauth2" ? (
<div style={{ color: "white", marginTop: 20 }}>
<div style={{ color: theme.palette.text.primary, marginTop: 20 }}>
<Typography variant="body1">Oauth2 authentication</Typography>
<Typography
variant="body2"
@@ -3060,7 +3068,7 @@ const AppCreator = (defaultprops) => {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
color: theme.palette.text.primary,
},
}}
/>
@@ -3111,7 +3119,7 @@ const AppCreator = (defaultprops) => {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
color: theme.palette.text.primary,
},
}}
/>
@@ -3160,7 +3168,7 @@ const AppCreator = (defaultprops) => {
}}
InputProps={{
style: {
color: "white",
color: theme.palette.text.primary,
},
}}
/>
@@ -3177,7 +3185,7 @@ const AppCreator = (defaultprops) => {
required
InputProps={{
style: {
color: "white",
color: theme.palette.text.primary,
maxHeight: 160,
},
}}
@@ -3202,7 +3210,7 @@ const AppCreator = (defaultprops) => {
const apiKey =
authenticationOption === "API key" ? (
<div style={{ color: "white", marginTop: 20 }}>
<div style={{ color: theme.palette.text.primary, marginTop: 20 }}>
<Typography variant="body1">API key authentication</Typography>
<Typography variant="body2" color="textSecondary">
<b>Do NOT put your actual API-key.</b> Add the name of the field used for authentication, e.g. "X-APIKEY".
@@ -3221,7 +3229,7 @@ const AppCreator = (defaultprops) => {
variant="outlined"
value={parameterName}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
<span style={{ color: theme.palette.text.primary, marginBottom: "2px" }}>
Can't be empty or contain any of the following: !#$%&'^"+-._~|]+$:=
</span>
}
@@ -3238,7 +3246,7 @@ const AppCreator = (defaultprops) => {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
color: theme.palette.text.primary,
},
}}
/>
@@ -3255,7 +3263,7 @@ const AppCreator = (defaultprops) => {
borderRadius: theme.shape.borderRadius,
backgroundColor: inputColor,
paddingLeft: 10,
color: "white",
color: theme.palette.text.primary,
height: 57,
}}
inputProps={{
@@ -3271,7 +3279,7 @@ const AppCreator = (defaultprops) => {
return (
<MenuItem
key={index}
style={{ backgroundColor: inputColor, color: "white" }}
style={{ backgroundColor: inputColor, color: theme.palette.text.primary }}
value={data}
>
{data}
@@ -3463,15 +3471,14 @@ const AppCreator = (defaultprops) => {
<Tooltip title={chipRequired ? "Make not required" : "Make required"}>
<Chip
style={{
backgroundColor: chipRequired ? "#f86a3e" : "#3d3f43",
backgroundColor: chipRequired ? "#f86a3e" : theme.palette.chipStyle.backgroundColor,
height: 30,
margin: 3,
paddingLeft: 5,
paddingRight: 5,
height: 28,
cursor: "pointer",
borderColor: "#3d3f43",
color: "white",
borderColor: theme.palette.chipStyle.borderColor,
color: theme.palette.chipStyle.color,
}}
label={parsedChip}
onClick={() => {
@@ -3557,7 +3564,7 @@ const AppCreator = (defaultprops) => {
placeholder={"Query name (key)"}
label={"Query Key"}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
<span style={{ color: theme.palette.text.primary, marginBottom: "2px" }}>
Click required to flip
</span>
}
@@ -3569,7 +3576,7 @@ const AppCreator = (defaultprops) => {
style={{flex: 3}}
InputProps={{
style: {
color: "white",
color: theme.palette.text.primary,
},
}}
/>
@@ -3589,7 +3596,7 @@ const AppCreator = (defaultprops) => {
style={{flex: 2}}
InputProps={{
style: {
color: "white",
color: theme.palette.text.primary,
},
}}
/>
@@ -3662,7 +3669,7 @@ const AppCreator = (defaultprops) => {
)}
<TextField
required
style={{ flex: "1", marginRight: "15px", backgroundColor: inputColor }}
style={{ flex: "1", marginRight: "15px", backgroundColor: theme.palette.textFieldStyle.backgroundColor }}
fullWidth={true}
placeholder={
'{\n\t"example": "${example}",\n\t"apikey": "${apikey}",\n\t"search": "1.2.3.5"\n}'
@@ -3678,7 +3685,7 @@ const AppCreator = (defaultprops) => {
}}
key={currentAction}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
<span style={{ color: theme.palette.text.primary, marginBottom: "2px" }}>
Shows an example body to the user. ${} creates variables.
</span>
}
@@ -3687,7 +3694,8 @@ const AppCreator = (defaultprops) => {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
color: theme.palette.textFieldStyle.color,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
},
}}
/>
@@ -3700,7 +3708,7 @@ const AppCreator = (defaultprops) => {
<b>Example success response</b>
<TextField
required
style={{ flex: "1", marginRight: "15px", backgroundColor: inputColor }}
style={{ flex: "1", marginRight: "15px", backgroundColor: theme.palette.textFieldStyle.backgroundColor }}
fullWidth={true}
placeholder={
'{\n\t"email": "testing@test.com",\n\t"firstname": "testing"\n}'
@@ -3712,14 +3720,15 @@ const AppCreator = (defaultprops) => {
defaultValue={currentAction["example_response"]}
onChange={(e) => setActionField("example_response", e.target.value)}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
<span style={{ color: theme.palette.text.primary, marginBottom: "2px" }}>
Helps with autocompletion and understanding of the endpoint
</span>
}
key={currentAction}
InputProps={{
style: {
color: "white",
color: theme.palette.textFieldStyle.color,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
},
}}
/>
@@ -3794,8 +3803,8 @@ const AppCreator = (defaultprops) => {
fullWidth
PaperProps={{
style: {
backgroundColor: surfaceColor,
color: "white",
backgroundColor: theme.palette.drawer.backgroundColor,
color: theme.palette.text.primary,
minWidth: 700,
maxWidth: 700,
},
@@ -3812,15 +3821,15 @@ const AppCreator = (defaultprops) => {
setFileUploadEnabled(false);
}}
>
<FormControl style={{ backgroundColor: surfaceColor, color: "white" }}>
<FormControl style={{ backgroundColor: theme.palette.drawer.backgroundColor, color: theme.palette.text.primary }}>
<DialogTitle style={{marginTop: 45, }}>
<div style={{ color: "white" }}>New action</div>
<div style={{ color: theme.palette.text.primary }}>New action</div>
</DialogTitle>
<DialogContent style={{paddingBottom: 100, }}>
<a
target="_blank"
href="https://shuffler.io/docs/app_creation#actions"
style={{ textDecoration: "none", color: "#f85a3e" }}
style={{ textDecoration: "none", color: theme.palette.linkColor }}
>
Learn more about actions
</a>
@@ -3832,7 +3841,8 @@ const AppCreator = (defaultprops) => {
flex: "1",
marginTop: 5,
marginRight: 15,
backgroundColor: inputColor,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
}}
fullWidth={true}
placeholder="Name"
@@ -3871,7 +3881,8 @@ const AppCreator = (defaultprops) => {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
},
}}
/>
@@ -3883,7 +3894,8 @@ const AppCreator = (defaultprops) => {
flex: "1",
marginTop: 5,
marginRight: "15px",
backgroundColor: inputColor,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
}}
fullWidth={true}
placeholder="Description"
@@ -3895,7 +3907,8 @@ const AppCreator = (defaultprops) => {
onChange={(e) => setActionField("description", e.target.value)}
InputProps={{
style: {
color: "white",
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
},
}}
/>
@@ -3917,14 +3930,18 @@ const AppCreator = (defaultprops) => {
}}
value={currentActionMethod}
style={{
backgroundColor: inputColor,
paddingLeft: "10px",
color: "white",
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
height: "50px",
}}
inputProps={{
name: "Method",
id: "method-option",
style: {
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
},
}}
>
@@ -3939,7 +3956,7 @@ const AppCreator = (defaultprops) => {
>
<Chip
style={{
color: "white",
color: theme.palette.text.primary,
borderRadius: theme.shape.borderRadius,
minWidth: 80,
marginRight: 10,
@@ -3963,7 +3980,8 @@ const AppCreator = (defaultprops) => {
flex: "1",
marginRight: "15px",
marginTop: "5px",
backgroundColor: inputColor,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
}}
fullWidth={true}
placeholder="URL path"
@@ -3976,7 +3994,7 @@ const AppCreator = (defaultprops) => {
setUrlPath(e.target.value);
}}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
<span style={{ color: theme.palette.text.primary, marginBottom: "2px" }}>
The path to use. Must start with /. Use {"{variablename}"} to
have path variables
</span>
@@ -3987,7 +4005,8 @@ const AppCreator = (defaultprops) => {
input: classes.input,
},
style: {
color: "white",
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
},
}}
onBlur={(event) => {
@@ -4270,7 +4289,7 @@ const AppCreator = (defaultprops) => {
defaultValue={currentAction["file_field"]}
onChange={(e) => setActionField("file_field", e.target.value)}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
<span style={{ color: theme.palette.text.primary, marginBottom: "2px" }}>
The File field to interact with
</span>
}
@@ -4279,7 +4298,7 @@ const AppCreator = (defaultprops) => {
notchedOutline: classes.notchedOutline,
},
style: {
color: "white",
color: theme.palette.text.primary,
},
}}
/>
@@ -4294,7 +4313,8 @@ const AppCreator = (defaultprops) => {
flex: "1",
marginRight: "15px",
marginTop: "5px",
backgroundColor: inputColor,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
}}
fullWidth={true}
placeholder={
@@ -4308,13 +4328,14 @@ const AppCreator = (defaultprops) => {
minRows="2"
onChange={(e) => setActionField("headers", e.target.value)}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
<span style={{ color: theme.palette.text.primary, marginBottom: "2px" }}>
Headers that are part of the request. Default: EMPTY
</span>
}
InputProps={{
style: {
color: "white",
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
},
}}
/>
@@ -4323,14 +4344,14 @@ const AppCreator = (defaultprops) => {
{bodyInfo}
<Divider
style={{
backgroundColor: "rgba(255,255,255,0.5)",
backgroundColor: theme.palette.defaultBorder,
marginTop: 15,
marginBottom: 15,
}}
/>
{exampleResponse}
</DialogContent>
<div style={{position: "fixed", backgroundColor: theme.palette.surfaceColor, bottom: 0, width: "100%", padding: 25, borderTop: "1px solid rgba(255,255,255,0.3)", }}>
<div style={{position: "fixed", backgroundColor: theme.palette.drawer.backgroundColor, bottom: 0, width: "100%", padding: 25, borderTop: theme.palette.defaultBorder, }}>
<Button
color="primary"
variant={urlPath.length > 0 ? "contained" : "outlined"}
@@ -4449,7 +4470,7 @@ const AppCreator = (defaultprops) => {
<Chip
style={{
backgroundColor: bgColor,
color: "white",
color: theme.palette.text.primary,
borderRadius: theme.shape.borderRadius,
minWidth: 80,
marginRight: 10,
@@ -4501,9 +4522,9 @@ const AppCreator = (defaultprops) => {
style={{
border: data.action_label === undefined || data.action_label === "No Label" ? "" : `2px solid ${bgColor}`,
borderRadius: theme.shape.borderRadius,
backgroundColor: inputColor,
backgroundColor: theme.palette.backgroundColor,
paddingLeft: 10,
color: "white",
color: theme.palette.text.primary,
height: 30,
maxWidth: 35,
marginLeft: 10,
@@ -4620,13 +4641,13 @@ const AppCreator = (defaultprops) => {
const tagView = (
<div style={{ color: "white" }}>
<div style={{ color: theme.palette.text.primary }}>
{/*
<ChipInput
style={{marginTop: 10}}
InputProps={{
style:{
color: "white",
color: theme.palette.text.primary,
},
}}
placeholder="Categories"
@@ -4661,7 +4682,7 @@ const AppCreator = (defaultprops) => {
}}
value={newWorkflowCategories.length === 0 ? "Select a category" : newWorkflowCategories[0]}
style={{ backgroundColor: inputColor, color: "white", height: "50px" }}
style={{ backgroundColor: theme.palette.backgroundColor, color: theme.palette.text.primary, height: "50px" }}
>
{categories.map((data, index) => {
if (data === undefined || data === null || data === "" || data === undefined || data === null || data === "") {
@@ -4671,7 +4692,7 @@ const AppCreator = (defaultprops) => {
return (
<MenuItem
key={index}
style={{ backgroundColor: inputColor, color: "white" }}
sx={{ backgroundColor: theme.palette.backgroundColor, color: theme.palette.text.primary, "&:hover" : { backgroundColor: theme.palette.hoverColor} }}
value={data.name}
>
{data.name}
@@ -4701,7 +4722,7 @@ const AppCreator = (defaultprops) => {
}}
InputProps={{
style: {
color: "white",
color: theme.palette.text.primary,
},
}}
/>
@@ -4713,7 +4734,7 @@ const AppCreator = (defaultprops) => {
style={{ marginTop: 10 }}
InputProps={{
style: {
color: "white",
color: theme.palette.text.primary,
},
}}
placeholder="Tags"
@@ -4786,7 +4807,7 @@ const AppCreator = (defaultprops) => {
}}
InputProps={{
style: {
color: "white",
color: theme.palette.text.primary,
height: 50,
fontSize: "1em",
},
@@ -5101,7 +5122,7 @@ const AppCreator = (defaultprops) => {
/*
{selectedAction.authentication.map(data => (
<MenuItem key={data.id} style={{backgroundColor: inputColor, color: "white"}} value={data}>
<MenuItem key={data.id} style={{backgroundColor: inputColor, color: theme.palette.text.primary}} value={data}>
*/
};
@@ -5120,7 +5141,7 @@ const AppCreator = (defaultprops) => {
target="_blank"
rel="norefferer"
href="https://shuffler.io/docs/app_creation#authentication"
style={{ textDecoration: "none", color: "#f85a3e" }}
style={{ textDecoration: "none", color: theme.palette.linkColor }}
>
What is this?
</a>
@@ -5135,7 +5156,7 @@ const AppCreator = (defaultprops) => {
}}
InputProps={{
style: {
color: "white",
color: theme.palette.text.primary,
marginLeft: "5px",
maxWidth: "95%",
height: 50,
@@ -5175,7 +5196,7 @@ const AppCreator = (defaultprops) => {
}}
InputProps={{
style: {
color: "white",
color: theme.palette.text.primary,
marginLeft: "5px",
maxWidth: "95%",
height: 50,
@@ -5225,7 +5246,7 @@ const AppCreator = (defaultprops) => {
};
const actionView = (
<div style={{ color: "white", position: "relative" }}>
<div style={{ color: theme.palette.text.primary, position: "relative" }}>
<div style={{ position: "absolute", right: 0, top: 0 }}>
{actionAmount > 0 && actionAmount < filteredActions.length ? (
<Button
@@ -5277,15 +5298,14 @@ const AppCreator = (defaultprops) => {
key={index}
style={{
backgroundColor:
tag === selectedCategory ? "#f86a3e" : "#3d3f43",
tag === selectedCategory ? "#f86a3e" : theme.palette.chipStyle.backgroundColor,
height: 30,
margin: 3,
paddingLeft: 5,
paddingRight: 5,
height: 28,
cursor: "pointer",
borderColor: "#3d3f43",
color: "white",
borderColor: theme.palette.chipStyle.borderColor,
color: theme.palette.chipStyle.color,
}}
label={newname}
onClick={() => {
@@ -5411,13 +5431,13 @@ const AppCreator = (defaultprops) => {
);
const testView = (
<div style={{ color: "white" }}>
<div style={{ color: theme.palette.text.primary }}>
<h2>Test</h2>
Test an action to see whether it performs in an expected way.
<a
target="_blank"
href="https://shuffler.io/docs/app_creation#testing"
style={{ textDecoration: "none", color: "#f85a3e" }}
style={{ textDecoration: "none", color: theme.palette.linkColor }}
>
&nbsp;TBD: Click here to learn more about testing
</a>
@@ -5572,7 +5592,7 @@ const AppCreator = (defaultprops) => {
PaperProps={{
style: {
backgroundColor: surfaceColor,
color: "white",
color: theme.palette.text.primary,
minWidth: "300px",
minHeight: "300px",
},
@@ -5721,7 +5741,7 @@ const AppCreator = (defaultprops) => {
PaperProps={{
style: {
backgroundColor: surfaceColor,
color: "white",
color: theme.palette.text.primary,
minWidth: "800px",
minHeight: "320px",
},
@@ -5741,7 +5761,7 @@ const AppCreator = (defaultprops) => {
margin="normal"
InputProps={{
style: {
color: "white",
color: theme.palette.text.primary,
height: "50px",
fontSize: "1em",
},
@@ -5768,7 +5788,7 @@ const AppCreator = (defaultprops) => {
setOpenApi(e.target.value);
}}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
<span style={{ color: theme.palette.text.primary, marginBottom: "2px" }}>
Must point to a version 2 or 3 OpenAPI specification.
</span>
}
@@ -5832,14 +5852,14 @@ const AppCreator = (defaultprops) => {
// Random names for type & autoComplete. Didn't research :^)
const landingpageDataBrowser = (
<div style={{ paddingBottom: 100, color: "white" }}>
<div style={{ paddingBottom: 100, color: theme.palette.text.primary, }}>
<Breadcrumbs
aria-label="breadcrumb"
separator=""
style={{ color: "white" }}
style={{ color: theme.palette.text.primary }}
>
<Link to="/apps" style={{ textDecoration: "none", color: "inherit" }}>
<h2 style={{ color: "rgba(255,255,255,0.5)" }}>
<h2 style={{ color: theme.palette.textColor }}>
<AppsIcon style={{ marginRight: 10 }} />
Apps
</h2>
@@ -5860,10 +5880,10 @@ const AppCreator = (defaultprops) => {
ref={(ref) => (upload = ref)}
onChange={editHeaderImage}
/>
<Paper style={boxStyle}>
<div style={boxStyle}>
<div style={{display: "flex", }}>
<div style={{flex: 1, }}>
<h2 style={{ marginBottom: "10px", color: "white" }}>
<h2 style={{ marginBottom: "10px", color: theme.palette.text.primary }}>
General information
</h2>
</div>
@@ -5907,13 +5927,13 @@ const AppCreator = (defaultprops) => {
<a
target="_blank"
href="https://shuffler.io/docs/app_creation#app-creator-instructions"
style={{ textDecoration: "none", color: "#f85a3e" }}
style={{ textDecoration: "none", color: theme.palette.linkColor }}
>
Click to learn more about app creation
</a>
<div
style={{
color: "white",
color: theme.palette.text.primary,
flex: "1",
display: "flex",
flexDirection: "row",
@@ -5944,7 +5964,7 @@ const AppCreator = (defaultprops) => {
/>
</div>
</Tooltip>
<div style={{ flex: "3", color: "white", marginLeft: 20, }}>
<div style={{ flex: "3", color: theme.palette.text.primary, marginLeft: 20, }}>
<div style={{ marginTop: "10px" }} />
Name
<TextField
@@ -5953,7 +5973,7 @@ const AppCreator = (defaultprops) => {
flex: "1",
marginTop: "5px",
marginRight: "15px",
backgroundColor: inputColor,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
}}
fullWidth={true}
placeholder="Name"
@@ -5989,7 +6009,8 @@ const AppCreator = (defaultprops) => {
color="primary"
InputProps={{
style: {
color: "white",
color: theme.palette.textFieldStyle.color,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
height: "50px",
fontSize: "1em",
},
@@ -6005,13 +6026,19 @@ const AppCreator = (defaultprops) => {
style={{
marginTop: 5,
marginRight: 15,
backgroundColor: inputColor,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
maxHeight: 250,
overflowY: "auto"
}}
fullWidth={true}
type="name"
id="outlined-with-placeholder"
inputProps={{
style: {
color: theme.palette.textFieldStyle.color,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
}
}}
margin="normal"
multiline
variant="outlined"
@@ -6033,7 +6060,7 @@ const AppCreator = (defaultprops) => {
/>
<Typography
variant="h6"
style={{ marginTop: 10, marginBottom: 10, color: "white" }}
style={{ marginTop: 10, marginBottom: 10, color: theme.palette.text.primary }}
>
API information
</Typography>
@@ -6042,14 +6069,15 @@ const AppCreator = (defaultprops) => {
</Typography>
<TextField
color="primary"
style={{ backgroundColor: inputColor, marginTop: "5px" }}
style={{ backgroundColor: theme.palette.textFieldStyle.backgroundColor, marginTop: "5px" }}
InputProps={{
classes: {
notchedOutline: classes.notchedOutline,
},
style: {
height: "50px",
color: "white",
color: theme.palette.textFieldStyle.color,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
fontSize: "1em",
},
}}
@@ -6061,7 +6089,7 @@ const AppCreator = (defaultprops) => {
variant="outlined"
value={baseUrl}
helperText={
<span style={{ color: "white", marginBottom: "2px" }}>
<span style={{ color: theme.palette.text.primary, marginBottom: "2px" }}>
Must start with http(s):// and CANT end with /.{" "}
</span>
}
@@ -6098,7 +6126,7 @@ const AppCreator = (defaultprops) => {
<a
target="_blank"
href="https://shuffler.io/docs/app_creation#authentication"
style={{ textDecoration: "none", color: "#f85a3e" }}
style={{ textDecoration: "none", color: theme.palette.linkColor }}
>
Learn more about app authentication
</a>
@@ -6122,15 +6150,15 @@ const AppCreator = (defaultprops) => {
}}
value={authenticationOption}
style={{
backgroundColor: inputColor,
color: "white",
backgroundColor: theme.palette.backgroundColor,
color: theme.palette.text.primary,
height: "50px",
}}
>
{authenticationOptions.map((data, index) => (
<MenuItem
key={index}
style={{ backgroundColor: inputColor, color: "white" }}
sx={{ backgroundColor: theme.palette.backgroundColor, color: theme.palette.text.primary, "&:hover": {backgroundColor: theme.palette.backgroundColor} }}
value={data}
>
{data}
@@ -6165,14 +6193,14 @@ const AppCreator = (defaultprops) => {
value={oauth2Type}
style={{
backgroundColor: inputColor,
color: "white",
color: theme.palette.text.primary,
height: "50px",
}}
>
{["delegated", "application"].map((data, index) => (
<MenuItem
key={index}
style={{ backgroundColor: inputColor, color: "white" }}
style={{ backgroundColor: inputColor, color: theme.palette.text.primary }}
value={data}
>
{data}
@@ -6193,14 +6221,14 @@ const AppCreator = (defaultprops) => {
value={oauth2GrantType}
style={{
backgroundColor: inputColor,
color: "white",
color: theme.palette.text.primary,
height: "50px",
}}
>
{["client_credentials", "password"].map((data, index) => (
<MenuItem
key={index}
style={{ backgroundColor: inputColor, color: "white" }}
style={{ backgroundColor: inputColor, color: theme.palette.text.primary }}
value={data}
>
{data}
@@ -6225,8 +6253,8 @@ const AppCreator = (defaultprops) => {
{/*authenticationOption === "No authentication" ? null :
<FormControlLabel
style={{color: "white", marginBottom: 0, marginTop: 20}}
label=<div style={{color: "white"}}>Authentication required (default true)</div>
style={{color: theme.palette.text.primary, marginBottom: 0, marginTop: 20}}
label=<div style={{color: theme.palette.text.primary}}>Authentication required (default true)</div>
control={<Switch checked={authenticationRequired} onChange={() => {
setAuthenticationRequired(!authenticationRequired)
}} />}
@@ -6321,7 +6349,7 @@ const AppCreator = (defaultprops) => {
{errorCode.length > 0 ? `Upload Error: ${errorCode}` : null}
</Typography>
</Paper>
</div>
</div>
);
+84 -72
View File
@@ -1,6 +1,6 @@
import React, { useState, useEffect, useContext } from "react";
import theme from "../theme.jsx";
import {getTheme} from "../theme.jsx";
import ReactGA from "react-ga4";
import Markdown from "react-markdown";
import algoliasearch from "algoliasearch/lite";
@@ -86,53 +86,6 @@ import { sortByKey } from "../views/AngularWorkflow.jsx";
import { v4 as uuidv4 } from "uuid";
import aa from "search-insights";
const surfaceColor = "#27292D";
const inputColor = "#383B40";
const chipStyle = {
marginTop: 5,
backgroundColor: "#3d3f43",
height: 30,
marginRight: 5,
paddingLeft: 5,
paddingRight: 5,
height: 28,
cursor: "pointer",
borderColor: "#3d3f43",
color: "white",
};
const actionListStyle = {
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
marginTop: 5,
backgroundColor: inputColor,
display: "flex",
color: "white",
maxWidth: 350,
minWidth: 350,
maxHeight: 54,
overflow: "hidden",
};
const boxStyle = {
color: "white",
flex: "3",
margin: 10,
paddingLeft: 30,
paddingRight: 30,
paddingBottom: 30,
paddingTop: 30,
display: "flex",
flexDirection: "column",
position: "relative",
maxHeight: 180,
overflow: "hidden",
};
const buttonBackground = "linear-gradient(to right, #f86a3e, #f34079)";
// AppTypes:
// 0 = OpenAPI (VALID)
@@ -162,7 +115,54 @@ const AppExplorer = (props) => {
const classes = useStyles()
let navigate = useNavigate()
const { leftSideBarOpenByClick, } = useContext(Context);
const { leftSideBarOpenByClick, themeMode, supportEmail } = useContext(Context);
const theme = getTheme(themeMode);
const surfaceColor = "#27292D";
const inputColor = theme.palette.textFieldStyle.backgroundColor;
const chipStyle = {
marginTop: 5,
backgroundColor: theme.palette.chipStyle.backgroundColor,
height: 30,
marginRight: 5,
paddingLeft: 5,
paddingRight: 5,
cursor: "pointer",
borderColor: theme.palette.chipStyle.borderColor,
color: theme.palette.chipStyle.color,
};
const actionListStyle = {
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
marginTop: 5,
backgroundColor: inputColor,
display: "flex",
color: theme.palette.text.primary,
maxWidth: 350,
minWidth: 350,
maxHeight: 54,
overflow: "hidden",
};
const boxStyle = {
color: theme.palette.text.primary,
flex: "3",
margin: 10,
paddingLeft: 30,
paddingRight: 30,
paddingBottom: 30,
paddingTop: 30,
display: "flex",
flexDirection: "column",
position: "relative",
maxHeight: 180,
overflow: "hidden",
};
const buttonBackground = "linear-gradient(to right, #f86a3e, #f34079)";
const params = useParams();
//var props = JSON.parse(JSON.stringify(defaultprops))
@@ -385,9 +385,9 @@ const AppExplorer = (props) => {
extraInfo = (
<div
style={{
backgroundColor: theme.palette.inputColor,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
padding: 15,
borderRadius: theme.palette?.borderRadius,
borderRadius: theme.palette?.textFieldStyle.borderRadius,
marginBottom: 30,
display: "flex",
}}
@@ -555,7 +555,9 @@ const AppExplorer = (props) => {
}}
style={{
cursor: "pointer",
color: "white",
backgroundColor: theme.palette.chipStyle.backgroundColor,
borderColor: theme.palette.chipStyle.borderColor,
color: theme.palette.chipStyle.color,
borderRadius: 40,
minWidth: 80,
marginRight: 10,
@@ -586,7 +588,9 @@ const AppExplorer = (props) => {
disabled={included === false}
style={{
cursor: included ? "pointer" : "default",
color: "white",
color: theme.palette.chipStyle.color,
borderColor: theme.palette.chipStyle.borderColor,
backgroundColor: theme.palette.chipStyle.backgroundColor,
borderRadius: 40,
minWidth: 80,
marginRight: 10,
@@ -776,7 +780,7 @@ const AppExplorer = (props) => {
if (responseJson.reason !== undefined) {
toast("Failed to perform action: "+responseJson.reason);
} else {
toast("Failed to perform action. Please try again or contact support@shuffler.io");
toast(`Failed to perform action. Please try again or contact ${supportEmail}`);
}
}
} else {
@@ -3093,7 +3097,7 @@ const AppExplorer = (props) => {
margin: 10,
padding: 30,
backgroundColor: boxStyle.backgroundColor,
color: "white",
color: theme.palette.text.primary,
textAlign: "left",
paddingBottom: 50,
overflow: "hidden",
@@ -3117,12 +3121,12 @@ const AppExplorer = (props) => {
style={{ marginBottom: 0, marginLeft: 0, marginRight: 0, minWidth: 800, maxWidth: 800, margin: "auto", }}
aria-label="disabled tabs example"
>
<Tab style={{marginLeft: 0, }} icon={<DescriptionIcon />} label="Docs" />
<Tab style={{marginLeft: 0, color: theme.palette.text.primary }} icon={<DescriptionIcon />} label="Docs" />
<Tab icon={appType === 0 || appType === 2 ? <OpenInNewIcon /> : <AppsIcon />} label={appType === 0 || appType === 2 ? "Explore the API" : "Try it out"} />
<Tab icon={<ShowChartIcon />} label="Stats" />
<Tab icon={<PolylineIcon />} disabled label="Integrations" />
<Tab icon={<PersonIcon />} disabled={userdata.support !== true} label="Creator" value={4} />
<Tab icon={<ShowChartIcon />} style={{color: theme.palette.text.primary}} label="Stats" />
<Tab icon={<PolylineIcon />} disabled style={{color: theme.palette.text.secondary}} label="Integrations" />
<Tab icon={<PersonIcon />} disabled={userdata.support !== true} style={{color: userdata.support !== true ? theme.palette.text.secondary: theme.palette.text.primary}} label="Creator" value={4} />
</Tabs>
<div style={{ marginTop: 25 }}>
{selectedTab === 1 && app.skipped_build == false ? (
@@ -3883,12 +3887,12 @@ const AppExplorer = (props) => {
</div>
<Button
variant="contained"
style={{ borderRadius: "2px", textTransform: 'none', fontSize:16, color: "#1a1a1a", backgroundColor: "#ff8544" }}
color="primary"
style={{ borderRadius: "2px", textTransform: 'none', fontSize:16, }}
onClick={() => {
updateAppField(selectedApp.id, "sharing", true);
setPublishModalOpen(false);
}}
color="primary"
>
Yes
</Button>
@@ -3919,13 +3923,13 @@ const AppExplorer = (props) => {
<Breadcrumbs
aria-label="breadcrumb"
separator=""
style={{ color: "white", marginLeft: 15, flex: 100 }}
style={{ color: theme.palette.text.primary, marginLeft: 15, flex: 100 }}
>
<Link
to="/search"
style={{ textDecoration: "none", color: "inherit" }}
>
<h2 style={{ color: "rgba(255,255,255,0.5)" }}>
<h2 style={{ color: theme.palette.text.primary }}>
<AppsIcon style={{ marginRight: 10 }} />
Apps
</h2>
@@ -3971,9 +3975,7 @@ const AppExplorer = (props) => {
) : null}
{appType === 0 || appType === 2 ? (
<IconButton
color="primary"
style={{ marginRight: 20 }}
variant="contained"
onClick={() => {
const data = openapi;
let exportFileDefaultName = name + ".json";
@@ -4020,7 +4022,7 @@ const AppExplorer = (props) => {
}}
>
<Tooltip title="Download OpenAPI" placement="top">
<CloudDownloadIcon color="secondary" />
<CloudDownloadIcon color={theme.palette.text.primary} />
</Tooltip>
</IconButton>
) : null}
@@ -4036,7 +4038,7 @@ const AppExplorer = (props) => {
}}
>
<Tooltip title="Public Authentication link for the current Organization. Times out every 24 hours." placement="top">
<LockOpenIcon />
<LockOpenIcon color={theme.palette.text.primary}/>
</Tooltip>
</IconButton>
: null}
@@ -4197,8 +4199,8 @@ const AppExplorer = (props) => {
}}
style={{
width: 150,
backgroundColor: theme.palette.surfaceColor,
color: "white",
backgroundColor: theme.palette.backgroundColor,
color: theme.palette.text.primary,
height: 40,
marginTop: 5
}}
@@ -4213,7 +4215,7 @@ const AppExplorer = (props) => {
return (
<MenuItem
key={data}
style={{ backgroundColor: inputColor, color: "white", display: 'flex' }}
sx={{ backgroundColor: inputColor, color: theme.palette.text.primary, display: 'flex', "&:hover": { backgroundColor: theme.palette.hoverColor } }}
value={data}
>
{data}
@@ -4373,8 +4375,8 @@ const AppExplorer = (props) => {
style={{
borderRadius: 25,
fontSize: 11,
color: "white",
backgroundColor: "rgba(255,255,255,0)",
color: theme.palette.text.primary,
backgroundColor: theme.palette.platformColor,
border: "1px solid #ddf4e1",
textTransform: "none",
marginLeft: 4,
@@ -4466,6 +4468,11 @@ const AppExplorer = (props) => {
color: "white",
textAlign: "center",
}}
sx={{
"&:hover": {
backgroundColor: theme.palette.hoverColor,
},
}}
>
<CardActionArea
component={Link}
@@ -4553,6 +4560,11 @@ const AppExplorer = (props) => {
color: "white",
textAlign: "center",
}}
sx={{
"&:hover": {
backgroundColor: theme.palette.hoverColor,
},
}}
>
<CardActionArea
component={Link}
+78 -51
View File
@@ -1,5 +1,5 @@
import React, { useState, useEffect, useContext, useCallback, memo, useMemo, useRef } from "react";
import theme from "../theme.jsx";
import {getTheme} from "../theme.jsx";
import { isMobile } from "react-device-detect";
import { useLocation, useNavigate } from "react-router-dom";
@@ -55,7 +55,9 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" || window.location.host === "localhost:3000";
//const appUrl = isCloud ? `/apps/${data.id}` : `https://shuffler.io/apps/${data.id}`;
const appUrl = `/apps/${data.id}`
const { themeMode } = useContext(Context);
const theme = getTheme(themeMode);
var canEditApp = userdata?.support || userdata?.id === data?.owner ||
(userdata?.admin === "true" && userdata?.active_org?.id === data?.reference_org) || data?.contributors?.includes(userdata?.id)
@@ -104,7 +106,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
display: "flex",
fontFamily: theme?.typography?.fontFamily,
width: '100%',
backgroundColor: mouseHoverIndex === index ? "#2F2F2F" : "#212121"
backgroundColor: mouseHoverIndex === index ? theme.palette.hoverColor : theme.palette.platformColor,
}}
onClick={() => {
handleAppClick(data);
@@ -150,7 +152,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
color: '#F1F1F1'
color: theme.palette.text.primary,
}}>
{data.name.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase())}
</div>
@@ -161,7 +163,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
textOverflow: "ellipsis",
whiteSpace: "nowrap",
marginLeft: 8,
color: "rgba(158, 158, 158, 1)"
color: theme.palette.text.secondary,
}}>
{data.categories ? data.categories.join(", ") : "NA"}
</div>
@@ -172,7 +174,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
whiteSpace: "nowrap",
width: "100%",
marginLeft: 8,
color: "rgba(158, 158, 158, 1)",
color: theme.palette.text.secondary,
display: "flex",
justifyContent: 'space-between',
paddingRight: 15,
@@ -202,7 +204,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
}}>
{
canEditApp ? (
<button style={{ backgroundColor: "rgba(73, 73, 73, 1)", border: "none", cursor: "pointer", color: "white", borderRadius: 3, display: "flex", alignItems: "center", justifyContent: "center", height: 35 }}
<Button style={{ border: "none", cursor: "pointer", borderRadius: 3, display: "flex", alignItems: "center", justifyContent: "center", height: 35 }}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
@@ -211,11 +213,13 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
navigate(editUrl)
}
}}
variant="contained"
color="secondary"
>
<EditIcon />
</button>
</Button>
) : (
<button style={{ backgroundColor: "rgba(73, 73, 73, 1)", border: "none", cursor: "pointer", color: "white", borderRadius: 3, display: "flex", alignItems: "center", justifyContent: "center", height: 35 }}
<Button variant="contained" color="secondary" style={{ border: "none", cursor: "pointer", color: "white", borderRadius: 3, display: "flex", alignItems: "center", justifyContent: "center", height: 35 }}
onClick={(event) => {
event.preventDefault();
event.stopPropagation();
@@ -224,26 +228,23 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
}}
>
<ForkRightIcon />
</button>
</Button>
)
}
<Button
disabled={data?.reference_org === userdata?.active_org?.id}
disabled={data?.reference_org === userdata?.active_org?.id}
variant="contained"
color="secondary"
className="deactivate-button"
sx={{
width: 110,
height: 35,
borderRadius: 0.75,
bgcolor: "rgba(73, 73, 73, 1)",
color: "rgba(241, 241, 241, 1)",
textTransform: "none",
fontSize: 16,
fontFamily: theme?.typography?.fontFamily,
transition: "background-color 0.3s ease",
"&:hover": {
bgcolor: "rgba(93, 93, 93, 1)",
},
}}
onMouseDown={(e) => e.stopPropagation()}
onMouseUp={(e) => e.stopPropagation()}
@@ -308,6 +309,8 @@ const Hits = ({
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
const [deactivatedIndexes, setDeactivatedIndexes] = React.useState([]);
const [isLoading, setIsLoading] = useState(false)
const { themeMode } = useContext(Context);
const theme = getTheme(themeMode);
useEffect(() => {
var baseurl = globalUrl;
@@ -507,7 +510,7 @@ const Hits = ({
overflow: "hidden",
display: "flex",
width: '100%',
backgroundColor: hoverEffect === index ? "#2F2F2F" : "#212121",
backgroundColor: hoverEffect === index ? theme.palette.hoverColor : theme.palette.platformColor,
fontFamily: theme?.typography?.fontFamily
}}
onClick={() => {
@@ -550,7 +553,7 @@ const Hits = ({
maxWidth: "90%",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
color: '#F1F1F1'
color: theme.palette.text.primary
}}
>
{(allActivatedAppIds && allActivatedAppIds.includes(data.objectID)) && <Box sx={{ width: 8, height: 8, backgroundColor: "#02CB70", borderRadius: '50%' }} />}
@@ -558,7 +561,7 @@ const Hits = ({
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
color: '#F1F1F1'
color: theme.palette.text.primary,
}}>
{normalizedString(data.name)}
</div>
@@ -569,7 +572,7 @@ const Hits = ({
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
color: "rgba(158, 158, 158, 1)",
color: theme.palette.text.secondary,
marginTop: 5,
}}
>
@@ -600,12 +603,12 @@ const Hits = ({
componentsProps={{
tooltip: {
sx: {
backgroundColor: "rgba(33, 33, 33, 1)",
color: "rgba(241, 241, 241, 1)",
backgroundColor: theme.palette.tooltip.backgroundColor,
color: theme.palette.tooltip.color,
width: "auto",
height: "auto",
fontSize: 16,
border: "1px solid rgba(73, 73, 73, 1)",
border: theme.palette.tooltip.border,
}
}
}}
@@ -650,15 +653,15 @@ const Hits = ({
<div>
{allActivatedAppIds && allActivatedAppIds?.includes(data.objectID) ? (
<Button
style={{
width: 110,
height: 35,
borderRadius: 4,
backgroundColor: "rgba(73, 73, 73, 1)",
color: "rgba(241, 241, 241, 1)",
variant="contained"
color="secondary"
sx={{
width: "110px",
height: "35px",
borderRadius: "4px",
textTransform: "none",
fontFamily: theme?.typography?.fontFamily,
fontSize: 16,
fontSize: "16px",
}}
onMouseDown={(e) => e.stopPropagation()}
onMouseUp={(e) => e.stopPropagation()}
@@ -671,9 +674,9 @@ const Hits = ({
) : (
<Button
variant="contained"
color="primary"
style={{
backgroundColor: "#FF8544",
color: "black",
width: 102,
height: 35,
borderRadius: 4,
@@ -719,6 +722,8 @@ const SearchBox = ({ refine, searchQuery, setSearchQuery }) => {
const inputRef = useRef(null);
const [localQuery, setLocalQuery] = useState(searchQuery);
const location = useLocation();
const { themeMode } = useContext(Context);
const theme = getTheme(themeMode);
// Initialize search when component mounts or when switching to Discover tab
useEffect(() => {
if (searchQuery) {
@@ -779,7 +784,8 @@ const SearchBox = ({ refine, searchQuery, setSearchQuery }) => {
InputProps={{
style: {
borderRadius: 4,
height: 45
height: 45,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
},
endAdornment: (
<InputAdornment position="end">
@@ -809,6 +815,8 @@ const CustomHits = connectHits(Hits);
// Custom Category Dropdown Component
const CategoryDropdown = ({ items, currentRefinement, refine }) => {
const { themeMode } = useContext(Context);
const theme = getTheme(themeMode);
const handleChange = (event) => {
const value = event.target.value;
refine(value);
@@ -823,7 +831,7 @@ const CategoryDropdown = ({ items, currentRefinement, refine }) => {
onChange={handleChange}
displayEmpty
multiple
style={{ borderRadius: 4, height: 45, fontFamily: theme?.typography?.fontFamily, flex: 1 }}
style={{ borderRadius: 4, height: 45, fontFamily: theme?.typography?.fontFamily, flex: 1, backgroundColor: theme.palette.textFieldStyle.backgroundColor, color: theme.palette.textFieldStyle.color }}
renderValue={(selected) => {
if (selected.length === 0) return 'All Categories';
return (
@@ -875,6 +883,9 @@ const LabelDropdown = ({ items, currentRefinement, refine }) => {
refine(value);
};
const { themeMode } = useContext(Context);
const theme = getTheme(themeMode);
return (
<div style={{ position: 'relative', width: '100%' }}>
<Select
@@ -884,7 +895,7 @@ const LabelDropdown = ({ items, currentRefinement, refine }) => {
onChange={handleChange}
displayEmpty
multiple
style={{ borderRadius: 4, height: 45, fontFamily: theme?.typography?.fontFamily, flex: 1 }}
style={{ borderRadius: 4, height: 45, fontFamily: theme?.typography?.fontFamily, flex: 1, backgroundColor: theme.palette.textFieldStyle.backgroundColor, color: theme.palette.textFieldStyle.color }}
renderValue={(selected) => {
if (selected.length === 0) return 'All Labels';
return (
@@ -930,6 +941,7 @@ const LabelDropdown = ({ items, currentRefinement, refine }) => {
</div>
);
};
const CustomLabelDropdown = connectRefinementList(LabelDropdown);
@@ -970,6 +982,8 @@ const filterApps = (apps, searchQuery, selectedCategory, selectedLabel) => {
const LoginPrompt = () => {
const navigate = useNavigate();
const { themeMode } = useContext(Context);
const theme = getTheme(themeMode);
return (
<div style={{
display: "flex",
@@ -1006,9 +1020,11 @@ const LoginPrompt = () => {
// Add this new component for the app skeleton
const AppSkeleton = () => {
const { themeMode } = useContext(Context);
const theme = getTheme(themeMode);
return (
<Paper elevation={0} style={{
backgroundColor: "#212121",
backgroundColor: theme.palette.platformColor,
width: "100%",
height: 120,
borderRadius: 4,
@@ -1025,7 +1041,7 @@ const AppSkeleton = () => {
height={90}
style={{
borderRadius: 4,
backgroundColor: "rgba(255, 255, 255, 0.1)"
backgroundColor: theme.palette.loaderColor
}}
/>
<div style={{
@@ -1039,19 +1055,19 @@ const AppSkeleton = () => {
variant="text"
width="40%"
height={24}
style={{ backgroundColor: "rgba(255, 255, 255, 0.1)" }}
style={{ backgroundColor: theme.palette.loaderColor }}
/>
<Skeleton
variant="text"
width="60%"
height={20}
style={{ backgroundColor: "rgba(255, 255, 255, 0.1)" }}
style={{ backgroundColor: theme.palette.loaderColor }}
/>
<Skeleton
variant="text"
width="30%"
height={20}
style={{ backgroundColor: "rgba(255, 255, 255, 0.1)" }}
style={{ backgroundColor: theme.palette.loaderColor }}
/>
</div>
</div>
@@ -1117,6 +1133,9 @@ const Apps2 = (props) => {
const [validation, setValidation] = useState(null);
const [createAppModalOpen, setCreateAppModalOpen] = useState(false);
const {themeMode, brandColor} = useContext(Context);
const theme = getTheme(themeMode, brandColor);
const baseRepository = "https://github.com/frikky/shuffle-apps";
const isCloud =
@@ -1373,7 +1392,6 @@ const Apps2 = (props) => {
// setSelectedAction({});
// }
}
if (privateapps.length > 0 && storageApps.length === 0) {
try {
localStorage.setItem("apps", JSON.stringify(privateapps))
@@ -1869,13 +1887,13 @@ const Apps2 = (props) => {
}
const tabActive = {
borderBottom: "5px solid #FF8544",
borderBottom: `5px solid ${theme.palette.primary.main}`,
borderRadius: "2px",
color: "#FF8544"
color: theme.palette.primary.main,
}
return (
<div style={{ paddingTop: 70, paddingLeft: leftSideBarOpenByClick ? 200 : 0, transition: "padding-left 0.3s ease", backgroundColor: "#1A1A1A", fontFamily: theme?.typography?.fontFamily, zoom: 0.7, }}>
<div style={{ paddingTop: 70, paddingLeft: leftSideBarOpenByClick ? 200 : 0, transition: "padding-left 0.3s ease", backgroundColor: theme.palette.backgroundColor, fontFamily: theme?.typography?.fontFamily, zoom: 0.7, }}>
<InstantSearch searchClient={searchClient} indexName="appsearch">
<AppModal
open={openModal}
@@ -1984,7 +2002,7 @@ const Apps2 = (props) => {
</span>
)}
</div>
<div style={{ borderBottom: '1px solid gray', marginBottom: 30 }}>
<div style={{ borderBottom: themeMode === "dark" ? "1px solid #808080" : theme.palette.defaultBorder, marginBottom: 30 }}>
<Tabs
value={currTab}
onChange={(event, newTab) => handleTabChange(event, newTab)}
@@ -2034,6 +2052,10 @@ const Apps2 = (props) => {
value={searchQuery}
id="shuffle_search_field"
onChange={handleSearchChange}
style={{
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
}}
onKeyDown={(event) => {
if (event.key === "Enter") {
event.preventDefault();
@@ -2043,7 +2065,10 @@ const Apps2 = (props) => {
InputProps={{
style: {
borderRadius: 4,
height: 45
height: 45,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
fontSize: 18,
},
endAdornment: (
<InputAdornment position="end">
@@ -2087,7 +2112,9 @@ const Apps2 = (props) => {
style={{
borderRadius: 4,
height: 45,
fontFamily: theme?.typography?.fontFamily
fontFamily: theme?.typography?.fontFamily,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
fontSize: 18,
}}
renderValue={(selected) => {
if (selected.length === 0) return 'All Categories';
@@ -2152,7 +2179,9 @@ const Apps2 = (props) => {
style={{
borderRadius: 4,
height: 45,
fontFamily: theme?.typography?.fontFamily
fontFamily: theme?.typography?.fontFamily,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
fontSize: 18,
}}
renderValue={(selected) => {
if (selected.length === 0) return 'All Labels';
@@ -2211,13 +2240,11 @@ const Apps2 = (props) => {
width: '100%',
borderRadius: '4px',
textTransform: 'none',
backgroundColor: "#FF8544",
color: "#1A1A1A",
fontFamily: theme?.typography?.fontFamily,
fontSize: 16,
fontWeight: 500
}}
startIcon={<AddIcon style={{ color: "#1A1A1A" }} />}
startIcon={<AddIcon />}
>
Create an App
</Button>
+89 -27
View File
@@ -1,7 +1,7 @@
import React, { useEffect, useLayoutEffect, useRef, useState, useContext, memo } from "react"
import React, { useEffect, useLayoutEffect, useRef, useState, useContext, memo, } from "react"
import { toast } from 'react-toastify';
import Markdown from 'react-markdown'
import theme from '../theme.jsx';
import {getTheme} from '../theme.jsx';
import ReactJson from "react-json-view-ssr";
import { isMobile } from "react-device-detect";
import { BrowserView, MobileView } from "react-device-detect";
@@ -28,7 +28,8 @@ import {
DialogTitle,
Box,
DialogContent,
InputAdornment
InputAdornment,
CircularProgress
} from "@mui/material";
import {
Link as LinkIcon,
@@ -171,6 +172,9 @@ export const Img = (props) => {
var height = "auto"
var width = isArticlePage ? 1000 : isFormPage ? 400: 750
const { themeMode } = useContext(Context)
const theme = getTheme(themeMode)
const docsImageStyle = {
border: isFormPage ? null : "1px solid rgba(255,255,255,0.3)",
borderRadius: theme.palette?.borderRadius,
@@ -215,6 +219,8 @@ export const CodeHandler = (props) => {
const propvalue = props.value !== undefined && props.value !== null ? props.value : props.children !== undefined && props.children !== null && props.children.length > 0 ? props.children[0] : ""
const validate = validateJson(propvalue)
const {themeMode } = useContext(Context)
const theme = getTheme(themeMode)
var newprop = propvalue
if (validate.valid === false) {
@@ -293,6 +299,7 @@ const Docs = (defaultprops) => {
let navigate = useNavigate();
const location = useLocation();
const pathname = location.pathname
// Quickfix for react router 5 -> 6
const params = useParams();
//var props = JSON.parse(JSON.stringify(defaultprops))
@@ -301,6 +308,8 @@ const Docs = (defaultprops) => {
props.match.params = params
//console.log("PARAMS: ", params)
const { themeMode } = useContext(Context)
const theme = getTheme(themeMode)
const [mobile, setMobile] = useState(serverMobile === true || isMobile === true ? true : false);
const [data, setData] = useState("");
@@ -326,9 +335,37 @@ const Docs = (defaultprops) => {
const [sidebarOpen, setSidebarOpen] = useState(false);
const [activeSubItem, setActiveSubItem] = useState(false);
const headingElementsRef = useRef({})
const [hasRedirected, setHasRedirected] = useState(false)
var isArticlePage = window.location.pathname.includes("/articles/") || window.location.pathname === "/articles" ? true : false;
const searchFieldRef = useRef(null);
const handleDocRedirectForPartners = () => {
if (hasRedirected) return;
if (
userdata &&
userdata?.org_status?.includes("integration_partner") &&
userdata?.active_org?.branding?.documentation_link?.length > 0
) {
const docLink = userdata?.active_org?.branding?.documentation_link;
if (docLink && docLink !== "") {
setHasRedirected(true);
if (docLink.startsWith('http')) {
window.location.replace(docLink);
} else {
navigate(docLink);
}
}
}
};
useEffect(() => {
if (isLoggedIn && isLoaded) {
handleDocRedirectForPartners()
}
}, [isLoggedIn, isLoaded]);
useEffect(() => {
fetchDocList();
@@ -353,6 +390,8 @@ const Docs = (defaultprops) => {
navigate('/docs/apps#app-creation-introduction')
}
}
}, [location]);
useEffect(() => {
@@ -501,19 +540,25 @@ const Docs = (defaultprops) => {
}
}}
PaperProps={{
style: {
color: "white",
minWidth: 750,
sx: {
color: theme.palette.DialogStyle.color,
minWidth: "750px",
minHeight: "180px",
maxHeight: "85vh",
borderRadius: 16,
borderRadius: theme.palette.DialogStyle.borderRadius,
border: "1px solid var(--Container-Stroke, #494949)",
background: "var(--Container, #000000)",
background: theme.palette.DialogStyle.backgroundColor,
boxShadow: "0px 16px 24px 8px rgba(0, 0, 0, 0.25)",
position: "fixed",
top: "70px",
left: "50%",
transform: "translateX(-50%)",
'& .MuiDialogContent-root': {
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
},
'& .MuiDialogTitle-root': {
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
},
},
}}
sx={{
@@ -526,7 +571,7 @@ const Docs = (defaultprops) => {
<Box sx={{ display: "flex", justifyContent: "space-between", alignItems: "center", px: 2, pr: 3, pt: 2 }}>
<DialogTitle
sx={{
color: "var(--Paragraph-text, #C8C8C8)",
color: theme.palette.DialogStyle.color,
p: 0,
m: 0,
ml: 1.5,
@@ -594,7 +639,7 @@ const Docs = (defaultprops) => {
}
const SidebarPaperStyle = {
backgroundColor: isArticlePage ? "transparent" : "rgb(26,26,26)",
backgroundColor: isArticlePage ? "transparent" : theme.palette.backgroundColor,
border: isArticlePage ? "none" : undefined,
borderRadius: isArticlePage ? "none" : undefined,
boxShadow: isArticlePage ? "none" : undefined,
@@ -663,9 +708,9 @@ const Docs = (defaultprops) => {
extraInfo = (
<div
style={{
backgroundColor: theme.palette.inputColor,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
padding: 15,
borderRadius: theme.palette?.borderRadius,
borderRadius: theme.palette?.textFieldStyle.borderRadius,
marginBottom: isArticlePage ? 25 : 30,
display: "flex",
}}
@@ -679,7 +724,7 @@ const Docs = (defaultprops) => {
href={selectedMeta.link}
style={{ textDecoration: "none", color: "#f85a3e" }}
>
<Button style={{ color: "white", }} variant="outlined" color="secondary">
<Button variant="outlined" color="secondary">
<EditIcon /> &nbsp;&nbsp;Edit
</Button>
</a>
@@ -788,7 +833,7 @@ const Docs = (defaultprops) => {
paddingLeft: "0.3em", rotate: "-30deg",
paddingTop: "0.9em", display: props.level === 1 ? "none" : "block",
}}>
<LinkIcon />
<LinkIcon style={{color: theme.palette.textColor}} />
</Link>
</div>
{isArticlePage ? (userdata?.support ? extraInfo : "") : extraInfo}
@@ -1028,13 +1073,12 @@ const Docs = (defaultprops) => {
}
const markdownStyle = {
color: "rgba(255, 255, 255, 0.90)",
color: theme.palette.textColor,
overflow: "hidden",
paddingBottom: 100,
margin: "auto",
maxWidth: "100%",
minWidth: "100%",
overflow: "hidden",
fontSize: isMobile ? "1.3rem" : "1.1rem",
};
@@ -1188,6 +1232,7 @@ const Docs = (defaultprops) => {
const activeHrefStyleToc2 = {
...hrefStyleToc2,
color: "#f86a3e",
fontFamily: theme.typography.fontFamily,
};
const activeListItemStyle = {
@@ -1228,9 +1273,10 @@ const Docs = (defaultprops) => {
</InputAdornment>
),
style: {
backgroundColor: "#212121",
backgroundColor: theme.palette.platformColor,
borderRadius: 4,
color: "white",
fontSize: 18,
color: theme.palette.textColor,
},
}}
style={{
@@ -1290,16 +1336,17 @@ const Docs = (defaultprops) => {
>
<ListItemText
style={{
color: itemMatching ? "#f86a3e" : "inherit",
color: itemMatching ? "#f86a3e" : theme.palette.textColor,
flex: 1,
}}
primary={
<Typography
variant="body1"
style={{
whiteSpace: "nowrap",
overflow: "hidden",
color : "inherit",
textOverflow: "ellipsis",
fontSize: "18px",
}}
>
{newname}
@@ -1371,7 +1418,7 @@ const Docs = (defaultprops) => {
)}
{tocLines.length > 0 ?
(
<h4 style={{ fontWeight: 600, margin: 0, fontSize: "16px", marginBottom: "8px" }}>Table Of Content</h4>
<h4 style={{ fontWeight: 600, margin: 0, fontSize: "16px", marginBottom: "8px", color: theme.palette.text.primary, }}>Table Of Content</h4>
) : null}
<div
@@ -1393,16 +1440,17 @@ const Docs = (defaultprops) => {
paddingLeft: isArticlePage ? "0" : "8px",
paddingRight: isArticlePage ? "0" : "8px",
lineHeight: "20px",
color: activeId === data.id ? "#f86a3e" : "inherit",
}}
onClick={(e) => {
handleCollapse(index)
setActiveId(data.id)
}}
>
{data.title}
<Typography style={{ fontSize: 14, fontWeight: 400, color: activeId === data.id ? "#f86a3e" : theme.palette.textColor, }}>
{data.title}
</Typography>
{data.items.length > 0 ? (
<>{isopen == index ? <ExpandMoreIcon /> : <KeyboardArrowRightIcon />}</>
<>{isopen === index ? <ExpandMoreIcon style={{color: theme.palette.text.secondary}} /> : <KeyboardArrowRightIcon style={{color: theme.palette.text.secondary}} />}</>
) : null}
</ListItemButton>
{
@@ -1414,7 +1462,7 @@ const Docs = (defaultprops) => {
return (
<ListItemButton
key={i}
style={activeSubItem === d.id ? activeHrefStyleToc2 : hrefStyleToc2}
style={activeSubItem === d.id ? activeHrefStyleToc2 : {...hrefStyleToc2, color: theme.palette.text.secondary, fontFamily: theme.typography.fontFamily,}}
href={`#${d.id}`}
onClick={(e) => {
// e.preventDefault()
@@ -1577,7 +1625,7 @@ const Docs = (defaultprops) => {
// Padding and zIndex etc set because of footer in cloud.
const loadedCheck = (
<DocsWrapper isLoggedIn={isLoggedIn} isLoaded={isLoaded}>
<DocsWrapper isLoggedIn={isLoggedIn} isLoaded={isLoaded} userdata={userdata}>
<DocsContent postDataBrowser={postDataBrowser} postDataMobile={postDataMobile}/>
</DocsWrapper>
);
@@ -1589,6 +1637,8 @@ return <div>{loadedCheck}</div>;
export default Docs;
const DocsContent = memo(({postDataBrowser, postDataMobile}) => {
const { themeMode } = useContext(Context);
const theme = getTheme(themeMode);
return(
<div style={{fontFamily: theme?.palette?.fontFamily}}>
<BrowserView>{postDataBrowser}</BrowserView>
@@ -1596,10 +1646,22 @@ const DocsContent = memo(({postDataBrowser, postDataMobile}) => {
</div>
)})
const DocsWrapper = memo(({isLoggedIn, isLoaded, children })=>{
const DocsWrapper = memo(({isLoggedIn, isLoaded, children, userdata })=>{
const { leftSideBarOpenByClick, windowWidth } = useContext(Context);
useEffect(() => {
if (isLoaded && isLoggedIn && userdata?.org_status?.includes("integration_partner") && userdata?.active_org?.branding.documentation_link?.length > 0) {
window.location.href = userdata?.active_org?.branding.documentation_link;
}
}, [isLoaded, isLoggedIn, userdata]);
if (isLoaded && isLoggedIn && userdata?.org_status?.includes("integration_partner") && userdata?.active_org?.branding.documentation_link?.length > 0) {
return <CircularProgress style={{position: "absolute", top: "50%", left: "50%", transform: "translate(-50%, -50%)"}} />;
}
return (
<div style={{
marginTop: window.location.pathname.includes("/articles/") ? 50 : undefined,
+1 -1
View File
@@ -297,7 +297,7 @@ const LoginPage = props => {
const [showPassword, setShowPassword] = useState(false)
const [ssoUrl, setSSOUrl] = useState("");
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" || window.location.host === "migration.shuffler.io";
const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" || window.location.host === "migration.shuffler.io" || window.location.host === "sandbox.shuffler.io";
const parsedsearch = serverside === true ? "" : window.location.search
useEffect(() => {
+5 -3
View File
@@ -1,5 +1,5 @@
/* eslint-disable react/no-multi-comp */
import React, {useState, useEffect} from 'react';
import React, {useState, useEffect, useContext} from 'react';
import ReactDOM from "react-dom"
import ReactJson from "react-json-view-ssr";
@@ -48,6 +48,7 @@ import {
Edit as EditIcon,
Polyline as PolylineIcon,
} from '@mui/icons-material';
import { Context } from '../context/ContextApi.jsx';
const hrefStyle = {
color: "white",
@@ -58,6 +59,7 @@ const hrefStyle = {
const RunWorkflow = (defaultprops) => {
const { globalUrl, userdata, isLoaded, isLoggedIn, setIsLoggedIn, setCookie, register, serverside } = defaultprops;
const { supportEmail } = useContext(Context);
let navigate = useNavigate();
const [_, setUpdate] = useState(""); // Used to force rendring, don't remove
const [explorerUi, setExplorerUi] = useState(false)
@@ -471,7 +473,7 @@ const RunWorkflow = (defaultprops) => {
}
if (response.status === 401 || response.status === 403) {
toast("This Form is not available for you to run. If you this is an error, contact support@shuffler.io with a link to this form")
toast(`This Form is not available for you to run. If you this is an error, contact ${supportEmail} with a link to this form`)
}
return response.json()
@@ -627,7 +629,7 @@ const RunWorkflow = (defaultprops) => {
}
if (response.status === 401 || response.status === 403) {
toast("This Form is not available to you. If you think this is an error, please contact support@shuffler.io with the URL.")
toast(`This Form is not available to you. If you think this is an error, please contact ${supportEmail} with the URL.`)
}
return response.json()
+4 -3
View File
@@ -1,13 +1,14 @@
import React, { useState } from "react";
import React, { useContext, useState } from "react";
import { Typography, CircularProgress } from "@mui/material";
import theme from '../theme.jsx';
import { red, } from "../views/AngularWorkflow.jsx"
import { Context } from "../context/ContextApi.jsx";
const SetAuthentication = (props) => {
const { globalUrl } = props;
const { supportEmail } = useContext(Context);
var headers = {
"Content-Type": "application/json",
"Accept": "application/json",
@@ -328,7 +329,7 @@ const SetAuthentication = (props) => {
<b>{failed ? "Failed auth. Error: " : ""}</b> {response}
<br/>
<br/>
{failed ? "If the error persists, try to use fewer scopes. Contact support@shuffler.io if you need further assistance, and include the current URL and a screenshot. You may now close this window." : ""}
{failed ? `If the error persists, try to use fewer scopes. Contact ${supportEmail} if you need further assistance, and include the current URL and a screenshot. You may now close this window.` : ""}
</Typography>
</div>
);
+26 -23
View File
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useContext } from "react";
import { useNavigate } from "react-router-dom";
import theme from '../theme.jsx';
import {getTheme} from '../theme.jsx';
import {
Grid,
Typography,
@@ -15,6 +15,7 @@ import {
//import { useAlert
import { ToastContainer, toast } from "react-toastify";
import "../codeeditor-index.css";
import { Context } from "../context/ContextApi.jsx";
import { FileCopy, Visibility, VisibilityOff } from "@mui/icons-material";
import IconButton from "@mui/material/IconButton";
@@ -40,6 +41,8 @@ const Settings = (props) => {
const [MFARequired, setMFARequired] = React.useState(false);
const [image2FA, setImage2FA] = React.useState("");
const [value2FA, setValue2FA] = React.useState("");
const {themeMode, supportEmail} = useContext(Context);
const theme = getTheme(themeMode);
// const [file, setFile] = React.useState("");
// const [fileBase64, setFileBase64] = React.useState(
@@ -83,7 +86,7 @@ const Settings = (props) => {
const boxStyle = {
flex: "1",
color: "white",
color: theme.palette.text.primary,
position: "relative",
marginLeft: "10px",
marginRight: "10px",
@@ -213,8 +216,8 @@ const Settings = (props) => {
left: "50%",
transform: "translate(-50%, -50%)",
zIndex: "9999",
backgroundColor: "#1a1a1a",
color: "white",
backgroundColor: theme.palette.backgroundColor,
color: theme.palette.text.primary,
padding: 20,
borderRadius: 5,
boxShadow: "0 0 10px rgba(0, 0, 0, 0.3)",
@@ -223,7 +226,7 @@ const Settings = (props) => {
};
const closeIconButtonStyling = {
color: "white",
color: theme.palette.text.primary,
border: "none",
backgroundColor: "transparent",
marginLeft: "90%",
@@ -243,7 +246,7 @@ const Settings = (props) => {
width: "100%",
fontSize: 16,
backgroundColor: disabled ? "gray" : "red",
color: "white",
color: theme.palette.text.primary,
cursor: disabled === false && "pointer",
};
const checkboxStyle = {
@@ -381,7 +384,7 @@ const Settings = (props) => {
className="ais-RefinementList-checkbox"
onClick={handleCheckBoxEvent}
/>
<label style={{ fontSize: "16px", color: "white" }}>
<label style={{ fontSize: "16px", color: theme.palette.text.primary }}>
I have read the above information and I agree to it completely
</label>
</div>
@@ -410,7 +413,7 @@ const Settings = (props) => {
endAdornment: (
<IconButton
onClick={handlePasswordVisibility}
style={{color:"white"}}
style={{color:theme.palette.text.primary}}
>
{showPassword ? <VisibilityOff /> : <Visibility />}
</IconButton>
@@ -704,7 +707,7 @@ const Settings = (props) => {
InputProps={{
style: {
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
}}
color="primary"
@@ -732,7 +735,7 @@ const Settings = (props) => {
InputProps={{
style: {
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
}}
color="primary"
@@ -757,7 +760,7 @@ const Settings = (props) => {
InputProps={{
style: {
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
}}
color="primary"
@@ -788,7 +791,7 @@ const Settings = (props) => {
InputProps={{
style: {
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
}}
color="primary"
@@ -806,7 +809,7 @@ const Settings = (props) => {
InputProps={{
style: {
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
endAdornment: (
<>
@@ -857,7 +860,7 @@ const Settings = (props) => {
InputProps={{
style:{
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
}}
color="primary"
@@ -877,7 +880,7 @@ const Settings = (props) => {
InputProps={{
style:{
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
}}
color="primary"
@@ -899,7 +902,7 @@ const Settings = (props) => {
InputProps={{
style:{
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
}}
color="primary"
@@ -919,7 +922,7 @@ const Settings = (props) => {
InputProps={{
style:{
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
}}
color="primary"
@@ -954,7 +957,7 @@ const Settings = (props) => {
InputProps={{
style: {
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
}}
color="primary"
@@ -979,7 +982,7 @@ const Settings = (props) => {
InputProps={{
style: {
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
}}
color="primary"
@@ -1002,7 +1005,7 @@ const Settings = (props) => {
InputProps={{
style: {
height: "50px",
color: "white",
color: theme.palette.text.primary,
},
}}
color="primary"
@@ -1046,7 +1049,7 @@ const Settings = (props) => {
{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
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: {supportEmail}
</Typography>
<Button
style={{ height: 40, marginTop: 10 }}
@@ -1133,7 +1136,7 @@ const Settings = (props) => {
height: "60px",
marginTop: "10px",
backgroundColor: "#d52b2b",
color: "white",
color: theme.palette.text.primary,
}}
// variant="contained"
// color="primary"
+4 -3
View File
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react";
import React, { useState, useEffect, useContext } from "react";
import ReactGA from "react-ga4";
import {
@@ -15,10 +15,11 @@ import { ToastContainer, toast } from "react-toastify"
import AuthenticationOauth2 from "../components/Oauth2Auth.jsx";
import AuthenticationWindow from "../components/AuthenticationWindow.jsx";
import { base64_decode, appCategories } from "../views/AppCreator.jsx";
import { Context } from "../context/ContextApi.jsx";
const SetAuthentication = (props) => {
const { globalUrl, serverside } = props;
const { supportEmail } = useContext(Context);
const [app, setApp] = useState({});
const [isAppLoaded, setIsAppLoaded] = useState(false);
const [loadFail, setLoadFail] = useState("");
@@ -114,7 +115,7 @@ const SetAuthentication = (props) => {
setLoadFail(
<span>
<Typography variant="h4">
Failed to load the app. Please contact your provider or support@shuffler.io if this persists
Failed to load the app. Please contact your provider or {supportEmail} if this persists
</Typography>
<Button
variant="contained"
+17 -13
View File
@@ -9,7 +9,7 @@ import { Context } from "../context/ContextApi.jsx"
import { ToastContainer, toast } from "react-toastify"
import { makeStyles, } from "@mui/styles"
import classNames from "classnames"
import theme from '../theme.jsx'
import {getTheme} from '../theme.jsx'
import {
Autocomplete,
@@ -123,7 +123,8 @@ const ParseUsecaseDesc = (priority, appFramework) => {
const UsecaseListComponent = (props) => {
const { keys, userdata, isCloud, globalUrl, frameworkData, isLoggedIn, workflows, setWorkflows, getFramework, setFrameworkData, } = props
const { themeMode, brandName } = useContext(Context)
const theme = getTheme(themeMode)
const [expandedIndex, setExpandedIndex] = useState(-1);
const [expandedItem, setExpandedItem] = useState(-1);
@@ -199,8 +200,8 @@ const UsecaseListComponent = (props) => {
const LoadingSkeleton = () => (
<div style={{paddingTop: 75, minHeight: 1000, textAlign: "left"}}>
{/* Header skeleton */}
<Skeleton variant="text" width={200} height={40} sx={{ bgcolor: 'grey.800' }} />
<Skeleton variant="text" width="60%" height={24} sx={{ marginTop: 3, bgcolor: 'grey.800' }} />
<Skeleton variant="text" width={200} height={40} />
<Skeleton variant="text" width="60%" height={24} sx={{ marginTop: 3, }} />
{/* Apps selection skeleton */}
<Skeleton variant="text" width={150} height={24} sx={{ marginTop: 5, marginBottom: 10 }} />
@@ -220,7 +221,7 @@ const UsecaseListComponent = (props) => {
variant="circular"
width={40}
height={40}
sx={{ bgcolor: 'grey.800' }}
sx={{ bgcolor: theme.palette.loaderColor}}
/>
))}
</div>
@@ -232,7 +233,7 @@ const UsecaseListComponent = (props) => {
sx={{
marginTop: "10px",
borderRadius: 20,
bgcolor: 'grey.800'
bgcolor: theme.palette.loaderColor
}}
/>
</Paper>
@@ -275,13 +276,13 @@ const UsecaseListComponent = (props) => {
variant="circular"
width={30}
height={30}
sx={{ bgcolor: 'grey.800' }}
sx={{ bgcolor: theme.palette.loaderColor}}
/>
<Skeleton
variant="circular"
width={30}
height={30}
sx={{ bgcolor: 'grey.800' }}
sx={{ bgcolor: theme.palette.loaderColor }}
/>
</div>
{/* Usecase title */}
@@ -289,7 +290,7 @@ const UsecaseListComponent = (props) => {
variant="text"
width="70%"
height={24}
sx={{ bgcolor: 'grey.800' }}
sx={{ bgcolor: theme.palette.loaderColor}}
/>
</Paper>
</Grid>
@@ -596,10 +597,10 @@ const UsecaseListComponent = (props) => {
return (
<div style={{paddingTop: 75, minHeight: 1000, textAlign: "left",}}>
<Typography variant="h4" style={{color: "white", }}>
<b>Usecases</b>
<Typography variant="h4" color="textPrimary" style={{fontWeight: "bold"}}>
Usecases
</Typography>
<Typography variant="body1" style={{marginTop: 25, }}>
<Typography variant="body1" color="textPrimary" style={{marginTop: 25, }}>
Choose a template tailored to your automation requirements, ready for immediate use.
</Typography>
@@ -887,6 +888,9 @@ const Usecases2 = (props) => {
const [keys, setKeys] = useState([])
const [treeKeys, setTreeKeys] = useState([])
const { themeMode, brandName } = useContext(Context)
const theme = getTheme(themeMode)
const [selectedUsecaseCategory, setSelectedUsecaseCategory] = useState("");
const [selectedUsecases, setSelectedUsecases] = useState([]);
const [usecases, setUsecases] = useState([])
@@ -987,7 +991,7 @@ const Usecases2 = (props) => {
}
document.title = "Shuffle - usecases";
document.title = brandName?.length > 0 ? `${brandName} - usecases` : "Shuffle - usecases";
var dayGraphLabels = [60, 80, 65, 130, 80, 105, 90, 130, 70, 115, 60, 130];
var dayGraphData = [60, 80, 65, 130, 80, 105, 90, 130, 70, 115, 60, 130];
+110
View File
@@ -440,6 +440,10 @@ export const collapseField = (field, inputdata) => {
return true
}
if (field.name === "result") {
return false
}
if (field.type === "array") {
return true
}
@@ -454,6 +458,112 @@ export const collapseField = (field, inputdata) => {
return false
}
export const HandleJsonCopy = (base, copy, base_node_name) => {
if (typeof copy.name === "string") {
copy.name = copy.name.replaceAll(" ", "_");
}
//lol
if (typeof base === 'object' || typeof base === 'dict') {
base = JSON.stringify(base)
}
if (base_node_name === "execution_argument" || base_node_name === "Runtime Argument") {
base_node_name = "exec"
}
//console.log("COPY: ", base_node_name, copy);
//var newitem = JSON.parse(base);
var newitem = validateJson(base).result
var to_be_copied = "$" + base_node_name.toLowerCase().replaceAll(" ", "_");
for (let copykey in copy.namespace) {
if (copy.namespace[copykey].includes("Results for")) {
continue;
}
if (newitem !== undefined && newitem !== null) {
newitem = newitem[copy.namespace[copykey]];
if (!isNaN(copy.namespace[copykey])) {
to_be_copied += ".#";
} else {
to_be_copied += "." + copy.namespace[copykey];
}
}
}
if (newitem !== undefined && newitem !== null) {
newitem = newitem[copy.name];
if (!isNaN(copy.name)) {
to_be_copied += ".#";
} else {
to_be_copied += "." + copy.name;
}
}
to_be_copied = to_be_copied.replaceAll(" ", "_");
console.log("COPY: ", to_be_copied);
const elementName = "copy_element_shuffle";
var copyText = document.getElementById(elementName);
if (copyText !== null && copyText !== undefined) {
//console.log("NAVIGATOR: ", navigator);
const clipboard = navigator.clipboard;
if (clipboard === undefined) {
toast("Can only copy over HTTPS (port 3443)");
return;
}
navigator.clipboard.writeText(to_be_copied);
copyText.select();
copyText.setSelectionRange(0, 99999); /* For mobile devices */
/* Copy the text inside the text field */
document.execCommand("copy");
//console.log("COPYING!");
toast("Copied JSON path to clipboard.")
} else {
console.log("Couldn't find element ", elementName);
}
}
export const handleReactJsonClipboard = (copy) => {
const elementName = "copy_element_shuffle";
var copyText = document.getElementById(elementName);
if (copyText !== null && copyText !== undefined) {
if (
copy.namespace !== undefined &&
copy.name !== undefined &&
copy.src !== undefined
) {
copy = copy.src;
}
const clipboard = navigator.clipboard;
if (clipboard === undefined) {
toast("Can only copy over HTTPS (port 3443)");
return;
}
var stringified = JSON.stringify(copy);
if (stringified.startsWith('"') && stringified.endsWith('"')) {
stringified = stringified.substring(1, stringified.length - 1);
}
navigator.clipboard.writeText(stringified);
copyText.select();
copyText.setSelectionRange(0, 99999); /* For mobile devices */
/* Copy the text inside the text field */
document.execCommand("copy");
console.log("COPYING!");
toast("Copied value to clipboard, NOT json path.")
} else {
console.log("Failed to copy from " + elementName + ": ", copyText);
}
}
export const validateJson = (showResult) => {
if (showResult === undefined || showResult === null) {
return {
+148 -119
View File
@@ -2,7 +2,7 @@
import React, { useEffect, useContext, memo, useState, useRef } from "react";
import { useLocation, useNavigate, Link } from "react-router-dom";
import ReactDOM from "react-dom"
import { getTheme } from "../theme.jsx";
// Material UI Icons
import Add from '@mui/icons-material/Add';
import Search from '@mui/icons-material/Search';
@@ -12,7 +12,6 @@ import GridOnIcon from '@mui/icons-material/GridOn';
import ListIcon from '@mui/icons-material/List';
import PublishIcon from '@mui/icons-material/Publish';
import GetAppIcon from '@mui/icons-material/GetApp';
// Material UI & Components
import { makeStyles } from "@mui/styles";
import { Navigate } from "react-router-dom";
@@ -103,7 +102,7 @@ import Dropzone from "../components/Dropzone.jsx";
import { ToastContainer, toast } from "react-toastify"
import { MuiChipsInput } from "mui-chips-input";
import { v4 as uuidv4 } from "uuid";
import theme from "../theme.jsx";
// import theme from "./theme.jsx";
import algoliasearch from 'algoliasearch/lite';
import { InstantSearch, Configure, connectHits, connectSearchBox, connectRefinementList } from 'react-instantsearch-dom';
import { debounce } from "lodash";
@@ -117,38 +116,7 @@ const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e52
const svgSize = 24;
const imagesize = 22;
const useStyles = makeStyles(() => {
return {
datagrid: {
border: 0,
"& .MuiDataGrid-columnsContainer": {
backgroundColor:
theme?.palette?.type === "light" ? "#fafafa" : theme?.palette?.inputColor,
},
"& .MuiDataGrid-iconSeparator": {
display: "none",
},
"& .MuiDataGrid-colCell, .MuiDataGrid-cell": {
borderRight: `1px solid ${theme?.palette?.type === "light" ? "white" : "#303030"
}`,
},
"& .MuiDataGrid-columnsContainer, .MuiDataGrid-cell": {
borderBottom: `1px solid ${theme?.palette?.type === "light" ? "#f0f0f0" : "#303030"
}`,
},
"& .MuiDataGrid-cell": {
color:
theme?.palette?.type === "light" ? "white" : "rgba(255,255,255,0.65)",
},
"& .MuiPaginationItem-root, .MuiTablePagination-actions, .MuiTablePagination-caption":
{
borderRadius: 0,
color: "white",
},
},
}
})
@@ -436,19 +404,7 @@ export const GetIconInfo = (action) => {
return selectedItem;
};
const chipStyle = {
backgroundColor: "#2F2F2F",
marginRight: 5,
paddingLeft: 5,
paddingRight: 5,
height: 35,
cursor: "pointer",
borderColor: "#2F2F2F",
color: "#C8C8C8",
fontSize: "14px",
fontFamily: theme?.typography?.fontFamily,
borderRadius: "17.5px"
};
export const collapseField = (field) => {
if (field === undefined || field === null) {
@@ -626,12 +582,14 @@ export const validateJson = (showResult) => {
//Custom hook for handling styling of the dropzone
const useDropzoneStyles = () => {
const { leftSideBarOpenByClick } = useContext(Context);
const { themeMode, brandColor } = useContext(Context);
const theme = getTheme(themeMode, brandColor);
return {
paddingTop: 70,
// minHeight: 1000,
backgroundColor: "#1A1A1A",
fontFamily: theme?.typography?.fontFamily,
backgroundColor: theme.palette.backgroundColor,
fontFamily: theme.typography?.fontFamily,
// maxWidth: window.innerWidth > 1366 ? 1366 : isMobile ? "100%" : 1200,
paddingLeft: leftSideBarOpenByClick ? 200 : 0,
transition: "padding-left 0.3s ease",
@@ -662,9 +620,59 @@ const Workflows2 = (props) => {
const [isLoadingWorkflow, setIsLoadingWorkflow] = useState(false);
const [isLoadingPublicWorkflow, setIsLoadingPublicWorkflow] = useState(false);
const [view, setView] = useState(localStorage?.getItem("workflowView") || "grid");
const classes = useStyles(theme)
const imgSize = 60;
const { themeMode, brandColor, brandName } = useContext(Context);
const theme = getTheme(themeMode, brandColor);
const chipStyle = {
backgroundColor: theme.palette.chipStyle.backgroundColor,
marginRight: 5,
paddingLeft: 5,
paddingRight: 5,
height: 35,
cursor: "pointer",
borderColor: theme.palette.chipStyle.borderColor,
color: theme.palette.chipStyle.color,
fontSize: "14px",
fontFamily: theme.typography?.fontFamily,
borderRadius: "17.5px"
};
const newStyles = makeStyles(() => {
return {
datagrid: {
border: 0,
"& .MuiDataGrid-columnsContainer": {
backgroundColor:
theme.palette?.type === "light" ? "#fafafa" : theme.palette?.inputColor,
},
"& .MuiDataGrid-iconSeparator": {
display: "none",
},
"& .MuiDataGrid-colCell, .MuiDataGrid-cell": {
borderRight: `1px solid ${theme.palette?.type === "light" ? "white" : "#303030"
}`,
},
"& .MuiDataGrid-columnsContainer, .MuiDataGrid-cell": {
borderBottom: `1px solid ${theme.palette?.type === "light" ? "#f0f0f0" : "#303030"
}`,
},
"& .MuiDataGrid-cell": {
color:
theme.palette?.type === "light" ? "white" : "rgba(255,255,255,0.65)",
},
"& .MuiPaginationItem-root, .MuiTablePagination-actions, .MuiTablePagination-caption":
{
borderRadius: 0,
color: "white",
},
},
}
})
const classes = newStyles(theme);
const referenceUrl = globalUrl + "/api/v1/hooks/";
var upload = "";
@@ -726,7 +734,7 @@ const Workflows2 = (props) => {
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
document.title = "Shuffle - Workflows";
document.title = brandName?.length > 0 ? `${brandName} - Workflows` : "Shuffle - Workflows";
useEffect(() => {
const queryParams = new URLSearchParams(location.search);
@@ -1267,7 +1275,20 @@ const Workflows2 = (props) => {
}
useEffect(() => {
const queryParams = new URLSearchParams(window.location.search);
const paramType = queryParams.get("type");
if (paramType === "sso_login") {
localStorage.removeItem("workflows");
queryParams.delete("type");
const newUrl = window.location.pathname + (queryParams.toString() ? `?${queryParams.toString()}` : '');
window.history.replaceState({}, '', newUrl);
window.location.reload();
}
}, []);
const getAvailableWorkflows = (amount) => {
var storageWorkflows = []
setIsLoadingWorkflow(true)
@@ -1568,7 +1589,7 @@ const Workflows2 = (props) => {
width: "100%",
color: "white",
display: "flex",
fontFamily: theme?.typography?.fontFamily,
fontFamily: theme.typography?.fontFamily,
boxSizing: "border-box",
position: "relative",
borderRadius: "8px",
@@ -1589,7 +1610,7 @@ const Workflows2 = (props) => {
width: 160,
height: 44,
justifyContent: "space-between",
fontFamily: theme?.typography?.fontFamily,
fontFamily: theme.typography?.fontFamily,
};
const exportAllWorkflows = (allWorkflows) => {
@@ -2124,7 +2145,7 @@ const Workflows2 = (props) => {
const WorkflowSkeleton = () => {
return (
<Paper elevation={0} style={{
backgroundColor: "#212121",
backgroundColor: theme.palette.platformColor,
width: "100%",
height: 120,
borderRadius: 8,
@@ -2141,7 +2162,7 @@ const Workflows2 = (props) => {
height={90}
style={{
borderRadius: 6,
backgroundColor: "rgba(255, 255, 255, 0.1)"
backgroundColor: theme.palette.loaderColor,
}}
/>
<div style={{
@@ -2155,19 +2176,19 @@ const Workflows2 = (props) => {
variant="text"
width="40%"
height={24}
style={{ backgroundColor: "rgba(255, 255, 255, 0.1)" }}
style={{ backgroundColor: theme.palette.loaderColor }}
/>
<Skeleton
variant="text"
width="60%"
height={20}
style={{ backgroundColor: "rgba(255, 255, 255, 0.1)" }}
style={{ backgroundColor: theme.palette.loaderColor }}
/>
<Skeleton
variant="text"
width="30%"
height={20}
style={{ backgroundColor: "rgba(255, 255, 255, 0.1)" }}
style={{ backgroundColor: theme.palette.loaderColor }}
/>
</div>
</div>
@@ -2240,6 +2261,11 @@ const Workflows2 = (props) => {
setOpen(false);
setAnchorEl(null);
}}
MenuListProps={{
sx: {
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
}
}}
>
{isDistributed ?
<MenuItem
@@ -2253,7 +2279,7 @@ const Workflows2 = (props) => {
</MenuItem>
: null}
<MenuItem
style={{ backgroundColor: theme.palette.inputColor, color: "white" }}
sx={{ backgroundColor: theme.palette.textFieldStyle.backgroundColor, color: theme.palette.text.primary, "&:hover": {backgroundColor: theme.palette.hoverColor} }}
disabled={isDistributed}
onClick={(event) => {
event.stopPropagation()
@@ -2274,7 +2300,7 @@ const Workflows2 = (props) => {
</MenuItem>
<MenuItem
style={{ backgroundColor: theme.palette.inputColor, color: "white" }}
sx={{ backgroundColor: theme.palette.textFieldStyle.backgroundColor, color: theme.palette.text.primary, "&:hover": {backgroundColor: theme.palette.hoverColor} }}
onClick={(event) => {
window.open(`/forms/${data.id}`, "_blank")
}}
@@ -2287,7 +2313,7 @@ const Workflows2 = (props) => {
<Divider />
<MenuItem
style={{ backgroundColor: theme.palette.inputColor, color: "white" }}
sx={{ backgroundColor: theme.palette.textFieldStyle.backgroundColor, color: theme.palette.text.primary, "&:hover": {backgroundColor: theme.palette.hoverColor} }}
disabled={isDistributed}
onClick={() => {
sideloadWorkflow(data.id, "publish")
@@ -2301,8 +2327,8 @@ const Workflows2 = (props) => {
</MenuItem>
<MenuItem
style={{ backgroundColor: theme.palette.inputColor, color: "white" }}
disabled={isDistributed}
sx={{ backgroundColor: theme.palette.textFieldStyle.backgroundColor, color: theme.palette.text.primary, "&:hover": {backgroundColor: theme.palette.hoverColor} }}
//disabled={isDistributed}
onClick={() => {
sideloadWorkflow(data.id, "export", setOpen)
@@ -2317,7 +2343,7 @@ const Workflows2 = (props) => {
<Divider />
<MenuItem
style={{ backgroundColor: theme.palette.inputColor, color: "white" }}
sx={{ backgroundColor: theme.palette.textFieldStyle.backgroundColor, color: theme.palette.text.primary, "&:hover": {backgroundColor: theme.palette.hoverColor} }}
disabled={isDistributed}
onClick={() => {
duplicateWorkflow(data)
@@ -2330,7 +2356,7 @@ const Workflows2 = (props) => {
</MenuItem>
<MenuItem
style={{ backgroundColor: theme.palette.inputColor, color: "white" }}
sx={{ backgroundColor: theme.palette.textFieldStyle.backgroundColor, color: theme.palette.text.primary, "&:hover": {backgroundColor: theme.palette.hoverColor} }}
onClick={() => {
setDeleteModalOpen(true);
setSelectedWorkflowId(data.id);
@@ -2447,7 +2473,7 @@ const Workflows2 = (props) => {
return (
<div style={{ width: "100%", minWidth: 320, position: "relative", border: highlightIds.includes(data.id) ? "2px solid #f85a3e" : isDistributed || hasSuborgs ? `2px solid ${theme.palette.distributionColor}` : "inherit", borderRadius: theme.palette?.borderRadius, backgroundColor: "#212121", fontFamily: theme?.typography?.fontFamily }}>
<div style={{ width: "100%", minWidth: 320, position: "relative", border: highlightIds.includes(data.id) ? "2px solid #f85a3e" : isDistributed || hasSuborgs ? `2px solid ${theme.palette.distributionColor}` : "inherit", borderRadius: theme.palette?.borderRadius, backgroundColor: "#212121", fontFamily: theme.typography?.fontFamily }}>
<Paper square style={paperAppStyle}>
{selectedCategory !== "" ?
<Tooltip title={`Usecase Category: ${selectedCategory}`} placement="bottom">
@@ -2461,7 +2487,7 @@ const Workflows2 = (props) => {
width: 3,
backgroundColor: boxColor,
borderRadius: "0 100px 0 0",
fontFamily: theme?.typography?.fontFamily,
fontFamily: theme.typography?.fontFamily,
}}
onClick={() => {
addFilter(selectedCategory)
@@ -2472,7 +2498,7 @@ const Workflows2 = (props) => {
<Grid
item
style={{ display: "flex", flexDirection: "column", width: "100%", fontFamily: theme?.typography?.fontFamily }}
style={{ display: "flex", flexDirection: "column", width: "100%", fontFamily: theme.typography?.fontFamily }}
>
<Grid item style={{ display: "flex", maxHeight: 34 }}>
{currTab === 2 ? null :
@@ -2526,7 +2552,7 @@ const Workflows2 = (props) => {
<Typography style={{
color: "rgba(255,255,255,0.9)",
fontSize: "16px",
fontFamily: theme?.typography?.fontFamily,
fontFamily: theme.typography?.fontFamily,
}}>
Edit: {data.name}
</Typography>
@@ -2553,13 +2579,13 @@ const Workflows2 = (props) => {
} placement="right">
<Typography
variant="body1"
style={{
marginBottom: 0,
paddingBottom: 0,
fontSize: 18,
maxHeight: 30,
flex: 10,
fontFamily: theme?.typography?.fontFamily,
fontFamily: theme.typography?.fontFamily,
fontWeight: 500,
}}
>
@@ -2594,7 +2620,7 @@ const Workflows2 = (props) => {
style={{
height: 24,
width: 24,
filter: "brightness(0.6)",
filter: themeMode === "dark" ? "brightness(0.6)" : "brightness(0.9)",
cursor: "pointer",
}}
onClick={() => {
@@ -2751,7 +2777,7 @@ const Workflows2 = (props) => {
overflow: "hidden",
marginTop: 8,
maxHeight: 35,
fontFamily: theme?.typography?.fontFamily,
fontFamily: theme.typography?.fontFamily,
}}
>
{data.tags !== undefined && data.tags !== null
@@ -3395,7 +3421,7 @@ const Workflows2 = (props) => {
);
}
return (
<div style={{ ...gridContainer, backgroundColor: "#212121" }}>
<div style={{ ...gridContainer, backgroundColor: theme.palette.platformColor }}>
<Tooltip title={`New Workflow`} placement="bottom">
<IconButton
style={{ position: "absolute", top: 10, right: 50, zIndex: 1000 }}
@@ -3984,8 +4010,8 @@ const Workflows2 = (props) => {
const iconButtonStyle = {
color: 'white',
backgroundColor: '#212121',
color: theme.palette.text.primary,
backgroundColor: theme.palette.platformColor,
borderRadius: '4px',
padding: "12px 16px",
cursor: 'pointer',
@@ -4085,20 +4111,20 @@ const Workflows2 = (props) => {
maxWidth: "25%",
minWidth: "25%",
height: 47,
backgroundColor: "#212121",
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
}}
InputProps={{
style: {
color: "white",
color: theme.palette.textFieldStyle.color,
height: "100%",
backgroundColor: "#212121",
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
},
placeholder: "Search Workflows",
}}
sx={{
'& .MuiOutlinedInput-root': {
borderRadius: '4px',
backgroundColor: "#212121",
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
},
}}
value={localQuery}
@@ -4140,9 +4166,9 @@ const Workflows2 = (props) => {
maxWidth: "25%",
height: 47,
borderRadius: 4,
backgroundColor: "#212121",
fontFamily: theme?.typography?.fontFamily,
color: "#FFFFFF",
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
fontFamily: theme.typography?.fontFamily,
color: theme.palette.textFieldStyle.color,
}}
MenuProps={{
anchorOrigin: {
@@ -4155,9 +4181,9 @@ const Workflows2 = (props) => {
},
PaperProps: {
style: {
backgroundColor: '#212121',
color: '#FFFFFF',
fontFamily: theme?.typography?.fontFamily,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color,
fontFamily: theme.typography?.fontFamily,
}
}
}}
@@ -4193,7 +4219,7 @@ const Workflows2 = (props) => {
)
}
>
<MenuItem disabled value="" style={{ fontFamily: theme?.typography?.fontFamily, fontSize: 16 }}>
<MenuItem disabled value="" style={{ fontFamily: theme.typography?.fontFamily, fontSize: 16 }}>
All Usecases
</MenuItem>
{items.map((usecase, index) => (
@@ -4206,13 +4232,13 @@ const Workflows2 = (props) => {
'&:hover': {
backgroundColor: '#3A3A3A', // Darker background on hover
},
fontFamily: theme?.typography?.fontFamily,
fontFamily: theme.typography?.fontFamily,
fontSize: 16
}}
>
<Checkbox
checked={currentRefinement.includes(usecase.label)}
style={{ marginRight: 8, color: '#FFFFFF', fontSize: 16 }}
style={{ marginRight: 8, fontSize: 16 }}
/>
{usecase.label} ({usecase.count})
</MenuItem>
@@ -4225,7 +4251,7 @@ const Workflows2 = (props) => {
const tabStyle = {
textTransform: 'none',
marginRight: 20,
fontFamily: theme?.typography?.fontFamily,
fontFamily: theme.typography?.fontFamily,
fontSize: 16,
borderBottom: "5px solid transparent",
minHeight: "48px",
@@ -4233,9 +4259,9 @@ const Workflows2 = (props) => {
}
const tabActive = {
borderBottom: "5px solid #FF8544",
borderBottom: `5px solid ${theme.palette.primary.main}`,
borderRadius: "2px",
color: "#FF8544"
color: theme.palette.primary.main
}
@@ -4258,16 +4284,16 @@ const Workflows2 = (props) => {
maxWidth: isSafari ? "100%" : "70%",
margin: "auto",
}}>
<Typography variant="h4" style={{ marginBottom: 20, paddingLeft: 15, textTransform: 'none', fontFamily: theme?.typography?.fontFamily }}>
<Typography variant="h4" color="textPrimary" style={{ marginBottom: 20, paddingLeft: 15, textTransform: 'none', fontFamily: theme.typography?.fontFamily }}>
{currTab === 0 ? "Org" : currTab === 1 ? "Your" : "Discover"} Workflows
</Typography>
<div style={{ borderBottom: '1px solid gray', marginBottom: 30 }}>
<div style={{ borderBottom: themeMode === "dark" ? "1px solid #808080" : theme.palette.defaultBorder, marginBottom: 30 }}>
<Tabs
value={currTab}
onChange={(event, newTab) => handleTabChange(event, newTab)}
style={{
fontFamily: theme?.typography?.fontFamily,
fontFamily: theme.typography?.fontFamily,
fontSize: 16,
marginBottom: "-2px"
}}
@@ -4327,16 +4353,17 @@ const Workflows2 = (props) => {
minWidth: "25%",
height: 43,
maxHeight: "fit-content",
backgroundColor: "#212121",
zIndex: 1000,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
zIndex: 1000,
color: theme.palette.textFieldStyle.color
}}
disabled={currTab === 2}
InputProps={{
style: {
color: "white",
height: "fit-content",
maxHeight: "fit-content",
backgroundColor: "#212121",
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color
},
placeholder: "Filter Workflows",
// endAdornment: (
@@ -4359,7 +4386,8 @@ const Workflows2 = (props) => {
'& .MuiOutlinedInput-root': {
height: "fit-content",
borderRadius: '4px',
backgroundColor: '#212121',
color: theme.palette.textFieldStyle.color,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
'& fieldset': {
borderColor: 'rgba(255, 255, 255, 0.23)',
},
@@ -4373,10 +4401,12 @@ const Workflows2 = (props) => {
display: 'flex',
flexWrap: 'wrap',
gap: '4px',
fontSize: 18,
padding: '4px 8px',
alignItems: 'center',
height: "fit-content", // Match height
backgroundColor: "#212121",
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
color: theme.palette.textFieldStyle.color
},
// Rest of the styling remains the same...
@@ -4424,8 +4454,9 @@ const Workflows2 = (props) => {
maxWidth: "25%",
height: 47,
borderRadius: 4,
backgroundColor: "#212121",
fontFamily: theme?.typography?.fontFamily
fontSize: 18,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
fontFamily: theme.typography?.fontFamily,
}}
sx={{
'& .MuiOutlinedInput-root': {
@@ -4460,12 +4491,12 @@ const Workflows2 = (props) => {
removeFilter(filters.indexOf(usecase?.name.toLowerCase()))
}
}}
style={{
sx={{
padding: "12px 16px",
borderBottom: index === usecases.length - 2 ? "none" : "1px solid rgba(255,255,255,0.05)",
"&:hover": {
backgroundColor: "rgba(255,255,255,0.1)"
}
},
}}
>
<div style={{
@@ -4479,7 +4510,7 @@ const Workflows2 = (props) => {
style={{
padding: 0,
marginRight: 8,
color: "rgba(255,255,255,0.7)"
color: theme.palette.textFieldStyle.color,
}}
/>
<div style={{
@@ -4491,7 +4522,7 @@ const Workflows2 = (props) => {
<Typography
variant="body1"
style={{
color: "rgba(255,255,255,0.9)",
color: theme.palette.textFieldStyle.color,
fontWeight: selectedCategory.includes(category) ? 500 : 400
}}
>
@@ -4500,8 +4531,8 @@ const Workflows2 = (props) => {
<Typography
variant="body2"
style={{
color: "rgba(255,255,255,0.5)",
backgroundColor: "rgba(255,255,255,0.1)",
color: theme.palette.textFieldStyle.color,
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
padding: "2px 8px",
borderRadius: "12px",
fontSize: "0.75rem"
@@ -4539,7 +4570,7 @@ const Workflows2 = (props) => {
onClick={() => navigate("/workflows/debug")}
disabled={currTab === 2}
>
<QueryStatsIcon style={{ color: currTab === 2 ? "rgba(241, 241, 241, 0.5)" : "#F1F1F1" }} />
<QueryStatsIcon style={{ color: theme.palette.text.primary, opacity: currTab === 2 ? 0.5 : 1 }} />
</IconButton>
</Tooltip>
@@ -4554,8 +4585,8 @@ const Workflows2 = (props) => {
disabled={currTab === 2}
>
{view === "grid" ?
<ListIcon style={{ color: currTab === 2 ? "rgba(255, 255, 255, 0.5)" : "white" }} /> :
<GridOnIcon style={{ color: currTab === 2 ? "rgba(255, 255, 255, 0.5)" : "white" }} />
<ListIcon style={{ color: theme.palette.text.primary, opacity: currTab === 2 ? 0.5 : 1 }} /> :
<GridOnIcon style={{ color: theme.palette.text.primary, opacity: currTab === 2 ? 0.5 : 1 }} />
}
</IconButton>
</Tooltip>
@@ -4568,7 +4599,7 @@ const Workflows2 = (props) => {
>
{submitLoading ?
<CircularProgress color="secondary" /> :
<PublishIcon style={{ color: currTab === 2 ? "rgba(255, 255, 255, 0.5)" : "white" }} />
<PublishIcon style={{ color: theme.palette.text.primary, opacity: currTab === 2 ? 0.5 : 1}} />
}
</IconButton>
</Tooltip>
@@ -4587,7 +4618,7 @@ const Workflows2 = (props) => {
disabled={isCloud || currTab === 2}
onClick={() => exportAllWorkflows(workflows)}
>
<GetAppIcon style={{ color: (isCloud || currTab === 2) ? "rgba(255, 255, 255, 0.5)" : "white" }} />
<GetAppIcon style={{ color: theme.palette.text.primary, opacity: currTab === 2 ? 0.5 : 1}} />
</IconButton>
</Tooltip>
</div>
@@ -4600,13 +4631,11 @@ const Workflows2 = (props) => {
borderRadius: 4,
flex: 0.8,
textTransform: 'none',
backgroundColor: "#FF8544",
color: "#1A1A1A",
fontFamily: theme?.typography?.fontFamily,
fontFamily: theme.typography?.fontFamily,
fontSize: 16,
fontWeight: 500
}}
startIcon={<Add style={{ color: "#1A1A1A" }} />}
startIcon={<Add/>}
>
Create Workflow
</Button>