Skip to content

Commit c190586

Browse files
Merge pull request #508 from DrDroidLab/feature/secret-management-ui
adds secret management UI
2 parents 38b3987 + d31e424 commit c190586

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+4137
-2092
lines changed

executor/models.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,4 @@ class Meta:
696696
]
697697
indexes = [
698698
models.Index(fields=['key', 'account', 'is_active']),
699-
]
700-
701-
def __str__(self):
702-
return f"{self.account.name}:{self.key}"
699+
]

web/package-lock.json

+2,515-2,074
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/src/components.ts

+1
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ export const components = {
4242
import("./pages/dynamicAlerts/CreateDynamicAlert"),
4343
[PageKeys.DYNAMIC_ALERT_VIEW]: () =>
4444
import("./pages/dynamicAlerts/CreateDynamicAlert"),
45+
[PageKeys.SECRET_MANAGEMENT]: () => import("./pages/secret-management"),
4546
};

web/src/components/Inputs/HandleInputRender.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import TypingDropdownMultipleSelectionInput from "./InputTypes/TypingDropdownMul
1515
import TextButton from "./InputTypes/TextButton.tsx";
1616
import CronInput from "../common/CronInput/index.tsx";
1717
import Checkbox from "../common/Checkbox/index.tsx";
18+
import SearchInput from "./InputTypes/SearchInput.tsx";
1819

