Force Rebuild frontend
This commit is contained in:
@@ -19,17 +19,19 @@ const RuleCard = ({ ruleName, description, file_id, globalUrl, folderDisabled, i
|
|||||||
|
|
||||||
const handleSwitchChange = (event) => {
|
const handleSwitchChange = (event) => {
|
||||||
if (folderDisabled) {
|
if (folderDisabled) {
|
||||||
toast("enable the directory to enable individual rules");
|
toast.warn("Enable the directory to enable individual rules");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isTenzirActive) {
|
if (!isTenzirActive) {
|
||||||
toast("connect to the siem to enable/disable the rule");
|
toast.warn("Connect to the siem first to enable/disable the rule");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newIsEnabled = event.target.checked;
|
const newIsEnabled = event.target.checked;
|
||||||
toggleRule(file_id, !newIsEnabled, globalUrl, () => {
|
toggleRule(file_id, !newIsEnabled, globalUrl, () => {
|
||||||
setIsEnabled(newIsEnabled);
|
setIsEnabled(newIsEnabled);
|
||||||
});
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
const UpdateText = (text) => {
|
const UpdateText = (text) => {
|
||||||
@@ -73,7 +75,6 @@ const RuleCard = ({ ruleName, description, file_id, globalUrl, folderDisabled, i
|
|||||||
color: "white",
|
color: "white",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<h1> HELO</h1>
|
|
||||||
<Typography variant="h6">{ruleName}</Typography>
|
<Typography variant="h6">{ruleName}</Typography>
|
||||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
<IconButton onClick={() => openEditBar(file_id, setOpenCodeEditor, setFileData, globalUrl)}>
|
<IconButton onClick={() => openEditBar(file_id, setOpenCodeEditor, setFileData, globalUrl)}>
|
||||||
@@ -82,7 +83,7 @@ const RuleCard = ({ ruleName, description, file_id, globalUrl, folderDisabled, i
|
|||||||
<Switch
|
<Switch
|
||||||
checked={isEnabled && !folderDisabled}
|
checked={isEnabled && !folderDisabled}
|
||||||
onChange={handleSwitchChange}
|
onChange={handleSwitchChange}
|
||||||
disabled={!isTenzirActive}
|
disabled={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -107,7 +108,7 @@ const RuleCard = ({ ruleName, description, file_id, globalUrl, folderDisabled, i
|
|||||||
|
|
||||||
const toggleRule = (fileId, isCurrentlyEnabled, globalUrl, callback) => {
|
const toggleRule = (fileId, isCurrentlyEnabled, globalUrl, callback) => {
|
||||||
const action = isCurrentlyEnabled ? "disable" : "enable";
|
const action = isCurrentlyEnabled ? "disable" : "enable";
|
||||||
const url = `${globalUrl}/api/v1/files/detection/${fileId}/${action}_rule`;
|
const url = `${globalUrl}/api/v1/detections/${fileId}/${action}_rule`;
|
||||||
|
|
||||||
fetch(url, {
|
fetch(url, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
|
|||||||
@@ -456,15 +456,19 @@ const Header = (props) => {
|
|||||||
<LightbulbIcon style={{ marginRight: 5 }} /> Use Cases
|
<LightbulbIcon style={{ marginRight: 5 }} /> Use Cases
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Link>
|
</Link>
|
||||||
<Link to={`/creators/${userdata.public_username}`} style={hrefStyle}>
|
|
||||||
<MenuItem
|
{userdata?.public_username === undefined || userdata?.public_username === null || userdata?.public_username.length <= 0 ? null :
|
||||||
onClick={(event) => {
|
<Link to={`/creators/${userdata.public_username}`} style={hrefStyle}>
|
||||||
handleClose();
|
<MenuItem
|
||||||
}}
|
onClick={(event) => {
|
||||||
>
|
handleClose();
|
||||||
<EmojiObjectsIcon style={{ marginRight: 5 }} /> Creator page
|
}}
|
||||||
</MenuItem>
|
>
|
||||||
</Link>
|
<EmojiObjectsIcon style={{ marginRight: 5 }} /> Creator page
|
||||||
|
</MenuItem>
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
|
||||||
<Divider style={{ marginTop: 10, marginBottom: 10, }} />
|
<Divider style={{ marginTop: 10, marginBottom: 10, }} />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
style={{ color: "white" }}
|
style={{ color: "white" }}
|
||||||
@@ -1155,7 +1159,11 @@ const Header = (props) => {
|
|||||||
userdata.app_execution_usage === undefined ||
|
userdata.app_execution_usage === undefined ||
|
||||||
userdata.app_execution_usage < 1000 ? null : (
|
userdata.app_execution_usage < 1000 ? null : (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={`Amount of App Runs used: ${userdata.app_execution_usage} / ${userdata.app_execution_limit}. When the limit is reached, you can still use Shuffle normally, but your Workflow triggers will stop workflows from starting. Reach out to support@shuffler.io to extend this limit.`}
|
title={
|
||||||
|
<Typography variant="body1" style={{margin: 10, }}>
|
||||||
|
<b>App Runs used</b>: {userdata.app_execution_usage} / {userdata.app_execution_limit}. When the limit is reached, you can still use Shuffle normally, but your Workflow triggers will stop workflows from starting. Reach out to support@shuffler.io to extend this limit. Customer workflows are NOT stopped this way.
|
||||||
|
</Typography>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@@ -4877,7 +4877,7 @@ If you're interested, please let me know a time that works for you, or set up a
|
|||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
href="/docs/organizations#schedules"
|
href="/docs/triggers#schedules"
|
||||||
style={{ textDecoration: "none", color: "#f85a3e" }}
|
style={{ textDecoration: "none", color: "#f85a3e" }}
|
||||||
>
|
>
|
||||||
Learn more
|
Learn more
|
||||||
@@ -4994,9 +4994,20 @@ If you're interested, please let me know a time that works for you, or set up a
|
|||||||
})}
|
})}
|
||||||
</List>
|
</List>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div style={{ marginTop: 20, marginBottom: 20 }}>
|
<div style={{ marginTop: 20, marginBottom: 20 }}>
|
||||||
<h2 style={{ display: "inline" }}>WebHooks</h2>
|
<h2 style={{ display: "inline" }}>Webhooks</h2>
|
||||||
|
<span style={{ marginLeft: 25 }}>
|
||||||
|
Webhooks used in Shuffle workflows.
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
href="/docs/triggers#webhooks"
|
||||||
|
style={{ textDecoration: "none", color: "#f85a3e" }}
|
||||||
|
>
|
||||||
|
Learn more
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Divider
|
<Divider
|
||||||
@@ -5138,8 +5149,8 @@ If you're interested, please let me know a time that works for you, or set up a
|
|||||||
</List>
|
</List>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* <div style={{ marginTop: 20, marginBottom: 20 }}>
|
<div style={{ marginTop: 20, marginBottom: 20 }}>
|
||||||
<h2 style={{ display: "inline" }}>Tenzir Pipelines</h2>
|
<h2 style={{ display: "inline" }}>Pipelines</h2>
|
||||||
<span style={{ marginLeft: 25 }}>
|
<span style={{ marginLeft: 25 }}>
|
||||||
Controls a pipeline to run things.{" "}
|
Controls a pipeline to run things.{" "}
|
||||||
<a
|
<a
|
||||||
@@ -5241,7 +5252,7 @@ If you're interested, please let me know a time that works for you, or set up a
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</List>
|
</List>
|
||||||
)}*/}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
|
|||||||
+52
-54
@@ -334,6 +334,11 @@ const Apps = (props) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("APPVALID: ", appValidation)
|
||||||
|
redirectOpenApi()
|
||||||
|
}, [appValidation])
|
||||||
|
|
||||||
const getUserProfile = (username) => {
|
const getUserProfile = (username) => {
|
||||||
if (serverside === true || !isCloud) {
|
if (serverside === true || !isCloud) {
|
||||||
setCreatorProfile({})
|
setCreatorProfile({})
|
||||||
@@ -1535,27 +1540,34 @@ const Apps = (props) => {
|
|||||||
|
|
||||||
const makeFancy = text?.includes("Generate")
|
const makeFancy = text?.includes("Generate")
|
||||||
|
|
||||||
|
var parsedStyle = {
|
||||||
|
flex: 1,
|
||||||
|
padding: 15,
|
||||||
|
margin: 10,
|
||||||
|
paddingTop: 25,
|
||||||
|
backgroundColor: hover ? theme.palette.surfaceColor : "transparent",
|
||||||
|
cursor: hover ? "pointer" : "default",
|
||||||
|
textAlign: "center",
|
||||||
|
minHeight: 150,
|
||||||
|
maxHeight: 150,
|
||||||
|
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!makeFancy) {
|
||||||
|
parsedStyle.border = hover ? "1px solid #f85a3e" : "1px solid rgba(255,255,255,0.3)"
|
||||||
|
} else {
|
||||||
|
parsedStyle.border = "1px solid transparent"
|
||||||
|
parsedStyle.borderImage = "linear-gradient(45deg, red, orange, yellow, green, blue, indigo, violet) 1"
|
||||||
|
parsedStyle.borderRadius = 0 // This doesn't work. Try to hover with a high one, and it's weird due to borderImage
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper
|
<Paper
|
||||||
onMouseEnter={() => setHover(true)}
|
onMouseEnter={() => setHover(true)}
|
||||||
onMouseLeave={() => setHover(false)}
|
onMouseLeave={() => setHover(false)}
|
||||||
onClick={func}
|
onClick={func}
|
||||||
style={{
|
style={parsedStyle}
|
||||||
flex: 1,
|
|
||||||
padding: 15,
|
|
||||||
margin: 10,
|
|
||||||
paddingTop: 25,
|
|
||||||
backgroundColor: hover ? theme.palette.surfaceColor : "transparent",
|
|
||||||
border: hover ? "1px solid #f85a3e" : "1px solid rgba(255,255,255,0.3)",
|
|
||||||
cursor: hover ? "pointer" : "default",
|
|
||||||
textAlign: "center",
|
|
||||||
minHeight: 150,
|
|
||||||
maxHeight: 150,
|
|
||||||
|
|
||||||
borderRadius: theme.palette.borderRadius,
|
|
||||||
//borderImage: makeFancy ? "linear-gradient(45deg, red, orange, yellow, green, blue, indigo, violet) 1" : null,
|
|
||||||
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{icon}
|
{icon}
|
||||||
<Typography>
|
<Typography>
|
||||||
@@ -2568,7 +2580,8 @@ const Apps = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//fetch("http://localhost:8080/doc_to_openapi", {
|
//fetch("http://localhost:8080/doc_to_openapi", {
|
||||||
fetch("https://doc-to-openapi-stbuwivzoq-nw.a.run.app/doc_to_openapi", {
|
//fetch("https://doc-to-openapi-stbuwivzoq-nw.a.run.app/doc_to_openapi", {
|
||||||
|
fetch("https://doc-to-openapi-stbuwivzoq-nw.a.run.app/api/v1/doc_to_openapi", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Accept": "application/json",
|
"Accept": "application/json",
|
||||||
@@ -2588,14 +2601,14 @@ const Apps = (props) => {
|
|||||||
})
|
})
|
||||||
.then((responseJson) => {
|
.then((responseJson) => {
|
||||||
// Check if openapi or swagger in string of the json
|
// Check if openapi or swagger in string of the json
|
||||||
|
var parsedtext = responseJson
|
||||||
try {
|
try {
|
||||||
const parsedtext = JSON.stringify(responseJson);
|
parsedtext = JSON.stringify(responseJson);
|
||||||
if (parsedtext.indexOf("openapi") === -1 && parsedtext.indexOf("swagger") === -1) {
|
if (parsedtext.indexOf("openapi") === -1 && parsedtext.indexOf("swagger") === -1) {
|
||||||
setValidation(false);
|
setValidation(false)
|
||||||
setOpenApiError("Error in generation: "+parsedtext);
|
setOpenApiError("Error in generation: "+parsedtext)
|
||||||
|
|
||||||
|
return
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setValidation(false);
|
setValidation(false);
|
||||||
@@ -2604,7 +2617,7 @@ const Apps = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log("Validating response!");
|
console.log("Validating response!");
|
||||||
validateOpenApi(responseJson);
|
validateOpenApi(parsedtext)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
setValidation(false);
|
setValidation(false);
|
||||||
@@ -2716,8 +2729,16 @@ const Apps = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const redirectOpenApi = () => {
|
const redirectOpenApi = () => {
|
||||||
|
if (appValidation === undefined || appValidation === null || appValidation.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
toast.success("Successfully validated OpenAPI. Redirecting to app creation. Remember to save the app to be able to use it.", {
|
||||||
|
// Disable autoclose
|
||||||
|
autoClose: 10000,
|
||||||
|
})
|
||||||
navigate(`/apps/new?id=${appValidation}`)
|
navigate(`/apps/new?id=${appValidation}`)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleGithubValidation = (forceUpdate) => {
|
const handleGithubValidation = (forceUpdate) => {
|
||||||
getSpecificApps(openApi, forceUpdate);
|
getSpecificApps(openApi, forceUpdate);
|
||||||
@@ -2977,10 +2998,12 @@ const Apps = (props) => {
|
|||||||
}}
|
}}
|
||||||
PaperProps={{
|
PaperProps={{
|
||||||
style: {
|
style: {
|
||||||
backgroundColor: surfaceColor,
|
backgroundColor: theme.palette.platformColor,
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
color: "white",
|
color: "white",
|
||||||
minWidth: "800px",
|
minWidth: "800px",
|
||||||
minHeight: "320px",
|
minHeight: "320px",
|
||||||
|
padding: 50,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -3019,7 +3042,7 @@ const Apps = (props) => {
|
|||||||
validateDocumentationUrl();
|
validateDocumentationUrl();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Validate
|
Generate
|
||||||
</Button>
|
</Button>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
@@ -3034,22 +3057,6 @@ const Apps = (props) => {
|
|||||||
placeholder="API Documentation URL"
|
placeholder="API Documentation URL"
|
||||||
fullWidth
|
fullWidth
|
||||||
/>
|
/>
|
||||||
<p>Or upload document with the content (coming soon)</p>
|
|
||||||
<input
|
|
||||||
hidden
|
|
||||||
type="file"
|
|
||||||
ref={upload}
|
|
||||||
multiple={false}
|
|
||||||
onChange={uploadFileDocumentation}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
color="primary"
|
|
||||||
disabled
|
|
||||||
onClick={() => upload.current.click()}
|
|
||||||
>
|
|
||||||
Upload
|
|
||||||
</Button>
|
|
||||||
{errorText}
|
{errorText}
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
@@ -3068,17 +3075,6 @@ const Apps = (props) => {
|
|||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
style={{ borderRadius: "0px" }}
|
|
||||||
disabled={appValidation.length === 0}
|
|
||||||
onClick={() => {
|
|
||||||
redirectOpenApi();
|
|
||||||
}}
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
Continue
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
@@ -3094,10 +3090,12 @@ const Apps = (props) => {
|
|||||||
}}
|
}}
|
||||||
PaperProps={{
|
PaperProps={{
|
||||||
style: {
|
style: {
|
||||||
backgroundColor: surfaceColor,
|
backgroundColor: theme.palette.platformColor,
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
color: "white",
|
color: "white",
|
||||||
minWidth: "800px",
|
minWidth: "800px",
|
||||||
minHeight: "320px",
|
minHeight: "320px",
|
||||||
|
padding: 50,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -0,0 +1,225 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import {
|
||||||
|
Container,
|
||||||
|
Box,
|
||||||
|
TextField,
|
||||||
|
Switch,
|
||||||
|
Typography,
|
||||||
|
Button,
|
||||||
|
CircularProgress,
|
||||||
|
Paper,
|
||||||
|
} from "@mui/material";
|
||||||
|
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import theme from '../theme.jsx';
|
||||||
|
import DetectionRuleCard from "../components/DetectionRuleCard.jsx";
|
||||||
|
|
||||||
|
const handleDirectoryChange = (folderDisabled, setFolderDisabled, globalUrl, isTenzirActive) => {
|
||||||
|
if (!isTenzirActive) {
|
||||||
|
toast.warn("Connect to siem first for global enable/disable to work");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = folderDisabled ? "enable_folder" : "disable_folder";
|
||||||
|
const url = `${globalUrl}/api/v1/detections/${action}`;
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: "PUT",
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) =>
|
||||||
|
response.json().then((responseJson) => {
|
||||||
|
if (responseJson["success"] === true) {
|
||||||
|
if (action === "enable_folder") setFolderDisabled(false);
|
||||||
|
else setFolderDisabled(true);
|
||||||
|
} else {
|
||||||
|
//toast(`failed to disable rule`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.catch((error) => {
|
||||||
|
console.log(`Error in ${action} the rule: `, error);
|
||||||
|
toast(`An error occurred while ${action} the rule`);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const Detection = (props) => {
|
||||||
|
const { globalUrl, ruleInfo, folderDisabled, setFolderDisabled, isTenzirActive, detectionInfo } = props;
|
||||||
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleConnectClick = () => {
|
||||||
|
if (isTenzirActive) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (detectionInfo.category === undefined || detectionInfo.category === null) {
|
||||||
|
toast.warn("Detection category not found. Please try again or contact support@shuffler.io if you think this is a bug.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
|
const url = `${globalUrl}/api/v1/detections/${detectionInfo?.category}/connect`;
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) =>
|
||||||
|
response.json().then((responseJson) => {
|
||||||
|
if (responseJson["success"] === true) {
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoading(false);
|
||||||
|
window.location.reload();
|
||||||
|
}, 15000);
|
||||||
|
} else {
|
||||||
|
if (responseJson.reason !== undefined && responseJson.reason !== null) {
|
||||||
|
toast(responseJson.reason)
|
||||||
|
} else {
|
||||||
|
toast(`Failed to connect to ${detectionInfo?.category}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responseJson.action !== undefined && responseJson.actio !== null && responseJson.action.length > 0) {
|
||||||
|
//if (responseJson.action === "environment_create") {
|
||||||
|
// navigate("/admin?tab=environments")
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.catch((error) => {
|
||||||
|
setLoading(false);
|
||||||
|
console.log(`Error in connecting to ${detectionInfo?.category}: `, error);
|
||||||
|
toast(`An error occurred while connecting to ${detectionInfo?.category}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const filteredRules = ruleInfo === "default" ? [] : ruleInfo?.filter((rule) =>
|
||||||
|
rule.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||||
|
rule.description.toLowerCase().includes(searchQuery.toLowerCase())
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<Paper
|
||||||
|
style={{
|
||||||
|
marginTop: 50,
|
||||||
|
width: "100%",
|
||||||
|
padding: 50,
|
||||||
|
backgroundColor: theme.palette.backgroundColor,
|
||||||
|
borderRadius: theme.palette.borderRadius,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
mb: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="h6" component="div">
|
||||||
|
{detectionInfo?.name} ({filteredRules?.length})
|
||||||
|
</Typography>
|
||||||
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={handleConnectClick}
|
||||||
|
disabled={loading} // Disable the button while loading
|
||||||
|
color={isTenzirActive ? "primary" : "secondary"}
|
||||||
|
style={{ }}
|
||||||
|
>
|
||||||
|
{loading ? <CircularProgress size={24} /> : isTenzirActive ? `Connected to ${detectionInfo?.category}` : `Connect to ${detectionInfo?.category}`}
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
mb: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
label="Search rules"
|
||||||
|
variant="outlined"
|
||||||
|
size="small"
|
||||||
|
sx={{ mr: 2 }}
|
||||||
|
value={searchQuery}
|
||||||
|
onChange={(e) => setSearchQuery(e.target.value)}
|
||||||
|
/>
|
||||||
|
{/* <Button
|
||||||
|
color="primary"
|
||||||
|
variant="contained"
|
||||||
|
onClick={() => uploadRef.current.click()}
|
||||||
|
>
|
||||||
|
<PublishIcon /> Upload sigma file
|
||||||
|
</Button>
|
||||||
|
<input
|
||||||
|
hidden
|
||||||
|
type="file"
|
||||||
|
multiple
|
||||||
|
ref={uploadRef}
|
||||||
|
onChange={(event) => {
|
||||||
|
uploadFiles(event.target.files);
|
||||||
|
}}
|
||||||
|
/> */}
|
||||||
|
</Box>
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||||
|
<Typography variant="body2" sx={{ mr: 1 }}>
|
||||||
|
Global disable/enable
|
||||||
|
</Typography>
|
||||||
|
<Switch
|
||||||
|
checked={!folderDisabled}
|
||||||
|
onChange={() =>
|
||||||
|
handleDirectoryChange(folderDisabled, setFolderDisabled, globalUrl, isTenzirActive)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
height: "500px",
|
||||||
|
width: "100%",
|
||||||
|
overflowY: "auto",
|
||||||
|
p: 1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{filteredRules?.length > 0 ?
|
||||||
|
filteredRules.map((rule, index) => {
|
||||||
|
console.log("RULE CARD: ", rule);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DetectionRuleCard
|
||||||
|
key={index}
|
||||||
|
ruleName={rule.file_name}
|
||||||
|
description={rule.description}
|
||||||
|
|
||||||
|
file_id={rule.file_id}
|
||||||
|
globalUrl={globalUrl}
|
||||||
|
folderDisabled={folderDisabled}
|
||||||
|
isTenzirActive={isTenzirActive}
|
||||||
|
{...rule}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
: null }
|
||||||
|
</Box>
|
||||||
|
</Paper>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Detection;
|
||||||
Reference in New Issue
Block a user