diff --git a/frontend/app/components/Client/Webhooks/ListItem.js b/frontend/app/components/Client/Webhooks/ListItem.js
deleted file mode 100644
index 3ea0e691b..000000000
--- a/frontend/app/components/Client/Webhooks/ListItem.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-import { Button } from 'UI';
-
-const ListItem = ({ webhook, onEdit }) => {
- return (
-
-
-
{webhook.name}
-
{webhook.endpoint}
-
-
-
-
-
- );
-};
-
-export default ListItem;
diff --git a/frontend/app/components/Client/Webhooks/WebhookForm.js b/frontend/app/components/Client/Webhooks/WebhookForm.js
deleted file mode 100644
index 9cdc50708..000000000
--- a/frontend/app/components/Client/Webhooks/WebhookForm.js
+++ /dev/null
@@ -1,80 +0,0 @@
-import React from 'react';
-import { Input } from 'UI';
-import { Button, Form } from 'antd';
-import styles from './webhookForm.module.css';
-import { useStore } from 'App/mstore';
-import { observer } from 'mobx-react-lite';
-import { toast } from 'react-toastify';
-
-function WebhookForm(props) {
- const { settingsStore } = useStore();
- const { webhookInst: webhook, saveWebhook, editWebhook, saving } = settingsStore;
- const write = ({ target: { value, name } }) => editWebhook({ [name]: value });
-
- const save = () => {
- saveWebhook(webhook)
- .then(() => {
- props.onClose();
- })
- .catch((e) => {
- toast.error(e.message || 'Failed to save webhook');
- });
- };
-
- return (
-
-
{webhook.exists() ? 'Update' : 'Add'} Webhook
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {webhook.exists() && }
-
- {webhook.exists() && (
-
- )}
-
-
-
- );
-}
-
-export default observer(WebhookForm);
diff --git a/frontend/app/components/Client/Webhooks/WebhookForm.tsx b/frontend/app/components/Client/Webhooks/WebhookForm.tsx
new file mode 100644
index 000000000..d3fe7b2c3
--- /dev/null
+++ b/frontend/app/components/Client/Webhooks/WebhookForm.tsx
@@ -0,0 +1,83 @@
+import React from 'react';
+import { Input } from 'UI';
+import { Button, Form } from 'antd';
+import { useStore } from 'App/mstore';
+import { observer } from 'mobx-react-lite';
+import { toast } from 'react-toastify';
+import { TrashIcon } from 'lucide-react';
+
+interface Props {
+ onClose: () => void;
+ onDelete: (id: string) => void;
+}
+
+function WebhookForm({ onClose, onDelete }: Props) {
+ const { settingsStore } = useStore();
+ const { webhookInst: webhook, saveWebhook, editWebhook, saving } = settingsStore;
+ const write = ({ target: { value, name } }) => editWebhook({ [name]: value });
+
+ const save = () => {
+ saveWebhook(webhook)
+ .then(() => {
+ onClose();
+ })
+ .catch((e) => {
+ toast.error(e.message || 'Failed to save webhook');
+ });
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {webhook.exists() && }
+
+ {webhook.exists() && (
+
}
+ type="text"
+ onClick={() => onDelete(webhook.webhookId)}
+ >
+ )}
+
+
+ );
+}
+
+export default observer(WebhookForm);
diff --git a/frontend/app/components/Client/Webhooks/Webhooks.tsx b/frontend/app/components/Client/Webhooks/Webhooks.tsx
index 023d5a789..c83f40526 100644
--- a/frontend/app/components/Client/Webhooks/Webhooks.tsx
+++ b/frontend/app/components/Client/Webhooks/Webhooks.tsx
@@ -1,83 +1,100 @@
import React, { useEffect } from 'react';
-import cn from 'classnames';
-import withPageTitle from 'HOCs/withPageTitle';
-import { Button, Loader, NoContent, Icon, Divider } from 'UI';
+import { Loader, NoContent, Icon } from 'UI';
import WebhookForm from './WebhookForm';
-import ListItem from './ListItem';
-import styles from './webhooks.module.css';
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
-import { confirm } from 'UI';
import { toast } from 'react-toastify';
-import { useModal } from 'App/components/Modal';
import { useStore } from 'App/mstore';
-import { observer } from 'mobx-react-lite'
+import { observer } from 'mobx-react-lite';
import { IWebhook } from 'Types/webhook';
+import { App, List, Button, Typography, Space } from 'antd';
+import { PencilIcon } from '.store/lucide-react-virtual-b029c146a4/package';
+import usePageTitle from '@/hooks/usePageTitle';
+import { useModal } from 'Components/ModalContext';
function Webhooks() {
- const { settingsStore } = useStore()
- const { webhooks, hooksLoading: loading } = settingsStore;
- const { showModal, hideModal } = useModal();
+ const { settingsStore } = useStore();
+ const { webhooks, hooksLoading: loading } = settingsStore;
+ const { openModal, closeModal } = useModal();
+ const { modal } = App.useApp();
+ usePageTitle('Webhooks - OpenReplay Preferences');
+ const customWebhooks = webhooks.filter((h) => h.type === 'webhook');
- const customWebhooks = webhooks.filter((hook) => hook.type === 'webhook');
- useEffect(() => {
- void settingsStore.fetchWebhooks();
- }, []);
+ useEffect(() => {
+ void settingsStore.fetchWebhooks();
+ }, []);
- const init = (webhookInst?: Partial) => {
- settingsStore.initWebhook(webhookInst);
- showModal(, { right: true });
- };
+ const init = (w?: Partial) => {
+ settingsStore.initWebhook({...w});
+ openModal(, { title: w ? 'Edit Webhook' : 'Add Webhook' });
+ };
- const removeWebhook = async (id: string) => {
- if (
- await confirm({
- header: 'Confirm',
- confirmButton: 'Yes, delete',
- confirmation: `Are you sure you want to remove this webhook?`,
- })
- ) {
- settingsStore.removeWebhook(id).then(() => {
- toast.success('Webhook removed successfully');
- });
- hideModal();
- }
- };
+ const removeWebhook = async (id: string) => {
+ modal.confirm({
+ title: 'Confirm',
+ content: 'Are you sure you want to remove this webhook?',
+ onOk: () => {
+ settingsStore.removeWebhook(id).then(() => toast.success('Webhook removed successfully'));
+ closeModal();
+ }
+ });
+ };
- return (
-
-
-
{'Webhooks'}
-
-
-
-
-
- Leverage webhook notifications on alerts to trigger custom callbacks.
-
-
-
-
-
- None added yet
-
- }
- size="small"
- show={customWebhooks.length === 0}
- >
-
- {customWebhooks.map((webhook) => (
- <>
-
init(webhook)} />
-
- >
- ))}
-
-
-
+ return (
+
+
+
+ Webhooks
+
+
+ Leverage webhook notifications on alerts to trigger custom callbacks.
+
- );
+
+
+
+
+
+
+ None added yet
+
+ }
+ size="small"
+ show={customWebhooks.length === 0}
+ >
+ (
+ init(w)}
+ className="p-2! group flex justify-between items-center cursor-pointer hover:bg-active-blue transition"
+ >
+
+ {w.name}
+
+ {w.endpoint}
+
+
+ } />
+
+ )}
+ />
+
+
+
+ );
}
-export default withPageTitle('Webhooks - OpenReplay Preferences')(observer(Webhooks));
+export default observer(Webhooks);
diff --git a/frontend/app/components/Client/Webhooks/listItem.module.css b/frontend/app/components/Client/Webhooks/listItem.module.css
deleted file mode 100644
index 88c863de4..000000000
--- a/frontend/app/components/Client/Webhooks/listItem.module.css
+++ /dev/null
@@ -1,52 +0,0 @@
-
-@import 'mixins.css';
-
-.wrapper {
- display: flex;
- padding: 15px 10px;
- border-bottom: solid thin $gray-light;
- transition: all 0.4s;
- align-items: center;
-
- &:hover {
- background-color: $active-blue;
- transition: all 0.2s;
- & .actions {
- opacity: 1;
- transition: all 0.4s;
- }
- }
-}
-
-.actions {
- margin-left: auto;
- opacity: 0;
- transition: all 0.4s;
- display: flex;
- align-items: center;
- & .button {
- padding: 5px;
- cursor: pointer;
- margin-left: 10px;
- &:hover {
- & svg {
- fill: $teal-dark;
- }
- }
- }
-}
-
-.tag {
- margin-left: 10px;
- font-size: 12px;
- padding: 2px 10px;
- border-radius: 10px;
- background-color: $gray-lightest;
- box-shadow: 0 0 0 1px $gray-light inset;
-}
-
-.endpoint {
- font-size: 12px;
- color: $gray-medium;
- margin-top: 5px;
-}
\ No newline at end of file