1920
export type HandleInputRenderType = {
2021
inputType: InputType;
@@ -48,6 +49,8 @@ function HandleInputRender({ inputType, ...props }: HandleInputRenderType) {
4849
switch (inputType) {
4950
case InputTypes.TEXT:
5051
return <Text {...props} handleChange={props.handleChange!} />;
52+
case InputTypes.SEARCH:
53+
return <SearchInput {...props} handleChange={props.handleChange!} />;
5154
case InputTypes.MULTILINE:
5255
return <Multiline handleChange={props.handleChange!} {...props} />;
5356
case InputTypes.BUTTON:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { SearchRounded } from "@mui/icons-material";
2+
import CustomInput from "../CustomInput.tsx";
3+
import { InputTypes } from "../../../types/index.ts";
4+
import { HandleInputRenderType } from "../HandleInputRender";
5+
6+
function SearchInput(props: Omit<HandleInputRenderType, "inputType">) {
7+
return (
8+
<div className="flex w-full h-full">
9+
<div
10+
className={`bg-gray-200 dark:bg-gray-800 rounded-l flex shrink-0 items-center justify-center p-1 border dark:border-gray-700 text-gray-500 dark:text-gray-500`}>
11+
<SearchRounded />
12+
</div>
13+
<CustomInput
14+
type="search"
15+
placeholder="Search playbooks..."
16+
inputType={InputTypes.TEXT}
17+
{...props}
18+
className={`${props.className} !rounded-none !rounded-r !border-l-0 flex-1`}
19+
containerClassName="!w-full"
20+
/>
21+
</div>
22+
);
23+
}
24+
25+
export default SearchInput;

web/src/components/Overlay/index.tsx

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable react-hooks/exhaustive-deps */
2-
import React, { useEffect, useRef } from "react";
2+
import { useEffect, useRef } from "react";
33
import styles from "./index.module.css";
4+
import { motion } from "framer-motion";
45

56
const Overlay = (props) => {
67
const { children, visible, close } = props;
@@ -23,9 +24,14 @@ const Overlay = (props) => {
2324
<>
2425
{visible && (
2526
<div className={styles.overlay}>
26-
<div ref={overlayRef} className={styles.children}>
27+
<motion.div
28+
ref={overlayRef}
29+
initial={{ opacity: 0, y: 50 }}
30+
animate={{ opacity: 1, y: 0 }}
31+
transition={{ duration: 0.2, ease: "easeOut" }}
32+
className={styles.children}>
2733
{children}
28-
</div>
34+
</motion.div>
2935
</div>
3036
)}
3137
</>

web/src/components/PlaybookDescription/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function PlaybookDescription() {
2828
}
2929
value={currentPlaybook?.description}
3030
onChange={handleDescription}
31-
disabled={isPrefetched !== "" ?? false}
31+
disabled={!!isPrefetched}
3232
/>
3333
);
3434
}

web/src/components/Playbooks/create/CustomEdge.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ const CustomEdge = ({
9393
<CustomButton
9494
className={`${
9595
additionalData.id === id ? "shadow-md shadow-violet-500 " : ""
96-
} w-10 h-10 rounded-full items-center p-0 justify-center font-normal step-notes absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2`}
96+
} w-10 h-10 rounded-full items-center p-0 justify-center font-normal step-notes absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 !min-w-0`}
9797
onClick={handleAddConditionClick}>
9898
<Tooltip title="Add Condition">
9999
<Add fontSize="small" />

web/src/components/Sidebar/index.tsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ import useToggle from "../../hooks/common/useToggle";
44
import SlackConnectOverlay from "../SlackConnectOverlay";
55
import { elements } from "./utils";
66
import SidebarElement from "./SidebarElement";
7-
import { LogoutRounded, SettingsRounded } from "@mui/icons-material";
7+
import {
8+
LockRounded,
9+
LogoutRounded,
10+
SecurityRounded,
11+
SettingsRounded,
12+
} from "@mui/icons-material";
813
import SidebarButtonElement from "./SidebarButtonElement";
914
import HeadElement from "./HeadElement";
1015
import useSidebar from "../../hooks/common/sidebar/useSidebar";
@@ -36,6 +41,11 @@ function Sidebar() {
3641
</div>
3742

3843
<div className="flex flex-col gap-2 w-full">
44+
<SidebarElement
45+
to="/secret-management"
46+
label="Secret Management"
47+
icon={<LockRounded fontSize="small" />}
48+
/>
3949
<SidebarButtonElement
4050
label="Join Slack Community"
4151
icon={

web/src/components/common/CustomButton/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function CustomButton({
1515
return (
1616
<button
1717
onClick={onClick}
18-
className={`${className} flex text-center gap-1 items-center text-xs bg-white hover:bg-violet-500 text-violet-500 hover:text-white rounded p-1 border border-violet-500 shrink-0 transition-all`}
18+
className={`${className} flex text-center gap-1 items-center text-xs bg-white hover:bg-violet-500 text-violet-500 hover:text-white rounded p-1 border shrink-0 transition-all`}
1919
{...props}>
2020
{children}
2121
</button>

web/src/components/common/GlobalVariable/AddVariableOverlay.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Toast } from "../../Toast.tsx";
1111
import CustomButton from "../CustomButton/index.tsx";
1212
import CustomInput from "../../Inputs/CustomInput.tsx";
1313
import { InputTypes } from "../../../types/inputs/inputTypes.ts";
14+
import { createPortal } from "react-dom";
1415

1516
const AddVariableOverlay = ({ isOpen, close }) => {
1617
const [name, setName] = useState("");
@@ -41,7 +42,7 @@ const AddVariableOverlay = ({ isOpen, close }) => {
4142
resetState();
4243
};
4344

44-
return (
45+
return createPortal(
4546
<Overlay close={close} visible={isOpen}>
4647
<div className="z-[200] bg-white max-w-sm rounded m-2">
4748
<div className={"p-4"}>
@@ -79,7 +80,8 @@ const AddVariableOverlay = ({ isOpen, close }) => {
7980
handleClose={() => setValidationError("")}
8081
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
8182
/>
82-
</Overlay>
83+
</Overlay>,
84+
document.body,
8385
);
8486
};
8587

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* eslint-disable react-hooks/exhaustive-deps */
2+
import { useEffect } from "react";
3+
import styles from "./index.module.css";
4+
import { CircularProgress } from "@mui/material";
5+
import Overlay from "../Overlay/index.js";
6+
import CustomButton from "../common/CustomButton/index.tsx";
7+
import { useDeleteSecretMutation } from "../../store/features/secrets/api/deleteSecretApi.ts";
8+
9+
const SecretActionOverlay = ({
10+
secret,
11+
isOpen,
12+
toggleOverlay,
13+
refreshTable,
14+
}: any) => {
15+
const [deleteVariable, { isLoading, isSuccess, status }] =
16+
useDeleteSecretMutation();
17+
const handleSuccess = () => {
18+
deleteVariable({ id: secret.id });
19+
};
20+
21+
useEffect(() => {
22+
if (isSuccess) {
23+
toggleOverlay();
24+
refreshTable();
25+
}
26+
}, [status]);
27+
28+
return (
29+
<>
30+
{isOpen && (
31+
<Overlay visible={isOpen}>
32+
<div className={`${styles["actionOverlay"]} dark:bg-gray-900`}>
33+
<header className="text-gray-500 dark:text-gray-400 flex items-center gap-1">
34+
Delete {secret.name}?
35+
</header>
36+
<div className={"flex items-center gap-2 mt-4"}>
37+
<CustomButton onClick={toggleOverlay}>Cancel</CustomButton>
38+
<CustomButton onClick={handleSuccess}>Yes</CustomButton>
39+
{isLoading && (
40+
<CircularProgress
41+
style={{
42+
marginLeft: "12px",
43+
}}
44+
size={20}
45+
/>
46+
)}
47+
</div>
48+
</div>
49+
</Overlay>
50+
)}
51+
</>
52+
);
53+
};
54+
55+
export default SecretActionOverlay;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import useToggle from "../../../hooks/common/useToggle";
2+
import CustomButton from "../../common/CustomButton";
3+
import { AddRounded } from "@mui/icons-material";
4+
import SecretCreateOverlay from "./SecretCreateOverlay";
5+
6+
type CreateVariableButtonProps = {
7+
buttonText?: string;
8+
};
9+
10+
function CreateSecretButton({
11+
buttonText = "Secret",
12+
}: CreateVariableButtonProps) {
13+
const { isOpen: isActionOpen, toggle } = useToggle();
14+
15+
const handleCreateVariable = () => {
16+
toggle();
17+
};
18+
19+
return (
20+
<div>
21+
<CustomButton
22+
className="!h-full self-stretch"
23+
onClick={handleCreateVariable}>
24+
<AddRounded fontSize="small" /> {buttonText}
25+
</CustomButton>
26+
27+
<SecretCreateOverlay isOpen={isActionOpen} toggleOverlay={toggle} />
28+
</div>
29+
);
30+
}
31+
32+
export default CreateSecretButton;

0 commit comments

Comments
 (0)