Skip to content

Commit

Permalink
add validations
Browse files Browse the repository at this point in the history
  • Loading branch information
jayeshsadhwani99 committed Apr 26, 2024
1 parent 0803f14 commit 0031f20
Show file tree
Hide file tree
Showing 10 changed files with 167 additions and 57 deletions.
9 changes: 3 additions & 6 deletions web/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const App = () => {

<Route element={<RequireAuth />}>
<Route element={<Layout />}>
<Route path="/" element={<PlaybookExecutionsList />} />
<Route path="/" element={<Playbooks />} />
<Route path="/playbooks" element={<Playbooks />} />
<Route
path="/playbooks/executions/list"
Expand All @@ -111,16 +111,13 @@ const App = () => {
element={<PlaybookLog />}
/>
<Route path="/workflows/create" element={<CreateWorkflow />} />
<Route path="/workflows" element={<Workflows />} />
<Route exact path="/workflows" element={<Workflows />} />
<Route path="/workflows/:id" element={<CreateWorkflow />} />
<Route
path="/workflows/executions/:id"
element={<WorkflowExecutions />}
/>
<Route
path="/workflows/executions/list"
element={<WorkflowExecutionsList />}
/>
<Route path="/executions/list" element={<WorkflowExecutionsList />} />
<Route
path="/workflows/logs/:workflow_run_id"
element={<WorkflowExecutionLogs />}
Expand Down
18 changes: 13 additions & 5 deletions web/src/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import GroupAddIcon from "@mui/icons-material/GroupAdd";
import SlackConnectOverlay from "./SlackConnectOverlay";
import useToggle from "./hooks/useToggle";
import "../src/Layout.css";
import { Key, Layers, Terminal } from "@mui/icons-material";
import { Key, Layers, SlowMotionVideo, Terminal } from "@mui/icons-material";
import { useLogoutMutation } from "./store/features/auth/api/index.ts";

function Sidebar() {
Expand Down Expand Up @@ -68,26 +68,34 @@ function Sidebar() {
</div>

<List sx={{ padding: 0 }}>
<NavLink className={activeStyle} to="/playbooks/executions/list">
<NavLink className={activeStyle} to="/">
<ListItemIcon
sx={{ minWidth: "44px" }}
onClick={(event) => handleListItemClick(event, 6)}>
<CollectionsBookmarkIcon />
</ListItemIcon>
<p style={{ fontSize: "14px" }} className="playbook_page">
Playbook Executions
Playbooks
</p>
</NavLink>
<NavLink className={activeStyle} to="/workflows/executions/list">
<NavLink className={activeStyle} to="/workflows">
<ListItemIcon
sx={{ minWidth: "44px" }}
onClick={(event) => handleListItemClick(event, 6)}>
<Layers />
</ListItemIcon>
<p style={{ fontSize: "14px" }} className="workflows_page">
Workflows Executions
Workflows
</p>
</NavLink>
<NavLink className={activeStyle} to="/executions/list">
<ListItemIcon
sx={{ minWidth: "44px" }}
onClick={(event) => handleListItemClick(event, 9)}>
<SlowMotionVideo />
</ListItemIcon>
<p style={{ fontSize: "14px" }}>All Executions</p>
</NavLink>
<NavLink className={activeStyle} to="/playgrounds">
<ListItemIcon
sx={{ minWidth: "44px" }}
Expand Down
12 changes: 6 additions & 6 deletions web/src/components/Playbooks/PlayBookTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import NoExistingPlaybook from "./NoExistingPlaybook";
import styles from "./playbooks.module.css";
import useToggle from "../../hooks/useToggle";
import PlaybookActionOverlay from "./PlaybookActionOverlay";
import { ContentCopy, History } from "@mui/icons-material";
import { ContentCopy } from "@mui/icons-material";
import { useDispatch } from "react-redux";
import { copyPlaybook } from "../../store/features/playbook/playbookSlice.ts";
import { useLazyGetPlaybookQuery } from "../../store/features/playbook/api/index.ts";
Expand All @@ -40,9 +40,9 @@ const PlaybookTableRender = ({ data, refreshTable, showDelete = true }) => {
navigate("/playbooks/create");
};

const handleExecutionHistory = (id) => {
navigate(`/playbooks/executions/${id}`);
};
// const handleExecutionHistory = (id) => {
// navigate(`/playbooks/executions/${id}`);
// };

return (
<>
Expand Down Expand Up @@ -88,13 +88,13 @@ const PlaybookTableRender = ({ data, refreshTable, showDelete = true }) => {
<DeleteIcon />
</Tooltip>
</button>
<button
{/* <button
className="rounded border border-violet-500 text-violet-500 hover:text-white hover:bg-violet-500 transition-all p-1"
onClick={() => handleExecutionHistory(item.id)}>
<Tooltip title="View execution history">
<History />
</Tooltip>
</button>
</button> */}
</div>
</TableCell>
)}
Expand Down
65 changes: 34 additions & 31 deletions web/src/components/Workflows/create/BasicDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,41 @@ function BasicDetails() {
placeHolder={"Enter workflow name"}
value={currentWorkflow.name}
onValueChange={(val) => handleInput("name", val)}
error={currentWorkflow?.errors?.name ?? false}
/>
</div>
</div>
<div className="flex flex-col gap-4">
<div className="space-y-2">
<label
className="flex gap-2 items-center text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
htmlFor="playbook">
Trigger Type
</label>
<div className="flex gap-2 items-center">
<SelectComponent
data={triggerTypes?.map((e) => {
return {
id: e.id,
label: e.label,
};
})}
placeholder={`Select Workflow Type`}
onSelectionChange={(_, val) => {
handleSelect("workflowType", val);
}}
selected={currentWorkflow?.workflowType}
searchable={true}
error={currentWorkflow?.errors?.workflowType ?? false}
/>
</div>
</div>
{currentWorkflow.workflowType === "slack" && (
<SlackTriggerForm
handleInput={handleInput}
handleSelect={handleSelect}
/>
)}
<div className="space-y-2">
<label
className="flex gap-2 items-center text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
Expand Down Expand Up @@ -62,6 +95,7 @@ function BasicDetails() {
}}
selected={currentWorkflow?.playbookId}
searchable={true}
error={currentWorkflow?.errors?.playbookId ?? false}
/>
{playbooksLoading && <CircularProgress size={20} />}
<button onClick={refetch}>
Expand All @@ -72,37 +106,6 @@ function BasicDetails() {
</div>
</div>
</div>
<div className="flex flex-col gap-4">
<div className="space-y-2">
<label
className="flex gap-2 items-center text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
htmlFor="playbook">
Trigger Type
</label>
<div className="flex gap-2 items-center">
<SelectComponent
data={triggerTypes?.map((e) => {
return {
id: e.id,
label: e.label,
};
})}
placeholder={`Select Workflow Type`}
onSelectionChange={(_, val) => {
handleSelect("workflowType", val);
}}
selected={currentWorkflow?.workflowType}
searchable={true}
/>
</div>
</div>
{currentWorkflow.workflowType === "slack" && (
<SlackTriggerForm
handleInput={handleInput}
handleSelect={handleSelect}
/>
)}
</div>
</>
);
}
Expand Down
2 changes: 2 additions & 0 deletions web/src/components/Workflows/create/CreateWorkflow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useLazyGetWorkflowQuery } from "../../../store/features/workflow/api/ge
import Loading from "../../common/Loading/index.tsx";
import { useUpdateWorkflowMutation } from "../../../store/features/workflow/api/updateWorkflowApi.ts";
import { stateToWorkflow } from "../../../utils/parser/workflow/stateToWorkflow.ts";
import { validate } from "./utils/validation.ts";

function CreateTrigger() {
const { id: workflowId } = useParams();
Expand All @@ -30,6 +31,7 @@ function CreateTrigger() {
const currentWorkflow = useSelector(currentWorkflowSelector);

const handleSave = async () => {
if (!validate()) return;
try {
const workflow = {
...stateToWorkflow(currentWorkflow).workflow,
Expand Down
87 changes: 87 additions & 0 deletions web/src/components/Workflows/create/utils/validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { store } from "../../../../store/index.ts";
import { showSnackbar } from "../../../../store/features/snackbar/snackbarSlice.ts";
import {
removeErrorKey,
setErrorKey,
} from "../../../../store/features/workflow/workflowSlice.ts";

export const validate = () => {
const currentWorkflow = store.getState().workflows.currentWorkflow;
const dispatch = store.dispatch;
let error = "";
if (!currentWorkflow.name) {
error = "Please enter a name";
dispatch(showSnackbar("Workflow name is required"));
dispatch(setErrorKey({ key: "name", value: "Please enter a name" }));
} else {
dispatch(removeErrorKey("name"));
}
if (!(currentWorkflow as any).playbookId) {
error = "Please select a playbook";
dispatch(showSnackbar("Playbook is required"));
dispatch(
setErrorKey({ key: "playbookId", value: "Please select a playbook" }),
);
} else {
dispatch(removeErrorKey("playbookId"));
}
if (!currentWorkflow.workflowType) {
error = "Please select a type";
dispatch(showSnackbar("Workflow type is required"));
dispatch(
setErrorKey({ key: "workflowType", value: "Please select a type" }),
);
} else {
dispatch(removeErrorKey("workflowType"));
}
if (currentWorkflow.workflowType === "slack") {
if (!(currentWorkflow.trigger as any)?.channel?.channel_id) {
error = "Please select a channel";
dispatch(showSnackbar("Channel ID is required"));
dispatch(
setErrorKey({ key: "channelId", value: "Please select a channel" }),
);
} else {
dispatch(removeErrorKey("channelId"));
}
if (!(currentWorkflow.trigger as any)?.source) {
error = "Please select a trigger";
dispatch(showSnackbar("A source is required"));
dispatch(
setErrorKey({ key: "source", value: "Please select a trigger" }),
);
} else {
dispatch(removeErrorKey("source"));
}
if (!(currentWorkflow.trigger as any)?.filterString) {
error = "Please enter a matching string";
dispatch(showSnackbar("A matching string is required"));
dispatch(
setErrorKey({
key: "filterString",
value: "Please enter a matching string",
}),
);
} else {
dispatch(removeErrorKey("filterString"));
}
}

if (currentWorkflow.schedule === "periodic") {
if (!(currentWorkflow as any)?.duration) {
error = "Please enter a duration";
dispatch(showSnackbar("A duration is required"));
dispatch(
setErrorKey({ key: "duration", value: "Please enter an duration" }),
);
} else {
dispatch(removeErrorKey("duration"));
}
}

if (error) {
return false;
} else {
return true;
}
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useNavigate } from "react-router-dom";
// import { useNavigate } from "react-router-dom";
import Heading from "../../Heading.js";
import { useEffect, useState } from "react";
import SuspenseLoader from "../../Skeleton/SuspenseLoader.js";
Expand All @@ -8,7 +8,7 @@ import ExecutionsTable from "./ExecutionsTable.jsx";
import { useGetWorkflowExecutionsQuery } from "../../../store/features/workflow/api/getWorkflowExecutionsApi.ts";

const WorkflowExecutionList = () => {
const navigate = useNavigate();
// const navigate = useNavigate();
const [pageMeta, setPageMeta] = useState({ limit: 10, offset: 0 });
const { data, isFetching, refetch } = useGetWorkflowExecutionsQuery({
...pageMeta,
Expand All @@ -24,11 +24,11 @@ const WorkflowExecutionList = () => {
setPageMeta(page);
};

const handleCreateWorkflow = () => {
navigate({
pathname: "/workflows/create",
});
};
// const handleCreateWorkflow = () => {
// navigate({
// pathname: "/workflows/create",
// });
// };

return (
<div>
Expand All @@ -37,7 +37,7 @@ const WorkflowExecutionList = () => {
onTimeRangeChangeCb={false}
onRefreshCb={false}
/>
<div
{/* <div
style={{
display: "flex",
flexDirection: "row",
Expand All @@ -51,7 +51,7 @@ const WorkflowExecutionList = () => {
style={{ color: "white", marginTop: "0px", marginRight: "10px" }}>
+ Create Workflow
</button>
</div>
</div> */}
<SuspenseLoader loading={isFetching} loader={<TableSkeleton />}>
<ExecutionsTable
workflowsList={workflowsList}
Expand Down
3 changes: 3 additions & 0 deletions web/src/components/Workflows/triggers/SlackTriggerForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ function SlackTriggerForm() {
}}
selected={currentWorkflow?.trigger?.channel?.channel_id ?? ""}
searchable={true}
error={currentWorkflow?.errors?.channelId ?? false}
/>
{isFetching && <CircularProgress size={20} />}
<button onClick={refetch}>
Expand All @@ -75,6 +76,7 @@ function SlackTriggerForm() {
onSelectionChange={(id) => handleTriggerSelect("source", id)}
selected={currentWorkflow?.trigger?.source ?? ""}
searchable={true}
error={currentWorkflow?.errors?.source ?? false}
/>
</div>
<div className="text-sm flex items-center gap-2">
Expand All @@ -87,6 +89,7 @@ function SlackTriggerForm() {
value={currentWorkflow?.trigger?.filterString}
placeHolder={"Enter Matching string"}
length={300}
error={currentWorkflow?.errors?.filterString ?? false}
/>
</div>
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const HandleInputRender = ({ option }) => {
: handleInput(option.id, val)
}
disabled={disabled}
error={currentWorkflow ? currentWorkflow.errors[option.id] : false}
{...option.additionalProps}
/>
</div>
Expand Down
Loading

0 comments on commit 0031f20

Please sign in to comment.