import React, { memo, useContext, useEffect, useState } from 'react';
import theme from "../theme.jsx";
import {
FormControl,
Card,
Tooltip,
Typography,
Switch,
Divider,
TextField,
Button,
Grid,
List,
ListItem,
ListItemText,
ListItemAvatar,
Avatar,
Dialog,
DialogTitle,
DialogActions,
DialogContent,
Skeleton,
} from "@mui/material";
import {
Edit as EditIcon,
Polyline as PolylineIcon,
CheckCircle as CheckCircleIcon,
Close as CloseIcon,
Apps as AppsIcon,
Business as BusinessIcon,
Flag,
} from "@mui/icons-material";
import { toast } from 'react-toastify';
const TenantsTab = memo((props) => {
const {
globalUrl,
isCloud,
userdata,
selectedOrganization,
setSelectedOrganization,
checkLogin
} = props;
const imageStyle = { width: 50, height: 50 };
// const [selectedOrganization, setSelectedOrganization] = React.useState({});
const [subOrgs, setSubOrgs] = useState([]);
const [cloudSyncApikey, setCloudSyncApikey] = React.useState("");
const [orgName, setOrgName] = React.useState("");
const [orgSyncResponse, setOrgSyncResponse] = React.useState("");
const [loading, setLoading] = React.useState(false);
// const [loginInfo, setLoginInfo] = React.useState("");
const [cloudSyncModalOpen, setCloudSyncModalOpen] = React.useState(false);
const [modalOpen, setModalOpen] = React.useState(false);
const [parentOrg, setParentOrg] = React.useState(null);
const [parentOrgFlag, setParentOrgFlag] = React.useState(null);
const [loadOrgs, setLoadOrgs] = React.useState(true);
const [, forceUpdate] = React.useState();
const itemColor = "black";
useEffect(() => {
if(parentOrg !== null && parentOrgFlag === null) {
let regiontag = "UK";
let regionCode = "gb";
if (parentOrg?.region_url?.length > 0) {
const regionsplit = parentOrg?.region_url.split(".");
if (regionsplit.length > 2 && !regionsplit[0].includes("shuffler")) {
const namesplit = regionsplit[0].split("/");
regiontag = namesplit[namesplit.length - 1];
if (regiontag === "california") {
regiontag = "US";
regionCode = "us";
} else if (regiontag === "frankfurt") {
regiontag = "EU-2";
regionCode = "eu";
} else if (regiontag === "ca") {
regiontag = "CA";
regionCode = "ca";
}
}
setParentOrgFlag(regionCode);
}
}
}, [parentOrg]);
var syncList = [
{
primary: "Workflows",
secondary: "",
active: true,
icon: ,
},
{
primary: "Apps",
secondary: "",
active: true,
icon: ,
},
{
primary: "Organization",
secondary: "",
active: true,
icon: ,
},
];
useEffect(() => {
if (userdata.orgs !== undefined && userdata.orgs !== null && userdata.orgs.length > 0) {
handleGetSubOrgs(userdata.active_org.id);
}
else console.log("error in user data")
}, [userdata]);
const handleGetSubOrgs = (orgId) => {
if (orgId.length === 0) {
toast("Organization ID not defined. Please contact us on https://shuffler.io if this persists logout.");
return;
}
fetch(`${globalUrl}/api/v1/orgs/${orgId}/suborgs`, {
method: "GET",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
})
.then((response) => {
if (!response.ok) {
throw new Error('Failed to fetch sub organizations');
}
return response.json();
})
.then((responseJson) => {
if (responseJson.success === false) {
setLoadOrgs(false)
//toast("Failed getting your org. If this persists, please contact support.");
} else {
const { subOrgs, parentOrg } = responseJson;
setLoadOrgs(false)
setSubOrgs(subOrgs);
setParentOrg(parentOrg);
let regiontag = "UK";
let regionCode = "gb";
if (parentOrg?.region_url?.length > 0) {
const regionsplit = parentOrg?.region_url.split(".");
if (regionsplit.length > 2 && !regionsplit[0].includes("shuffler")) {
const namesplit = regionsplit[0].split("/");
regiontag = namesplit[namesplit.length - 1];
if (regiontag === "california") {
regiontag = "US";
regionCode = "us";
} else if (regiontag === "frankfurt") {
regiontag = "EU-2";
regionCode = "eu";
} else if (regiontag === "ca") {
regiontag = "CA";
regionCode = "ca";
}
}
setParentOrgFlag(regionCode);
}
}
})
.catch((error) => {
console.log("Error getting sub orgs: ", error);
//toast("Error getting sub organizations");
setLoadOrgs(false)
});
};
const GridItem = (props) => {
const [expanded, setExpanded] = React.useState(false);
const [showEdit, setShowEdit] = React.useState(false);
const [newValue, setNewValue] = React.useState(-100);
const primary = props.data.primary;
const secondary = props.data.secondary;
const primaryIcon = props.data.icon;
const secondaryIcon = props.data.active ? (
) : (
);
const submitFeatureEdit = (sync_features) => {
if (!userdata.support) {
console.log(
"User does not have support access and can't edit features",
);
return;
}
sync_features.editing = true;
const data = {
org_id: selectedOrganization.id,
sync_features: sync_features,
};
const url = globalUrl + `/api/v1/orgs/${selectedOrganization.id}`;
fetch(url, {
mode: "cors",
method: "POST",
body: JSON.stringify(data),
credentials: "include",
crossDomain: true,
withCredentials: true,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
})
.then((response) =>
response.json().then((responseJson) => {
if (responseJson["success"] === false) {
toast("Failed updating org: ", responseJson.reason);
} else {
toast("Successfully edited org!");
}
}),
)
.catch((error) => {
toast("Err: " + error.toString());
});
};
const enableFeature = () => {
console.log("Enabling " + primary);
console.log(selectedOrganization.sync_features);
// Check if primary is in sync_features
var tmpprimary = primary.replaceAll(" ", "_");
if (!(tmpprimary in selectedOrganization.sync_features)) {
console.log("Primary not in sync_features: " + tmpprimary);
return;
}
if (props.data.active) {
selectedOrganization.sync_features[tmpprimary].active = false;
} else {
selectedOrganization.sync_features[tmpprimary].active = true;
}
// setSelectedOrganization(selectedOrganization);
forceUpdate(Math.random());
submitFeatureEdit(selectedOrganization.sync_features);
};
const submitEdit = (e) => {
e.preventDefault();
e.stopPropagation();
// Check if primary is in sync_features
var tmpprimary = primary.replaceAll(" ", "_");
if (!(tmpprimary in selectedOrganization.sync_features)) {
console.log("Primary not in sync_features: " + tmpprimary);
return;
}
// Make it into a number
var tmp = parseInt(newValue);
if (isNaN(tmp)) {
console.log("Not a number: " + newValue);
return;
}
selectedOrganization.sync_features[tmpprimary].limit = tmp;
// setSelectedOrganization(selectedOrganization);
forceUpdate(Math.random());
submitFeatureEdit(selectedOrganization.sync_features);
};
return (
{
setExpanded(!expanded);
}}
>
{primaryIcon}
{isCloud && userdata.support === true ? (
{
e.preventDefault();
e.stopPropagation();
if (showEdit) {
setShowEdit(false);
return;
}
console.log("Edit");
setShowEdit(true);
}}
/>
) : null}
{
if (!isCloud || userdata.support !== true) {
return;
}
e.preventDefault();
e.stopPropagation();
enableFeature();
}}
>
{secondaryIcon}
{expanded ? (
Usage:
{props.data.limit === 0 ? (
"Unlimited"
) : (
{props.data.usage} /{" "}
{props.data.limit === "" ? "Unlimited" : props.data.limit}
)}
{/*
Data sharing: {props.data.data_collection}
*/}
Description: {secondary}
) : null}
{showEdit ? (
{
console.log("Submit");
submitEdit(e);
}}
>
{
setNewValue(event.target.value);
}}
/>
{
console.log("Submit 2");
submitEdit(e);
}}
>
Submit
) : null}
);
};
const enableCloudSync = (apikey, organization, disableSync) => {
setOrgSyncResponse("");
const data = {
apikey: apikey,
organization: organization,
disable: disableSync,
};
const url = globalUrl + "/api/v1/cloud/setup";
fetch(url, {
mode: "cors",
method: "POST",
body: JSON.stringify(data),
credentials: "include",
crossDomain: true,
withCredentials: true,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
})
.then((response) => {
setLoading(false);
if (response.status === 200) {
console.log("Cloud sync success?");
} else {
console.log("Cloud sync fail?");
}
return response.json();
//setTimeout(() => {
//}, 1000)
})
.then((responseJson) => {
console.log("RESP: ", responseJson);
if (
responseJson.success === false &&
responseJson.reason !== undefined
) {
setOrgSyncResponse(responseJson.reason);
toast("Failed to handle sync: " + responseJson.reason);
} else if (!responseJson.success) {
toast("Failed to handle sync.");
} else {
// getOrgs();
if (disableSync) {
toast("Successfully disabled sync!");
setOrgSyncResponse("Successfully disabled syncronization");
} else {
toast("Cloud Syncronization successfully set up!");
setOrgSyncResponse(
"Successfully started syncronization. Cloud features you now have access to can be seen below.",
);
}
selectedOrganization.cloud_sync = !selectedOrganization.cloud_sync;
// setSelectedOrganization(selectedOrganization);
setCloudSyncApikey("");
// handleGetOrg(userdata.active_org.id);
}
})
.catch((error) => {
setLoading(false);
toast("Err: " + error.toString());
});
};
const createSubOrg = (currentOrgId, name) => {
const data = { name: name, org_id: currentOrgId };
console.log(data);
const url = globalUrl + `/api/v1/orgs/${currentOrgId}/create_sub_org`;
fetch(url, {
mode: "cors",
method: "POST",
body: JSON.stringify(data),
credentials: "include",
crossDomain: true,
withCredentials: true,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
})
.then((response) =>
response.json().then((responseJson) => {
if (responseJson["success"] === false) {
if (responseJson.reason !== undefined) {
toast.error(responseJson.reason, {
autoClose: 5000,
})
} else {
toast("Failed creating suborg. Please try again");
}
} else {
toast("Successfully created suborg. Reloading in 3 seconds!");
// setSelectedUserModalOpen(false);
setTimeout(() => {
window.location.reload();
}, 2500);
}
setOrgName("");
setModalOpen(false);
}),
)
.catch((error) => {
toast("Err: " + error.toString());
});
};
const handleClickChangeOrg = (orgId) => {
// Don't really care about the logout
//name: org.name,
//orgId = "asd"
const data = {
org_id: orgId,
};
localStorage.setItem("globalUrl", "");
localStorage.setItem("getting_started_sidebar", "open");
fetch(`${globalUrl}/api/v1/orgs/${orgId}/change`, {
mode: "cors",
credentials: "include",
crossDomain: true,
method: "POST",
body: JSON.stringify(data),
withCredentials: true,
headers: {
"Content-Type": "application/json; charset=utf-8",
},
})
.then(function (response) {
if (response.status !== 200) {
console.log("Error in response");
} else {
localStorage.setItem("apps", [])
}
return response.json();
})
.then(function (responseJson) {
if (responseJson.success === true) {
if (
responseJson.region_url !== undefined &&
responseJson.region_url !== null &&
responseJson.region_url.length > 0
) {
localStorage.setItem("globalUrl", responseJson.region_url);
//globalUrl = responseJson.region_url
}
checkLogin()
setTimeout(() => {
window.location.reload();
}, 3000);
toast("Successfully changed active organization - refreshing!");
} else {
toast("Failed changing org: " + responseJson.reason);
}
})
.catch((error) => {
console.log("error changing: ", error);
//removeCookie("session_token", {path: "/"})
});
};
const modalView = (
{
setModalOpen(false);
}}
PaperProps={{
sx: {
borderRadius: theme?.palette?.DialogStyle?.borderRadius,
border: theme?.palette?.DialogStyle?.border,
minWidth: "800px",
minHeight: "320px",
fontFamily: theme?.typography?.fontFamily,
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
zIndex: 1000,
'& .MuiDialogContent-root': {
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
},
'& .MuiDialogTitle-root': {
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
},
'& .MuiDialogActions-root': {
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
},
},
}}
>
Add Sub-Organization
Name
{
setOrgName(event.target.value);
}}
/>
{/* {loginInfo} */}
setModalOpen(false)}
color="primary"
>
Cancel
{
createSubOrg(selectedOrganization.id, orgName);
}}
color="primary"
>
Submit
);
const cloudSyncModal = (
{
setCloudSyncModalOpen(false);
}}
PaperProps={{
sx: {
borderRadius: theme?.palette?.DialogStyle?.borderRadius,
border: theme?.palette?.DialogStyle?.border,
minWidth: "800px",
minHeight: "320px",
fontFamily: theme?.typography?.fontFamily,
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
zIndex: 1000,
'& .MuiDialogContent-root': {
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
},
'& .MuiDialogTitle-root': {
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
},
'& .MuiDialogActions-root': {
backgroundColor: theme?.palette?.DialogStyle?.backgroundColor,
},
},
}}
>
Enable cloud features
What does{" "}
cloud sync
{" "}
do?
{
setCloudSyncApikey(event.target.value);
}}
/>
{
setLoading(true);
enableCloudSync(
cloudSyncApikey,
selectedOrganization,
selectedOrganization.cloud_sync,
);
}}
color="primary"
variant={
selectedOrganization.cloud_sync === true
? "outlined"
: "contained"
}
>
{selectedOrganization.cloud_sync ? "Stop sync" : "Start sync"}
{orgSyncResponse.length > 0 ? (
Error: {orgSyncResponse}
) : null}
{syncList.map((data, index) => {
return ;
})}
* New triggers (userinput, hotmail realtime)
* Execute in the cloud rather than onprem
* Apps can be built in the cloud
* Easily share apps and workflows
* Access to powerful cloud search
);
const textColor = "#9E9E9E !important";
return (
{modalView}
{cloudSyncModal}
Tenants
Create, manage and change to sub-organizations (tenants)! {" "}
{isCloud
? "You can only make a sub organization if you are a customer of shuffle or running a POC of the platform. Please contact support@shuffler.io to try it out."
: ''}
Learn more
{
setModalOpen(true);
}}
>
Add suborganization
Your Parent Organization
{/*
*/}
{isCloud && (
)}
{loadOrgs ? (
[...Array(3)].map((_, rowIndex) => (
{[
{ width: 100, minWidth: 100, maxWidth: 100 },
{ width: 250, minWidth: 50, maxWidth: 250 },
{ width: 400, minWidth: 400, maxWidth: 400 },
{ width: "28%", minWidth: "28%" },
{ width: 400, minWidth: 400, maxWidth: 400 },
].map((style, colIndex) => (
))}
))
) : parentOrg?.id?.length > 0 ? (
}
style={{
width: 100,
minWidth: 100,
maxWidth: 100,
display: "table-cell",
padding: "8px 8px 8px 20px",
textAlign: "center",
}}
/>
{isCloud && (
}
style={{ display: "table-cell", padding: 8, verticalAlign: "middle" }}
/>
)}
{
handleClickChangeOrg(parentOrg?.id);
}}
>
Switch to Parent
}
style={{ display: "table-cell", verticalAlign: "middle" }}
/>
): (
{Array(5).fill().map((_, index) => (
))}
)}
{subOrgs.length > 0 && (
Sub Organizations of the Current Organization ({subOrgs.length})
{/*
*/}
{isCloud && (
)}
{subOrgs.map((data, index) => {
let regiontag = "UK";
let regionCode = "gb";
if (data.region_url?.length > 0) {
const regionsplit = data.region_url.split(".");
if (regionsplit.length > 2 && !regionsplit[0].includes("shuffler")) {
const namesplit = regionsplit[0].split("/");
regiontag = namesplit[namesplit.length - 1];
if (regiontag === "california") {
regiontag = "US";
regionCode = "us";
} else if (regiontag === "frankfurt") {
regiontag = "EU-2";
regionCode = "eu";
} else if (regiontag === "ca") {
regiontag = "CA";
regionCode = "ca";
}
}
}
return (
} style={{ width: 100,
minWidth: 100,
maxWidth: 100,
display: "table-cell",
padding: "8px 8px 8px 20px",
textAlign: "center", }} />
{isCloud && (
}
style={{ display: "table-cell", padding: 8, verticalAlign: "middle" }}
/>
)}
{
handleClickChangeOrg(data.id);
}}
sx={{
boxShadow:"none", textTransform:"capitalize",
fontSize:16,
'&.Mui-disabled': {
backgroundColor: 'rgba(200, 200, 200, 0.5)',
color: '#A9A9A9',
},
}}
>
Change Active Org
}
style={{ display: "table-cell", verticalAlign: "middle" }}
/>
)})}
)}
All Tenants
{/*
*/}
{isCloud && (
)}
{userdata?.orgs?.length <= 0 ? (
[...Array(6)].map((_, rowIndex) => (
{Array(7)
.fill()
.map((_, colIndex) => (
))}
))
) : (
userdata?.orgs?.length > 0 &&
userdata.orgs.map((data, index) => {
let regiontag = "UK";
let regionCode = "gb";
if (data.region_url?.length > 0) {
const regionsplit = data.region_url.split(".");
if (regionsplit.length > 2 && !regionsplit[0].includes("shuffler")) {
const namesplit = regionsplit[0].split("/");
regiontag = namesplit[namesplit.length - 1];
if (regiontag === "california") {
regiontag = "US";
regionCode = "us";
} else if (regiontag === "frankfurt") {
regiontag = "EU-2";
regionCode = "eu";
} else if (regiontag === "ca") {
regiontag = "CA";
regionCode = "ca";
}
}
}
return (
}
style={{
width: 100,
minWidth: 100,
maxWidth: 100,
display: "table-cell",
padding: "8px 8px 8px 20px",
textAlign: "center",
}}
/>
{isCloud ? (
}
style={{
display: "table-cell",
padding: 8,
verticalAlign: "middle",
}}
>
) : null}
{
handleClickChangeOrg(data?.id);
}}
>
Change Active Org
}
style={{
display: "table-cell",
padding: 8,
verticalAlign: "middle",
}}
>
);
})
)}
);
});
export default TenantsTab;