1- import { Fragment , useCallback , useMemo , useState } from 'react' ;
1+ import { useCallback , useState } from 'react' ;
22import Head from 'next/head' ;
3- import { HTTPError } from 'ky' ;
43import { CopyToClipboard } from 'react-copy-to-clipboard' ;
54import { SubmitHandler , useForm , useWatch } from 'react-hook-form' ;
65import { DEFAULT_METADATA_MAX_ROWS_TO_READ } from '@hyperdx/common-utils/dist/core/metadata' ;
76import {
87 SourceKind ,
98 TeamClickHouseSettings ,
10- WebhookService ,
119} from '@hyperdx/common-utils/dist/types' ;
1210import {
1311 Box ,
@@ -26,7 +24,6 @@ import {
2624 TextInput ,
2725 Tooltip ,
2826} from '@mantine/core' ;
29- import { useDisclosure } from '@mantine/hooks' ;
3027import { notifications } from '@mantine/notifications' ;
3128import {
3229 IconCheck ,
@@ -47,14 +44,12 @@ import { IS_LOCAL_MODE } from '@/config';
4744
4845import { PageHeader } from './components/PageHeader' ;
4946import TeamMembersSection from './components/TeamSettings/TeamMembersSection' ;
50- import { WebhookForm } from './components/TeamSettings/WebhookForm ' ;
47+ import WebhooksSection from './components/TeamSettings/WebhooksSection ' ;
5148import api from './api' ;
5249import { useConnections } from './connection' ;
5350import { DEFAULT_QUERY_TIMEOUT , DEFAULT_SEARCH_ROW_LIMIT } from './defaults' ;
5451import { withAppNav } from './layout' ;
5552import { useSources } from './source' ;
56- import type { Webhook } from './types' ;
57- import { useConfirm } from './useConfirm' ;
5853import { capitalizeFirstLetter } from './utils' ;
5954
6055function ConnectionsSection ( ) {
@@ -242,159 +237,15 @@ function SourcesSection() {
242237 </ Box >
243238 ) ;
244239}
245-
246- function DeleteWebhookButton ( {
247- webhookId,
248- webhookName,
249- onSuccess,
250- } : {
251- webhookId : string ;
252- webhookName : string ;
253- onSuccess : VoidFunction ;
254- } ) {
255- const confirm = useConfirm ( ) ;
256- const deleteWebhook = api . useDeleteWebhook ( ) ;
257-
258- const handleDelete = async ( ) => {
259- if (
260- await confirm (
261- `Are you sure you want to delete ${ webhookName } webhook?` ,
262- 'Delete' ,
263- )
264- ) {
265- try {
266- await deleteWebhook . mutateAsync ( { id : webhookId } ) ;
267- notifications . show ( {
268- color : 'green' ,
269- message : 'Webhook deleted successfully' ,
270- } ) ;
271- onSuccess ( ) ;
272- } catch ( e ) {
273- console . error ( e ) ;
274- const message =
275- ( e instanceof HTTPError
276- ? ( await e . response . json ( ) ) ?. message
277- : null ) || 'Something went wrong. Please contact HyperDX team.' ;
278- notifications . show ( {
279- message,
280- color : 'red' ,
281- autoClose : 5000 ,
282- } ) ;
283- }
284- }
285- } ;
286-
287- return (
288- < Button
289- color = "red"
290- size = "compact-xs"
291- variant = "outline"
292- onClick = { handleDelete }
293- loading = { deleteWebhook . isPending }
294- >
295- Delete
296- </ Button >
297- ) ;
298- }
299-
300240function IntegrationsSection ( ) {
301- const { data : webhookData , refetch : refetchWebhooks } = api . useWebhooks ( [
302- WebhookService . Slack ,
303- WebhookService . Generic ,
304- WebhookService . IncidentIO ,
305- ] ) ;
306-
307- const allWebhooks = useMemo < Webhook [ ] > ( ( ) => {
308- return Array . isArray ( webhookData ?. data ) ? webhookData . data : [ ] ;
309- } , [ webhookData ] ) ;
310-
311- const [ editedWebhookId , setEditedWebhookId ] = useState < string | null > ( null ) ;
312- const [
313- isAddWebhookModalOpen ,
314- { open : openWebhookModal , close : closeWebhookModal } ,
315- ] = useDisclosure ( ) ;
316-
317241 return (
318242 < Box id = "integrations" >
319243 < Text size = "md" > Integrations</ Text >
320244 < Divider my = "md" />
321245 < Card variant = "muted" >
322- < Text mb = "xs" > Webhooks</ Text >
323-
324- < Stack >
325- { allWebhooks . map ( webhook => (
326- < Fragment key = { webhook . _id } >
327- < Group justify = "space-between" align = "flex-start" >
328- < Stack gap = { 0 } >
329- < Text size = "sm" >
330- { webhook . name } ({ webhook . service } )
331- </ Text >
332- < Text size = "xs" opacity = { 0.7 } >
333- { webhook . url }
334- </ Text >
335- { webhook . description && (
336- < Text size = "xxs" opacity = { 0.7 } >
337- { webhook . description }
338- </ Text >
339- ) }
340- </ Stack >
341- < Group gap = "xs" >
342- { editedWebhookId !== webhook . _id && (
343- < >
344- < Button
345- variant = "subtle"
346- onClick = { ( ) => setEditedWebhookId ( webhook . _id ) }
347- size = "compact-xs"
348- leftSection = { < IconPencil size = { 14 } /> }
349- >
350- Edit
351- </ Button >
352- < DeleteWebhookButton
353- webhookId = { webhook . _id }
354- webhookName = { webhook . name }
355- onSuccess = { refetchWebhooks }
356- />
357- </ >
358- ) }
359- { editedWebhookId === webhook . _id && (
360- < Button
361- variant = "subtle"
362- onClick = { ( ) => setEditedWebhookId ( null ) }
363- size = "compact-xs"
364- >
365- < IconX size = { 14 } className = "me-2" /> Cancel
366- </ Button >
367- ) }
368- </ Group >
369- </ Group >
370- { editedWebhookId === webhook . _id && (
371- < WebhookForm
372- webhook = { webhook }
373- onClose = { ( ) => setEditedWebhookId ( null ) }
374- onSuccess = { ( ) => {
375- setEditedWebhookId ( null ) ;
376- refetchWebhooks ( ) ;
377- } }
378- />
379- ) }
380- < Divider />
381- </ Fragment >
382- ) ) }
246+ < Stack gap = "md" >
247+ < WebhooksSection />
383248 </ Stack >
384-
385- { ! isAddWebhookModalOpen ? (
386- < Button variant = "outline" onClick = { openWebhookModal } >
387- Add Webhook
388- </ Button >
389- ) : (
390- < WebhookForm
391- onClose = { closeWebhookModal }
392- onSuccess = { ( ) => {
393- refetchWebhooks ( ) ;
394- closeWebhookModal ( ) ;
395- } }
396- />
397- ) }
398249 </ Card >
399250 </ Box >
400251 ) ;
0 commit comments