Further cloud syncs for MUlti Tenant distribution
This commit is contained in:
@@ -734,9 +734,9 @@ const EnvironmentTab = memo((props) => {
|
|||||||
<div style={{ height: "100%", maxHeight: 1700, overflowY: "auto", scrollbarColor: '#494949 transparent', scrollbarWidth: 'thin' }}>
|
<div style={{ height: "100%", maxHeight: 1700, overflowY: "auto", scrollbarColor: '#494949 transparent', scrollbarWidth: 'thin' }}>
|
||||||
<div style={{ height: "100%", width: "calc(100% - 20px)", scrollbarColor: '#494949 transparent', scrollbarWidth: 'thin'}}>
|
<div style={{ height: "100%", width: "calc(100% - 20px)", scrollbarColor: '#494949 transparent', scrollbarWidth: 'thin'}}>
|
||||||
<div style={{ marginBottom: 20 }}>
|
<div style={{ marginBottom: 20 }}>
|
||||||
<h2 style={{ marginBottom: 8, marginTop: 0, color: "#ffffff" }}>Locations</h2>
|
<h2 style={{ marginBottom: 8, marginTop: 0, color: "#ffffff" }}>Runtime Locations</h2>
|
||||||
<span style={{ color: textColor }}>
|
<span style={{ color: textColor }}>
|
||||||
Decides which Orborus <b>runtime location</b> to run your workflows in. Previously Environments. <br /> If you have scale problems, talk to our team: support@shuffler.io.
|
Decides which Orborus <b>runtime location</b> to run your workflows in. Previously called Environments. <br /> If you have scale problems, <a href="https://shuffler.io/docs/configuration#high-availability" target="_blank" rel="noopener noreferrer" style={{ color: "#FF8444" }}>check the docs</a> or talk to our team: support@shuffler.io.
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
@@ -1310,7 +1310,7 @@ const EnvironmentTab = memo((props) => {
|
|||||||
<div style={{minWidth: 700, maxWidth: 700, minHeight: 350, display: 'flex', justifyContent: "center", backgroundColor: "transparent", }}>
|
<div style={{minWidth: 700, maxWidth: 700, minHeight: 350, display: 'flex', justifyContent: "center", backgroundColor: "transparent", }}>
|
||||||
<div style={{ paddingTop: 50, paddingBottom: 100, }}>
|
<div style={{ paddingTop: 50, paddingBottom: 100, }}>
|
||||||
<Typography variant="h6">
|
<Typography variant="h6">
|
||||||
Your Self-Hosted Orborus instance
|
Self-Hosted Orborus instance
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" color="textSecondary">
|
<Typography variant="body2" color="textSecondary">
|
||||||
Orborus is the Shuffle queue handler that runs your hybrid workflows and manages pipelines. It can be run in Docker/k8s container on your server or in your cluster. Follow the steps below, and configure as need be.
|
Orborus is the Shuffle queue handler that runs your hybrid workflows and manages pipelines. It can be run in Docker/k8s container on your server or in your cluster. Follow the steps below, and configure as need be.
|
||||||
@@ -1399,9 +1399,23 @@ const EnvironmentTab = memo((props) => {
|
|||||||
>
|
>
|
||||||
{getOrborusCommand(environment)}
|
{getOrborusCommand(environment)}
|
||||||
</code>
|
</code>
|
||||||
<CopyToClipboard
|
|
||||||
text={orborusCommandWrapper()}
|
<div
|
||||||
/>
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
right: 0,
|
||||||
|
top: -10,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
navigator.clipboard.writeText(orborusCommandWrapper())
|
||||||
|
toast("Copied to clipboard")
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FileCopyIcon />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Divider style={{marginTop: 25, marginBottom: 10, }}/>
|
<Divider style={{marginTop: 25, marginBottom: 10, }}/>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useRef, useState, useContext, useCallback, useMemo } from "react";
|
import React, { useEffect, useRef, useState, useContext, useCallback, useMemo, memo } from "react";
|
||||||
import {
|
import {
|
||||||
ExpandLess as ExpandLessIcon,
|
ExpandLess as ExpandLessIcon,
|
||||||
ExpandMore as ExpandMoreIcon,
|
ExpandMore as ExpandMoreIcon,
|
||||||
@@ -754,35 +754,6 @@ useEffect(() => {
|
|||||||
fontSize: 18
|
fontSize: 18
|
||||||
};
|
};
|
||||||
|
|
||||||
const modalView = (
|
|
||||||
<Dialog
|
|
||||||
open={searchBarModalOpen}
|
|
||||||
onClose={() => {
|
|
||||||
setSearchBarModalOpen(false);
|
|
||||||
}}
|
|
||||||
PaperProps={{
|
|
||||||
style: {
|
|
||||||
color: "white",
|
|
||||||
minWidth: 750,
|
|
||||||
height: 785,
|
|
||||||
borderRadius: 16,
|
|
||||||
border: "1px solid var(--Container-Stroke, #494949)",
|
|
||||||
background: "var(--Container, #000000)",
|
|
||||||
boxShadow: "0px 16px 24px 8px rgba(0, 0, 0, 0.25)",
|
|
||||||
zIndex: 13000,
|
|
||||||
paddingTop: 20,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DialogContent className='dialog-content' style={{}}>
|
|
||||||
<SearchBox globalUrl={globalUrl} serverside={serverside} userdata={userdata} />
|
|
||||||
</DialogContent>
|
|
||||||
<Divider style={{overflow: "hidden"}}/>
|
|
||||||
<span style={{display:"flex", width:"100%", height:30}}>
|
|
||||||
</span>
|
|
||||||
</Dialog>
|
|
||||||
);
|
|
||||||
|
|
||||||
const getRegionFlag = (region_url) => {
|
const getRegionFlag = (region_url) => {
|
||||||
var region = "gb";
|
var region = "gb";
|
||||||
const regionMapping = {
|
const regionMapping = {
|
||||||
@@ -821,7 +792,7 @@ useEffect(() => {
|
|||||||
height: "calc((100vh - 32px)*1.2)",
|
height: "calc((100vh - 32px)*1.2)",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{modalView}
|
{searchBarModalOpen ? <ModalView serverside={serverside} userdata={userdata} searchBarModalOpen={searchBarModalOpen} setSearchBarModalOpen={setSearchBarModalOpen} globalUrl={globalUrl} /> : null}
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@@ -1908,3 +1879,37 @@ useEffect(() => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default LeftSideBar;
|
export default LeftSideBar;
|
||||||
|
|
||||||
|
|
||||||
|
const ModalView = memo(({searchBarModalOpen, setSearchBarModalOpen, globalUrl, serverside, userdata}) => {
|
||||||
|
return (
|
||||||
|
(
|
||||||
|
<Dialog
|
||||||
|
open={searchBarModalOpen}
|
||||||
|
onClose={() => {
|
||||||
|
setSearchBarModalOpen(false);
|
||||||
|
}}
|
||||||
|
PaperProps={{
|
||||||
|
style: {
|
||||||
|
color: "white",
|
||||||
|
minWidth: 750,
|
||||||
|
height: 785,
|
||||||
|
borderRadius: 16,
|
||||||
|
border: "1px solid var(--Container-Stroke, #494949)",
|
||||||
|
background: "var(--Container, #000000)",
|
||||||
|
boxShadow: "0px 16px 24px 8px rgba(0, 0, 0, 0.25)",
|
||||||
|
zIndex: 13000,
|
||||||
|
paddingTop: 20,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DialogContent className='dialog-content' style={{}}>
|
||||||
|
<SearchBox globalUrl={globalUrl} serverside={serverside} userdata={userdata} />
|
||||||
|
</DialogContent>
|
||||||
|
<Divider style={{overflow: "hidden"}}/>
|
||||||
|
<span style={{display:"flex", width:"100%", height:30}}>
|
||||||
|
</span>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|||||||
@@ -310,11 +310,13 @@ const [orgName, setOrgName] = useState(selectedOrganization?.name);
|
|||||||
if(region === "US") {
|
if(region === "US") {
|
||||||
region = "us-west2"
|
region = "us-west2"
|
||||||
} else if(region === "EU") {
|
} else if(region === "EU") {
|
||||||
region = "europe-west3"
|
region = "europe-west2"
|
||||||
} else if(region === "CA") {
|
} else if(region === "CA") {
|
||||||
region = "northamerica-northeast1"
|
region = "northamerica-northeast1"
|
||||||
} else if(region === "UK") {
|
} else if(region === "UK") {
|
||||||
region = "europe-west2"
|
region = "europe-west2"
|
||||||
|
} else if (region === "EU-2") {
|
||||||
|
region = "europe-west3"
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Link, useNavigate, useLocation } from "react-router-dom";
|
|||||||
import Billing from "../components/Billing.jsx";
|
import Billing from "../components/Billing.jsx";
|
||||||
import Priorities from "../components/Priorities.jsx";
|
import Priorities from "../components/Priorities.jsx";
|
||||||
import Branding from "../components/Branding.jsx";
|
import Branding from "../components/Branding.jsx";
|
||||||
// import AnalyticsTab from '../components/AnalyticsTab.jsx';
|
import AnalyticsTab from '../components/AnalyticsTab.jsx';
|
||||||
import EditOrgTab from '../components/EditOrgTab.jsx';
|
import EditOrgTab from '../components/EditOrgTab.jsx';
|
||||||
import CloudSyncTab from '../components/CloudSyncTab.jsx';
|
import CloudSyncTab from '../components/CloudSyncTab.jsx';
|
||||||
import SSOTab from "../components/ssoTab.jsx"
|
import SSOTab from "../components/ssoTab.jsx"
|
||||||
|
|||||||
@@ -4122,7 +4122,10 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
setCookie("session_token", sessionToken, { path: "/" });
|
setCookie("session_token", sessionToken, { path: "/" });
|
||||||
window.location.href = "https://shuffler.io/workflows/3abdfb21-b40f-4e50-b855-ac0d62f83cbe";
|
window.location.href = "https://shuffler.io/workflows/3abdfb21-b40f-4e50-b855-ac0d62f83cbe";
|
||||||
}, 2000)
|
}, 2000)
|
||||||
}
|
} else if (execFound !== null && response.status >= 300) {
|
||||||
|
toast.info("Failed to load the workflow, but you may still find a list of workflow runs if you have access.")
|
||||||
|
setExecutionModalOpen(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect, useContext, useRef } from "react";
|
import React, { useState, useEffect, useContext } from "react";
|
||||||
|
|
||||||
import theme from "../theme.jsx";
|
import theme from "../theme.jsx";
|
||||||
import ReactGA from "react-ga4";
|
import ReactGA from "react-ga4";
|
||||||
@@ -223,7 +223,6 @@ const AppExplorer = (props) => {
|
|||||||
result: baseResult,
|
result: baseResult,
|
||||||
});
|
});
|
||||||
const [executing, setExecuting] = useState(false);
|
const [executing, setExecuting] = useState(false);
|
||||||
const [activatedApps, setActivatedApps] = useState([]);
|
|
||||||
const [anchorEl, setAnchorEl] = React.useState(null);
|
const [anchorEl, setAnchorEl] = React.useState(null);
|
||||||
const [creatorProfile, setCreatorProfile] = React.useState({});
|
const [creatorProfile, setCreatorProfile] = React.useState({});
|
||||||
const [selectedTab, setSelectedTab] = React.useState(0);
|
const [selectedTab, setSelectedTab] = React.useState(0);
|
||||||
@@ -248,7 +247,6 @@ const AppExplorer = (props) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const isCloud = (window.location.host === "localhost:3002" || window.location.host === "shuffler.io") ? true : (process.env.IS_SSR === "true");
|
const isCloud = (window.location.host === "localhost:3002" || window.location.host === "shuffler.io") ? true : (process.env.IS_SSR === "true");
|
||||||
const isFirstRequestSentRef = useRef(false);
|
|
||||||
|
|
||||||
|
|
||||||
// FIXME: This is used, as useEffect() creates an issue with apps not loading at all
|
// FIXME: This is used, as useEffect() creates an issue with apps not loading at all
|
||||||
@@ -301,15 +299,13 @@ const AppExplorer = (props) => {
|
|||||||
if (serverside) {
|
if (serverside) {
|
||||||
console.log("Not getting app because serverside.");
|
console.log("Not getting app because serverside.");
|
||||||
} else {
|
} else {
|
||||||
if (isCloud) {
|
if (params.appid.length === 32 || params.appid.length === 36) {
|
||||||
if (params.appid.length === 32 || params.appid.length === 36) {
|
handleEditApp(params.appid);
|
||||||
handleEditApp(params.appid);
|
runAlgoliaAppSearch(params.appid, false, true);
|
||||||
runAlgoliaAppSearch(params.appid, false, true);
|
} else {
|
||||||
} else {
|
runAlgoliaAppSearch(params.appid);
|
||||||
runAlgoliaAppSearch(params.appid);
|
|
||||||
|
//handleEditApp()
|
||||||
//handleEditApp()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//parseIncomingOpenapiData(YAML.parse(data))
|
//parseIncomingOpenapiData(YAML.parse(data))
|
||||||
@@ -348,86 +344,6 @@ const AppExplorer = (props) => {
|
|||||||
loadOrganization(userdata.active_org.id)
|
loadOrganization(userdata.active_org.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getApps = () => {
|
|
||||||
// Get apps from localstorage
|
|
||||||
var storageApps = []
|
|
||||||
try {
|
|
||||||
const appstorage = localStorage.getItem("apps")
|
|
||||||
storageApps = JSON.parse(appstorage)
|
|
||||||
if (storageApps === null || storageApps === undefined || storageApps.length === 0) {
|
|
||||||
storageApps = []
|
|
||||||
} else {
|
|
||||||
setActivatedApps(storageApps)
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
//console.log("Failed to get apps from localstorage: ", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fetch(globalUrl + "/api/v1/apps", {
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Accept: "application/json",
|
|
||||||
},
|
|
||||||
credentials: "include",
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.status !== 200) {
|
|
||||||
console.log("Status not 200 for apps :O!");
|
|
||||||
|
|
||||||
//if (isCloud) {
|
|
||||||
// window.location.pathname = "/search";
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then((responseJson) => {
|
|
||||||
var privateapps = [];
|
|
||||||
var valid = [];
|
|
||||||
var invalid = [];
|
|
||||||
for (var key in responseJson) {
|
|
||||||
const app = responseJson[key];
|
|
||||||
|
|
||||||
if (app.categories !== undefined && app.categories !== null && app?.categories.includes("Eradication")) {
|
|
||||||
app.categories = ["EDR"]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (app.is_valid && !(!app.activated && app.generated)) {
|
|
||||||
privateapps.push(app);
|
|
||||||
} else if (
|
|
||||||
app.private_id !== undefined &&
|
|
||||||
app.private_id.length > 0
|
|
||||||
) {
|
|
||||||
valid.push(app);
|
|
||||||
} else {
|
|
||||||
invalid.push(app);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
privateapps.push(...valid);
|
|
||||||
privateapps.push(...invalid);
|
|
||||||
setActivatedApps(privateapps);
|
|
||||||
|
|
||||||
if (params.appid.length === 32 || params.appid.length === 36) {
|
|
||||||
handleEditApp(params.appid, privateapps);
|
|
||||||
runAlgoliaAppSearch(params.appid, false, true, privateapps);
|
|
||||||
} else {
|
|
||||||
runAlgoliaAppSearch(params.appid,true, false, privateapps);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
toast(error.toString());
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (activatedApps?.length === 0 && !isCloud) {
|
|
||||||
getApps();
|
|
||||||
}
|
|
||||||
}, [activatedApps]);
|
|
||||||
|
|
||||||
var activateButton = (
|
var activateButton = (
|
||||||
<Link to={`/apps/new?id=${appId}`} style={{ textDecoration: "none" }}>
|
<Link to={`/apps/new?id=${appId}`} style={{ textDecoration: "none" }}>
|
||||||
<Button
|
<Button
|
||||||
@@ -869,101 +785,14 @@ const AppExplorer = (props) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleEditApp = (appid) => {
|
||||||
|
|
||||||
const HandleActivateApp = (appid) => {
|
|
||||||
if (isFirstRequestSentRef.current) {
|
|
||||||
console.log("Skipping duplicate activation request for app:", appid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
isFirstRequestSentRef.current = true;
|
|
||||||
|
|
||||||
toast.info("App is not activated. Activating it now. Please wait...");
|
|
||||||
|
|
||||||
const baseURL = globalUrl;
|
|
||||||
const url = `${baseURL}/api/v1/apps/${appid}/activate`;
|
|
||||||
|
|
||||||
fetch(url, {
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Accept: "application/json",
|
|
||||||
},
|
|
||||||
credentials: "include",
|
|
||||||
})
|
|
||||||
.then((response) => response.json())
|
|
||||||
.then((responseJson) => {
|
|
||||||
if (!responseJson.success) {
|
|
||||||
toast.error("Failed to activate app. Redirecting to https://shuffler.io. Please wait...");
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location.replace(`https://shuffler.io/apps/${appid}`);
|
|
||||||
}, 2000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.removeItem("apps");
|
|
||||||
getApps();
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log("App activation error: ", error.toString());
|
|
||||||
toast.error("Failed to activate app. Redirecting to https://shuffler.io. Please wait...");
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location.href = `https://shuffler.io/apps/${appid}`;
|
|
||||||
}, 2000);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handleEditApp = (appid, privateapps) => {
|
|
||||||
if (serverside === true) {
|
if (serverside === true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newAppId = appid
|
setAppId(appid)
|
||||||
var appIdFound = false
|
|
||||||
|
|
||||||
if (!isCloud) {
|
|
||||||
// Ensure privateapps is always an array
|
|
||||||
privateapps = Array.isArray(privateapps) ? privateapps : [];
|
|
||||||
|
|
||||||
let found = privateapps.find(app => {
|
|
||||||
return app.id?.trim().toLowerCase() === appid
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
found = privateapps.find(app => {
|
|
||||||
return app.published_id?.trim().toLowerCase() === appid;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (found && found.id) {
|
|
||||||
newAppId = found.id;
|
|
||||||
appIdFound = true
|
|
||||||
} else {
|
|
||||||
if (!isFirstRequestSentRef.current) {
|
|
||||||
HandleActivateApp(appid);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
toast.info("App activated but can't load it for now. Loading app on https://shuffler.io. Please wait...");
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location.href = `https://shuffler.io/apps/${appid}`;
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
setAppId(newAppId)
|
fetch(globalUrl + "/api/v1/apps/" + appid + "/config", {
|
||||||
|
|
||||||
if (isFirstRequestSentRef.current && !isCloud && !appIdFound) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch(`${globalUrl}/api/v1/apps/${newAppId}/config`, {
|
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -997,9 +826,9 @@ const AppExplorer = (props) => {
|
|||||||
) {
|
) {
|
||||||
toast("Failed to get the app")
|
toast("Failed to get the app")
|
||||||
setIsAppLoaded(true)
|
setIsAppLoaded(true)
|
||||||
// setTimeout(() => {
|
setTimeout(() => {
|
||||||
// navigate("/search")
|
navigate("/search")
|
||||||
// }, 1000);
|
}, 1000);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
parseIncomingOpenapiData(responseJson);
|
parseIncomingOpenapiData(responseJson);
|
||||||
@@ -1010,7 +839,6 @@ const AppExplorer = (props) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const parseIncomingAppdata = (data, openapiExists) => {
|
const parseIncomingAppdata = (data, openapiExists) => {
|
||||||
document.title = data.name + " App - OpenAPI and API";
|
document.title = data.name + " App - OpenAPI and API";
|
||||||
|
|
||||||
@@ -1594,7 +1422,7 @@ const AppExplorer = (props) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const runAlgoliaAppSearch = (appname, isOriginal, triggerOnly, privatedapps) => {
|
const runAlgoliaAppSearch = (appname, isOriginal, triggerOnly) => {
|
||||||
const index = searchClient.initIndex("appsearch");
|
const index = searchClient.initIndex("appsearch");
|
||||||
|
|
||||||
console.log("Running appsearch for: ", appname);
|
console.log("Running appsearch for: ", appname);
|
||||||
@@ -1609,7 +1437,7 @@ const AppExplorer = (props) => {
|
|||||||
if (hits !== undefined && hits !== null && hits.length === 1) {
|
if (hits !== undefined && hits !== null && hits.length === 1) {
|
||||||
found = true
|
found = true
|
||||||
if (isOriginal !== false) {
|
if (isOriginal !== false) {
|
||||||
handleEditApp(hits[0].objectID, privatedapps)
|
handleEditApp(hits[0].objectID)
|
||||||
} else {
|
} else {
|
||||||
setSecondaryApp(hits[0])
|
setSecondaryApp(hits[0])
|
||||||
}
|
}
|
||||||
@@ -1644,7 +1472,7 @@ const AppExplorer = (props) => {
|
|||||||
} else {
|
} else {
|
||||||
if (isOriginal !== false) {
|
if (isOriginal !== false) {
|
||||||
found = true
|
found = true
|
||||||
handleEditApp(hit.objectID, privatedapps);
|
handleEditApp(hit.objectID);
|
||||||
} else {
|
} else {
|
||||||
console.log("Found second app: ", hit);
|
console.log("Found second app: ", hit);
|
||||||
hit.name = hit.name.charAt(0).toUpperCase() + hit.name.slice(1);
|
hit.name = hit.name.charAt(0).toUpperCase() + hit.name.slice(1);
|
||||||
@@ -1659,7 +1487,7 @@ const AppExplorer = (props) => {
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
if (hits.length > 0) {
|
if (hits.length > 0) {
|
||||||
if (isOriginal !== false) {
|
if (isOriginal !== false) {
|
||||||
handleEditApp(hits[0].objectID, privatedapps)
|
handleEditApp(hits[0].objectID)
|
||||||
} else {
|
} else {
|
||||||
setSecondaryApp(hits[0]);
|
setSecondaryApp(hits[0]);
|
||||||
}
|
}
|
||||||
@@ -1717,13 +1545,11 @@ const AppExplorer = (props) => {
|
|||||||
setTriggers([])
|
setTriggers([])
|
||||||
//handleEditApp(params.appid)
|
//handleEditApp(params.appid)
|
||||||
|
|
||||||
if (isCloud) {
|
if (params.appid.length === 32 || params.appid.length === 36) {
|
||||||
if (params.appid.length === 32 || params.appid.length === 36) {
|
handleEditApp(params.appid);
|
||||||
handleEditApp(params.appid);
|
runAlgoliaAppSearch(params.appid, false, true);
|
||||||
runAlgoliaAppSearch(params.appid, false, true);
|
} else {
|
||||||
} else {
|
runAlgoliaAppSearch(params.appid);
|
||||||
runAlgoliaAppSearch(params.appid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3216,7 +3042,9 @@ const AppExplorer = (props) => {
|
|||||||
|
|
||||||
const getDownloadUrl = () => {
|
const getDownloadUrl = () => {
|
||||||
|
|
||||||
return `curl -X POST ${globalUrl}/api/v1/download_docker_image \\\n -H \"Authorization: Bearer ${userdata?.apikey}" \\\n -d '{"name": "frikky/shuffle:${app?.name.toLowerCase().replaceAll(' ', '_')}_${app.app_version}"}' \\\n -o image.zip; \\\n docker load -i image.zip`
|
const appEnding = app?.public === true ? app?.app_verison : app?.id
|
||||||
|
|
||||||
|
return `curl -L \ \\\n "${globalUrl}/api/v1/download_docker_image?image=frikky/shuffle:${app?.name.toLowerCase().replaceAll(' ', '_')}_${appEnding}" \\\n -H \"Authorization: Bearer ${userdata?.apikey}" \\\n -o image.zip; \\\n docker load -i image.zip`
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderedActionOptions = deduplicateByName((
|
const renderedActionOptions = deduplicateByName((
|
||||||
@@ -3406,9 +3234,11 @@ const AppExplorer = (props) => {
|
|||||||
Use the App onprem
|
Use the App onprem
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography variant="body2" color="textSecondary" style={{marginTop: 5, }}>
|
<Typography variant="body2" color="textSecondary" style={{marginTop: 5, }}>
|
||||||
Due to using docker containers with private containers, we had to use a custom registry. Use the command below to download the image to the server if it fails to run.
|
Due to using docker containers with privately uploaded containers, we had to use a custom registry. Use the command below to download the image to the server if it fails to run.
|
||||||
|
|
||||||
<b> PS: This does NOT work for ARM containers.</b>
|
It will authenticate and authorize you, before redirecting to a Signed URL on https://storage.googleapis.com
|
||||||
|
|
||||||
|
<b> Now also works for ARM containers!</b>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -4076,10 +3906,6 @@ const AppExplorer = (props) => {
|
|||||||
</Dialog>
|
</Dialog>
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
console.log("App: ", app);
|
|
||||||
|
|
||||||
console.log("userdata is: ", userdata);
|
|
||||||
|
|
||||||
const landingpageDataBrowser = (
|
const landingpageDataBrowser = (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -4218,7 +4044,7 @@ const AppExplorer = (props) => {
|
|||||||
|
|
||||||
{isMobile ? null : (
|
{isMobile ? null : (
|
||||||
<Button
|
<Button
|
||||||
variant={(userdata.active_apps !== undefined && userdata.active_apps !== null && userdata.active_apps.includes(appId) || !isCloud) ? "outlined": "contained"}
|
variant={userdata.active_apps !== undefined && userdata.active_apps !== null && userdata.active_apps.includes(appId) ? "outlined": "contained"}
|
||||||
component="label"
|
component="label"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -4263,7 +4089,7 @@ const AppExplorer = (props) => {
|
|||||||
}}
|
}}
|
||||||
style={{ height: 40, marginTop: 5 }}
|
style={{ height: 40, marginTop: 5 }}
|
||||||
>
|
>
|
||||||
{((userdata.active_apps !== undefined && userdata.active_apps !== null && userdata.active_apps.includes(appId) )|| !isCloud ) ?
|
{userdata.active_apps !== undefined && userdata.active_apps !== null && userdata.active_apps.includes(appId) ?
|
||||||
"Deactivate App"
|
"Deactivate App"
|
||||||
:
|
:
|
||||||
"Activate App"
|
"Activate App"
|
||||||
|
|||||||
Reference in New Issue
Block a user