Tons of minor fixes from cloud sync
This commit is contained in:
@@ -4,7 +4,8 @@ import { getTheme } from "../theme.jsx";
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import ReactJson from "react-json-view-ssr";
|
||||
import { GetIconInfo } from "../views/Workflows2.jsx";
|
||||
import { GetIconInfo, } from "../views/Workflows2.jsx";
|
||||
import { validateJson, handleReactJsonClipboard, } from "../views/Workflows.jsx";
|
||||
import { red } from "../views/AngularWorkflow.jsx";
|
||||
import CollectIngestModal from "../components/CollectIngestModal.jsx";
|
||||
import {
|
||||
@@ -76,8 +77,8 @@ import {
|
||||
SmartToy as SmartToyIcon,
|
||||
Settings as SettingsIcon,
|
||||
FilterAlt as FilterAltIcon,
|
||||
CompareArrows as CompareArrowsIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { validateJson, } from "../views/Workflows.jsx";
|
||||
import { Context } from "../context/ContextApi.jsx";
|
||||
|
||||
const scrollStyle1 = {
|
||||
@@ -130,7 +131,6 @@ const CacheView = memo((props) => {
|
||||
})
|
||||
const [_, setUpdate] = useState(Math.random())
|
||||
const [selectedRows, setSelectedRows] = useState([]);
|
||||
|
||||
// Direct category migration from ../components/Files.jsx
|
||||
const [selectAllChecked, setSelectAllChecked] = React.useState(false)
|
||||
const [renderTextBox, setRenderTextBox] = React.useState(false);
|
||||
@@ -139,12 +139,14 @@ const CacheView = memo((props) => {
|
||||
const [selectedFileId, setSelectedFileId] = React.useState("");
|
||||
const [updateToThisCategory, setUpdateToThisCategory] = useState("")
|
||||
const [workflows, setWorkflows] = useState([]);
|
||||
const [apps, setApps] = useState([]);
|
||||
|
||||
const [selectedFiles, setSelectedFiles] = useState([]);
|
||||
const [showAutomationMenu, setShowAutomationMenu] = useState(false);
|
||||
const [showSettingsMenu, setShowSettingsMenu] = useState(false);
|
||||
const [showCollectIngestMenu, setShowCollectIngestMenu] = useState(false);
|
||||
|
||||
var to_be_copied = "";
|
||||
const defaultAutomation = [
|
||||
{
|
||||
"name": "Run workflow",
|
||||
@@ -156,6 +158,42 @@ const CacheView = memo((props) => {
|
||||
"icon": <AirIcon />,
|
||||
"enabled": false,
|
||||
},
|
||||
{
|
||||
"name": "Correlate Categories",
|
||||
"description": "",
|
||||
"type": "singul",
|
||||
"options": [{
|
||||
"key": "datastore_categories",
|
||||
"value": "",
|
||||
}],
|
||||
"icon": <CompareArrowsIcon />,
|
||||
"enabled": false,
|
||||
"disabled": false,
|
||||
},
|
||||
{
|
||||
"name": "Run AI Agent",
|
||||
"description": "",
|
||||
"options": [{
|
||||
"key": "",
|
||||
"value": "",
|
||||
}],
|
||||
"icon": <SmartToyIcon />,
|
||||
"enabled": false,
|
||||
"disabled": true,
|
||||
},
|
||||
{
|
||||
"name": "Send webhook",
|
||||
"description": "Sends the updated value to a specified webhook URL.",
|
||||
"options": [{
|
||||
"key": "webhook_url",
|
||||
"value": "",
|
||||
}],
|
||||
"icon": <WebhookIcon />,
|
||||
"enabled": false,
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"name": "Send message",
|
||||
"description": "",
|
||||
@@ -180,27 +218,6 @@ const CacheView = memo((props) => {
|
||||
"enabled": false,
|
||||
"disabled": true,
|
||||
},
|
||||
{
|
||||
"name": "Run AI Agent",
|
||||
"description": "",
|
||||
"options": [{
|
||||
"key": "",
|
||||
"value": "",
|
||||
}],
|
||||
"icon": <SmartToyIcon />,
|
||||
"enabled": false,
|
||||
"disabled": true,
|
||||
},
|
||||
{
|
||||
"name": "Send webhook",
|
||||
"description": "Sends the updated value to a specified webhook URL.",
|
||||
"options": [{
|
||||
"key": "webhook_url",
|
||||
"value": "",
|
||||
}],
|
||||
"icon": <WebhookIcon />,
|
||||
"enabled": false,
|
||||
},
|
||||
]
|
||||
|
||||
const [categoryAutomations, setCategoryAutomations] = useState(defaultAutomation)
|
||||
@@ -210,6 +227,35 @@ const CacheView = memo((props) => {
|
||||
const theme = getTheme(themeMode, brandColor);
|
||||
const classes = useStyles();
|
||||
|
||||
const getApps = () => {
|
||||
const url = `${globalUrl}/api/v1/apps`
|
||||
fetch(url, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.status !== 200) {
|
||||
console.log("Status not 200 for workflows :O!");
|
||||
return;
|
||||
}
|
||||
|
||||
return response.json();
|
||||
})
|
||||
.then((responseJson) => {
|
||||
if (responseJson?.success === false) {
|
||||
toast.warn("Failed to load apps. Please try again or contact support@shuffler if this persists.")
|
||||
} else {
|
||||
setApps(responseJson)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
toast(error.toString());
|
||||
});
|
||||
}
|
||||
|
||||
const getWorkflows = () => {
|
||||
const url = `${globalUrl}/api/v1/workflows`
|
||||
@@ -251,6 +297,7 @@ const CacheView = memo((props) => {
|
||||
|
||||
useEffect(() => {
|
||||
getWorkflows()
|
||||
getApps()
|
||||
listOrgCache(orgId, selectedCategory, 0, pageSize, page)
|
||||
}, [])
|
||||
|
||||
@@ -322,7 +369,7 @@ const CacheView = memo((props) => {
|
||||
.then((responseJson) => {
|
||||
setCachedLoaded(true);
|
||||
if (responseJson?.success === true) {
|
||||
setListCache(responseJson.keys)
|
||||
setListCache(responseJson.keys);
|
||||
|
||||
if (responseJson.total_amount !== undefined && responseJson.total_amount !== null && responseJson.total_amount > 0) {
|
||||
setTotalAmount(responseJson.total_amount)
|
||||
@@ -563,34 +610,6 @@ const CacheView = memo((props) => {
|
||||
}
|
||||
}
|
||||
|
||||
const handleReactJsonClipboard = (copy) => {
|
||||
const elementName = "copy_element_shuffle";
|
||||
let copyText = document.getElementById(elementName);
|
||||
|
||||
if (copyText) {
|
||||
if (copy.namespace && copy.name && copy.src) {
|
||||
copy = copy.src;
|
||||
}
|
||||
|
||||
const clipboard = navigator.clipboard;
|
||||
if (!clipboard) {
|
||||
toast("Can only copy over HTTPS (port 3443)");
|
||||
return;
|
||||
}
|
||||
|
||||
let stringified = JSON.stringify(copy);
|
||||
if (stringified.startsWith('"') && stringified.endsWith('"')) {
|
||||
stringified = stringified.slice(1, -1);
|
||||
}
|
||||
|
||||
navigator.clipboard.writeText(stringified);
|
||||
toast("Copied value to clipboard, NOT json path.");
|
||||
} else {
|
||||
console.log("Failed to copy from " + elementName + ": ", copyText);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const timestamp = (timestamp) => {
|
||||
if (timestamp === undefined || timestamp === null || timestamp === "") {
|
||||
return null
|
||||
@@ -1096,7 +1115,153 @@ const CacheView = memo((props) => {
|
||||
|
||||
{showOptions && (
|
||||
updatedAutomation.options.map((option, optionIndex) => {
|
||||
if (option?.key === "workflow_id") {
|
||||
if (option?.key === "datastore_categories") {
|
||||
if (datastoreCategories === undefined || datastoreCategories === null || datastoreCategories.length <= 1) {
|
||||
return (
|
||||
<Typography key={optionIndex} style={{ color: theme.palette.text.secondary, marginTop: 10 }}>
|
||||
No categories available. Please add categories in the settings.
|
||||
</Typography>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Autocomplete
|
||||
key={optionIndex}
|
||||
|
||||
multiple
|
||||
label="Choose Datastore Categories"
|
||||
id="datastore_category_search"
|
||||
autoHighlight
|
||||
freeSolo
|
||||
value={datastoreCategories?.filter(c => option?.value.includes(c)) || []}
|
||||
classes={{ inputRoot: classes.inputRoot }}
|
||||
ListboxProps={{
|
||||
style: {
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
color: theme.palette.text.primary,
|
||||
borderRadius: theme.palette.borderRadius,
|
||||
},
|
||||
}}
|
||||
onChange={(event, newValue) => {
|
||||
console.log("New Value: ", newValue)
|
||||
|
||||
option.value = ""
|
||||
for (var i = 0; i < newValue.length; i++) {
|
||||
option.value += newValue[i] + ","
|
||||
}
|
||||
|
||||
if (newValue.length > 0) {
|
||||
updatedAutomation.enabled = true
|
||||
} else {
|
||||
updatedAutomation.enabled = false
|
||||
}
|
||||
|
||||
updatedAutomation.options[optionIndex] = option
|
||||
setUpdatedAutomation(updatedAutomation)
|
||||
setUpdated(true)
|
||||
|
||||
setUpdate(Math.random()) // Force re-render
|
||||
}}
|
||||
|
||||
getOptionLabel={(option) => {
|
||||
if (option === undefined || option === null) {
|
||||
return "No Categories Selected";
|
||||
}
|
||||
|
||||
return option
|
||||
}}
|
||||
options={datastoreCategories}
|
||||
fullWidth
|
||||
style={{
|
||||
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
|
||||
borderRadius: theme.palette.textFieldStyle.borderRadius,
|
||||
color: theme.palette.textFieldStyle.color,
|
||||
height: 35,
|
||||
marginBottom: 40,
|
||||
}}
|
||||
renderOption={(props, data, state) => {
|
||||
const fixedname = data?.charAt(0)?.toUpperCase() + data?.slice(1)?.replaceAll("_", " ")
|
||||
const iconDetails = GetIconInfo({
|
||||
"app_name": fixedname,
|
||||
"name": fixedname,
|
||||
})
|
||||
|
||||
const keyfound = option?.value.includes(data)
|
||||
|
||||
return (
|
||||
<Tooltip arrow placement="left" title={
|
||||
<span style={{}}>
|
||||
{data.image !== undefined && data.image !== null && data.image.length > 0 ?
|
||||
<img src={data.image} alt={data.name} style={{ backgroundColor: theme.palette.surfaceColor, maxHeight: 200, minHeigth: 200, borderRadius: theme.palette?.borderRadius, }} />
|
||||
: null}
|
||||
<Typography>
|
||||
Choose {data}
|
||||
</Typography>
|
||||
</span>
|
||||
} >
|
||||
<MenuItem
|
||||
{...props}
|
||||
style={{
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
}}
|
||||
value={data}
|
||||
>
|
||||
<Typography style={{
|
||||
display: "flex",
|
||||
marginTop: 5,
|
||||
color: keyfound ? red : theme.palette.text.primary,
|
||||
}}>
|
||||
<div style={{marginRight: 10, }}>
|
||||
{iconDetails?.originalIcon && (
|
||||
iconDetails?.originalIcon
|
||||
)}
|
||||
</div>
|
||||
|
||||
{fixedname}
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
</Tooltip>
|
||||
)
|
||||
}}
|
||||
renderInput={(params) => {
|
||||
return (
|
||||
<TextField
|
||||
{...params}
|
||||
style={{
|
||||
backgroundColor: theme.palette.textFieldStyle.backgroundColor,
|
||||
color: theme.palette.textFieldStyle.color,
|
||||
borderRadius: theme.palette.textFieldStyle.borderRadius,
|
||||
height: 35,
|
||||
fontSize: 16,
|
||||
marginTop: "16px"
|
||||
}}
|
||||
InputProps={{
|
||||
...params.InputProps,
|
||||
style: {
|
||||
height: 35,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
padding: "0px 8px",
|
||||
fontSize: 16,
|
||||
borderRadius: 4,
|
||||
},
|
||||
inputProps: {
|
||||
...params.inputProps,
|
||||
style: {
|
||||
height: "100%",
|
||||
boxSizing: "border-box",
|
||||
}
|
||||
|
||||
}
|
||||
}}
|
||||
variant="outlined"
|
||||
placeholder="Select Categories to Correlate"
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
} else if (option?.key === "workflow_id") {
|
||||
return (
|
||||
<Autocomplete
|
||||
key={optionIndex}
|
||||
@@ -1181,8 +1346,7 @@ const CacheView = memo((props) => {
|
||||
{...props}
|
||||
style={{
|
||||
backgroundColor: theme.palette.surfaceColor,
|
||||
color: data.id === option?.value ? "red" : theme.palette.text.primary,
|
||||
borderBottom: data.id === "parent" ? "2px solid rgba(255,255,255,0.5)" : null
|
||||
color: data.id === option?.value ? red : theme.palette.text.primary,
|
||||
}}
|
||||
value={data}
|
||||
>
|
||||
@@ -1327,16 +1491,11 @@ const CacheView = memo((props) => {
|
||||
}}
|
||||
collapsed={true}
|
||||
enableClipboard={(copy) => {
|
||||
// handleReactJsonClipboard(copy);
|
||||
handleReactJsonClipboard(copy)
|
||||
}}
|
||||
collapseStringsAfterLength={theme.palette.jsonCollapseStringsAfterLength}
|
||||
iconStyle={theme.palette.jsonIconStyle}
|
||||
displayDataTypes={false}
|
||||
onSelect={(select) => {
|
||||
|
||||
// HandleJsonCopy(showResult, select, data.action.label);
|
||||
console.log("SELECTED!: ", select);
|
||||
}}
|
||||
name={null}
|
||||
/>
|
||||
:
|
||||
@@ -1419,7 +1578,9 @@ const CacheView = memo((props) => {
|
||||
<IconButton
|
||||
style={{ padding: "6px" }}
|
||||
disabled={data.org_id !== selectedOrganization.id ? true : false}
|
||||
onClick={() => {
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
// Try to make the value JSON indented
|
||||
const valid = validateJson(data.value)
|
||||
var newvalue = data.value
|
||||
@@ -1469,7 +1630,9 @@ const CacheView = memo((props) => {
|
||||
<IconButton
|
||||
style={{ padding: "6px" }}
|
||||
disabled={data.public_authorization === undefined || data.public_authorization === null || data.public_authorization === "" || data.org_id !== selectedOrganization.id ? true : false}
|
||||
onClick={() => {
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
window.open(`${globalUrl}/api/v1/orgs/${orgId}/cache/${data.key}?type=text&authorization=${data.public_authorization}`, "_blank");
|
||||
}}
|
||||
>
|
||||
@@ -1486,7 +1649,9 @@ const CacheView = memo((props) => {
|
||||
<IconButton
|
||||
style={{ padding: "6px" }}
|
||||
disabled={selectedOrganization?.id === undefined ? false : data.org_id !== selectedOrganization.id ? true : false}
|
||||
onClick={() => {
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
deleteEntry(orgId, data.key, data.category)
|
||||
}}
|
||||
>
|
||||
@@ -1609,6 +1774,8 @@ const CacheView = memo((props) => {
|
||||
|
||||
workflows={workflows}
|
||||
getWorkflows={getWorkflows}
|
||||
|
||||
apps={apps}
|
||||
/>
|
||||
|
||||
{cacheDistributionModal}
|
||||
@@ -2067,12 +2234,14 @@ const CacheView = memo((props) => {
|
||||
<DataGrid
|
||||
rows={listCache}
|
||||
columns={columns}
|
||||
|
||||
checkboxSelection
|
||||
disableRowSelectionOnClick
|
||||
rowSelectionModel={selectedRows}
|
||||
onSelectionModelChange={(newSelection) => {
|
||||
setSelectedRows(newSelection);
|
||||
}}
|
||||
onRowSelectionModelChange={(newSelection) => {
|
||||
setSelectedRows(newSelection)
|
||||
setSelectedRows(newSelection);
|
||||
}}
|
||||
keepNonExistentRowsSelected={false}
|
||||
getRowId={(row) => row.key}
|
||||
@@ -2245,6 +2414,11 @@ const CacheView = memo((props) => {
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<TextField
|
||||
id="copy_element_shuffle"
|
||||
value={to_be_copied}
|
||||
style={{ display: "none" }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user