More header, notifications & debugger fixes
This commit is contained in:
@@ -294,49 +294,26 @@ const Header = (props) => {
|
||||
borderBottom: "1px solid rgba(255,255,255,0.4)",
|
||||
}}
|
||||
>
|
||||
{/*<Typography variant="h6">
|
||||
{new Date(data.updated_at).toISOString()}
|
||||
</Typography >*/}
|
||||
{data.reference_url !== undefined &&
|
||||
data.reference_url !== null &&
|
||||
data.reference_url.length > 0 ? (
|
||||
<Link
|
||||
to={data.reference_url}
|
||||
style={{ color: "#f86a3e", textDecoration: "none" }}
|
||||
>
|
||||
<Typography variant="body1">{data.title}</Typography>
|
||||
</Link>
|
||||
) : (
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
{data.title}
|
||||
</Typography>
|
||||
)}
|
||||
{data.reference_url !== undefined && data.reference_url !== null && data.reference_url.length > 0 ?
|
||||
<Link to={data.reference_url} style={{color: "#f86a3e", textDecoration: "none",}}>
|
||||
<Typography variant="body1">
|
||||
{data.title} ({data.amount})
|
||||
</Typography >
|
||||
</Link>
|
||||
:
|
||||
<Typography variant="body1" color="textSecondary">
|
||||
{data.title}
|
||||
</Typography >
|
||||
}
|
||||
|
||||
{data.image !== undefined &&
|
||||
data.image !== null &&
|
||||
data.image.length > 0 ? (
|
||||
<img
|
||||
alt={data.title}
|
||||
src={data.image}
|
||||
style={{ height: 100, width: 100 }}
|
||||
/>
|
||||
) : null}
|
||||
<Typography variant="body2">{data.description}</Typography>
|
||||
{/*data.tags !== undefined && data.tags !== null && data.tags.length > 0 ?
|
||||
data.tags.map((tag, index) => {
|
||||
return (
|
||||
<Chip
|
||||
key={index}
|
||||
style={chipStyle}
|
||||
label={tag}
|
||||
onClick={() => {
|
||||
}}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
/>
|
||||
)
|
||||
})
|
||||
: null */}
|
||||
{data.image !== undefined && data.image !== null && data.image.length > 0 ?
|
||||
<img alt={data.title} src={data.image} style={{height: 100, width: 100, }} />
|
||||
:
|
||||
null
|
||||
}
|
||||
<Typography variant="body2" style={{marginTop: 10, maxHeight: 200, overflowX: "hidden", overflowY: "auto", }}>
|
||||
{data.description}
|
||||
</Typography >
|
||||
<div style={{ display: "flex" }}>
|
||||
{data.read === false ? (
|
||||
<Button
|
||||
@@ -429,8 +406,9 @@ const Header = (props) => {
|
||||
) : null}
|
||||
</div>
|
||||
<Typography variant="body2">
|
||||
Notifications are made by Shuffle to help you discover issues or
|
||||
improvements.
|
||||
Notifications generated made by Shuffle to help you discover issues or
|
||||
improvements. <a href="/docs/organizations#notifications" target="_blank" rel="noopener noreferrer" style={{color: "#f86a3e", textDecoration: "none", }}>
|
||||
Learn more</a>
|
||||
</Typography>
|
||||
</Paper>
|
||||
{notifications.map((data, index) => {
|
||||
|
||||
@@ -170,6 +170,7 @@ const ParsedAction = (props) => {
|
||||
|
||||
setEditorData,
|
||||
setcodedata,
|
||||
setAiQueryModalOpen,
|
||||
} = props;
|
||||
|
||||
const classes = useStyles();
|
||||
@@ -2913,14 +2914,17 @@ const ParsedAction = (props) => {
|
||||
}}
|
||||
disabled={autoCompleting}
|
||||
onClick={() => {
|
||||
// aiSubmit(aiMsg, undefined, undefined, newSelectedAction)
|
||||
aiSubmit("Fill based on previous values", undefined, undefined, selectedAction)
|
||||
//if (setAiQueryModalOpen !== undefined) {
|
||||
// setAiQueryModalOpen(true)
|
||||
//} else {
|
||||
aiSubmit("Fill based on previous values", undefined, undefined, selectedAction)
|
||||
//}
|
||||
setAutocompleting(true)
|
||||
}}
|
||||
>
|
||||
<Tooltip
|
||||
color="primary"
|
||||
title={"Autocompletes fields. Uses NAME of the action and previous values' results."}
|
||||
title={"Autocomplete fields. Will show a popup so that you can query how you would like to fill it in"}
|
||||
placement="top"
|
||||
>
|
||||
{autoCompleting ?
|
||||
|
||||
@@ -46,11 +46,6 @@ const RuntimeDebugger = (props) => {
|
||||
|
||||
const classes = useStyles();
|
||||
|
||||
//const [workflowId, setWorkflowId] = useState("");
|
||||
//const [status, setStatus] = useState("FINISHED");
|
||||
//const [endTime, setEndTime] = useState(dayjs().subtract(0, 'day'))
|
||||
//const [startTime, setStartTime] = useState(dayjs().subtract(30, 'day'))
|
||||
|
||||
const [workflowId, setWorkflowId] = useState("")
|
||||
const [status, setStatus] = useState("")
|
||||
const [endTime, setEndTime] = useState("")
|
||||
@@ -75,7 +70,7 @@ const RuntimeDebugger = (props) => {
|
||||
|
||||
const submitSearch = (workflowId, status, startTime, endTime, cursor, limit) => {
|
||||
|
||||
setResultRows([])
|
||||
//setResultRows([])
|
||||
setSearchLoading(true)
|
||||
const fetchData = {
|
||||
workflow_id: workflowId,
|
||||
@@ -107,22 +102,29 @@ const RuntimeDebugger = (props) => {
|
||||
//data.runs[key].endTimestamp = data.runs[key].ended_at.toISOString().slice(0, 19).replace('T', ' ')
|
||||
const startTimestamp = new Date(data.runs[key].started_at*1000)
|
||||
data.runs[key].startTimestamp = startTimestamp.toISOString().slice(0, 19).replace('T', ' ')
|
||||
|
||||
const endTimestamp = new Date(data.runs[key].completed_at*1000)
|
||||
data.runs[key].endTimestamp = endTimestamp.toISOString().slice(0, 19).replace('T', ' ')
|
||||
if (data.runs[key].completed_at === 0 || data.runs[key].completed_at === null) {
|
||||
data.runs[key].endTimestamp = ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add 20 empty rows to the end of the resultRows array
|
||||
// This is to make sure that the scrollbar is always visible
|
||||
setResultRows(data.runs)
|
||||
} else {
|
||||
toast("No results found. Keeping old runs")
|
||||
}
|
||||
} else {
|
||||
console.error("Search error: ", data.reason)
|
||||
toast("Failed to search for runs. Please try again.")
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
setSearchLoading(false)
|
||||
console.error("Error:", error);
|
||||
toast("Failed to search for runs. Please try again (2)")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -315,27 +317,63 @@ const RuntimeDebugger = (props) => {
|
||||
)
|
||||
},
|
||||
},
|
||||
{ field: 'startTimestamp', headerName: 'Start time (UTC)', width: 160, },
|
||||
{ field: 'startTimestamp', headerName: 'Start time (UTC)', width: 160,
|
||||
renderCell: (params) => {
|
||||
const hasError = params.row.completed_at-params.row.started_at > 300
|
||||
|
||||
return (
|
||||
<Tooltip title={hasError ? "More than 5 minutes from start to finish" : ""} placement="top">
|
||||
<span style={{cursor: "pointer", backgroundColor: !hasError ? "inherit" : "rgba(244,0,0,0.4)",}} onClick={() => {
|
||||
console.log("Zoom in on end timestamp is this one: ", params.row.endTimestamp)
|
||||
//setEndTimestamp(params.row.endTimestamp)
|
||||
|
||||
// Make a new Date() from params.row.startTimestamp and set it in the endTime
|
||||
const newEndTime = new Date(params.row.startTimestamp)
|
||||
if (newEndTime !== null && newEndTime !== undefined && newEndTime !== "" && newEndTime !== "Invalid Date") {
|
||||
// Translate newEndTime to UTC no matter what timezone we are in. Based it on local()
|
||||
// Plus 1 minute to make sure it comes in
|
||||
setEndTime(dayjs(newEndTime.setMinutes(newEndTime.getMinutes()+1)))
|
||||
|
||||
// Use dayjs to translate it into something useful
|
||||
|
||||
// Remove 5 minutes from it and set startTime
|
||||
//newEndTime.setMinutes(newEndTime.getMinutes()-5)
|
||||
//setStartTime(dayjs(newEndTime))
|
||||
}
|
||||
}}>
|
||||
{params.row.startTimestamp}
|
||||
</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
},
|
||||
{ field: 'endTimestamp', headerName: 'End time (UTC)', width: 160, },
|
||||
{
|
||||
field: 'id',
|
||||
headerName: 'Explore',
|
||||
width: 65,
|
||||
renderCell: (params) => (
|
||||
<Tooltip arrow placement="right" title={
|
||||
<Typography variant="body2" style={{whiteSpace: "pre-line", }}>
|
||||
{params.row.result !== null && params.row.result !== undefined && params.row.result !== "" ?
|
||||
params.row.result
|
||||
:
|
||||
null
|
||||
}
|
||||
</Typography>
|
||||
} >
|
||||
<Link href={`/workflows/${params.row.workflow.id}?execution_id=${params.row.id}`} target="_blank" rel="noopener noreferrer">
|
||||
<OpenInNewIcon fontSize="small" />
|
||||
</Link>
|
||||
</Tooltip>
|
||||
),
|
||||
renderCell: (params) => {
|
||||
const parsedResult = params.row.result === null || params.row.result === undefined || params.row.result === "" ? null : params.row.result
|
||||
const hasError = parsedResult !== null && parsedResult !== undefined && parsedResult !== "" ? parsedResult.includes("{%") && parsedResult.includes("%}") : false
|
||||
|
||||
return (
|
||||
<Tooltip arrow placement="right" title={
|
||||
<Typography variant="body2" style={{whiteSpace: "pre-line", }}>
|
||||
{params.row.result !== null && params.row.result !== undefined && params.row.result !== "" ?
|
||||
params.row.result
|
||||
:
|
||||
null
|
||||
}
|
||||
</Typography>
|
||||
}>
|
||||
<span style={{backgroundColor: !hasError ? "inherit" : "rgba(244,0,0,0.6)", }}>
|
||||
<Link href={`/workflows/${params.row.workflow.id}?execution_id=${params.row.id}`} target="_blank" rel="noopener noreferrer">
|
||||
<OpenInNewIcon fontSize="small" />
|
||||
</Link>
|
||||
</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
@@ -522,6 +560,7 @@ const RuntimeDebugger = (props) => {
|
||||
minWidth: 240,
|
||||
maxWidth: 240,
|
||||
}}
|
||||
ampm={false}
|
||||
label="Search from"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value={startTime}
|
||||
@@ -535,6 +574,7 @@ const RuntimeDebugger = (props) => {
|
||||
minWidth: 240,
|
||||
maxWidth: 240,
|
||||
}}
|
||||
ampm={false}
|
||||
label="Search until"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value={endTime}
|
||||
|
||||
@@ -550,7 +550,6 @@ const CodeEditor = (props) => {
|
||||
var code_lines = localcodedata.split('\n')
|
||||
for (var i = 0; i < code_lines.length; i++){
|
||||
var current_code_line = code_lines[i]
|
||||
console.log("Codeline: ", current_code_line)
|
||||
|
||||
var variable_occurence = current_code_line.match(/[\\]{0,1}[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
|
||||
|
||||
@@ -612,8 +611,6 @@ const CodeEditor = (props) => {
|
||||
const fixedVariable = fixVariable(variable_occurence[occ])
|
||||
var correctVariable = availableVariables.includes(fixedVariable)
|
||||
if(!correctVariable) {
|
||||
console.log("Line: ", i, "ch: ", dollar_occurence[occ])
|
||||
|
||||
value.markText({line:i, ch:dollar_occurence[occ]}, {line:i, ch:dollar_occurence_len[occ]+dollar_occurence[occ]}, {"css": "background-color: rgb(248, 106, 62, 0.9); padding-top: 2px; padding-bottom: 2px; color: white"})
|
||||
} else {
|
||||
value.markText({line:i, ch:dollar_occurence[occ]}, {line:i, ch:dollar_occurence_len[occ]+dollar_occurence[occ]}, {"css": "background-color: #8b8e26; padding-top: 2px; padding-bottom: 2px; color: white"})
|
||||
@@ -664,6 +661,23 @@ const CodeEditor = (props) => {
|
||||
setlocalcodedata(updatedCode)
|
||||
}
|
||||
|
||||
const fixStringInput = (new_input) => {
|
||||
// Newline fixes
|
||||
new_input = new_input.replace(/\r\n/g, "\\n")
|
||||
new_input = new_input.replace(/\n/g, "\\n")
|
||||
|
||||
// Quote fixes
|
||||
new_input = new_input.replace(/\\"/g, '"')
|
||||
new_input = new_input.replace(/"/g, '\\"')
|
||||
|
||||
new_input = new_input.replace(/\\'/g, "'")
|
||||
new_input = new_input.replace(/'/g, "\\'")
|
||||
|
||||
|
||||
return new_input
|
||||
}
|
||||
|
||||
|
||||
const expectedOutput = (input) => {
|
||||
|
||||
//const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
|
||||
@@ -687,20 +701,26 @@ const CodeEditor = (props) => {
|
||||
|
||||
valuefound = true
|
||||
|
||||
console.log("Here. Checking if we got an example?")
|
||||
try {
|
||||
if (typeof actionlist[j].example === "object") {
|
||||
|
||||
input = input.replace(found[i], JSON.stringify(actionlist[j].example), -1);
|
||||
|
||||
} else if (actionlist[j].example.trim().startsWith("{") || actionlist[j].example.trim().startsWith("[")) {
|
||||
input = input.replace(found[i], JSON.stringify(actionlist[j].example), -1);
|
||||
} else {
|
||||
input = input.replace(found[i], actionlist[j].example, -1)
|
||||
console.log("This?")
|
||||
|
||||
const newExample = fixStringInput(actionlist[j].example)
|
||||
input = input.replace(found[i], newExample, -1)
|
||||
}
|
||||
} catch (e) {
|
||||
input = input.replace(found[i], actionlist[j].example, -1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//if (!valuefound) {
|
||||
// console.log("Couldn't find value "+fixedVariable)
|
||||
//}
|
||||
@@ -736,7 +756,10 @@ const CodeEditor = (props) => {
|
||||
new_input = JSON.stringify(new_input)
|
||||
} else {
|
||||
if (typeof new_input === "string") {
|
||||
new_input = new_input
|
||||
// Check if it contains any newlines, and replace them with raw newlines
|
||||
new_input = fixStringInput(new_input)
|
||||
|
||||
// Replace quotes with nothing
|
||||
} else {
|
||||
console.log("NO TYPE? ", typeof new_input)
|
||||
try {
|
||||
@@ -747,7 +770,6 @@ const CodeEditor = (props) => {
|
||||
}
|
||||
}
|
||||
|
||||
//console.log("FOUND2: ", fixedVariable, actionlist[j].example)
|
||||
input = input.replace(fixedVariable, new_input, -1)
|
||||
input = input.replace(found[i], new_input, -1)
|
||||
|
||||
@@ -1430,7 +1452,6 @@ const CodeEditor = (props) => {
|
||||
highlight_variables(value)
|
||||
}}
|
||||
onChange={(value, viewUpdate) => {
|
||||
console.log("Value: ", value, viewUpdate)
|
||||
setlocalcodedata(value)
|
||||
expectedOutput(value)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user