-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
style: create webhook page to modal (#3223)
* style: create webhook page to modal * fix: create page removed * fix: auto modal close on empty state * fix: secret key heading removed from generated modal
- Loading branch information
1 parent
542b18a
commit e14baf1
Showing
9 changed files
with
273 additions
and
158 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import React, { useState } from "react"; | ||
import { useRouter } from "next/router"; | ||
import { Dialog, Transition } from "@headlessui/react"; | ||
// components | ||
import { WebhookForm } from "./form"; | ||
import { GeneratedHookDetails } from "./generated-hook-details"; | ||
// hooks | ||
import useToast from "hooks/use-toast"; | ||
// helpers | ||
import { csvDownload } from "helpers/download.helper"; | ||
// utils | ||
import { getCurrentHookAsCSV } from "./utils"; | ||
// types | ||
import { IWebhook, IWorkspace, TWebhookEventTypes } from "types"; | ||
|
||
interface WebhookWithKey { | ||
webHook: IWebhook; | ||
secretKey: string | undefined; | ||
} | ||
interface ICreateWebhookModal { | ||
currentWorkspace: IWorkspace | null; | ||
isOpen: boolean; | ||
clearSecretKey: () => void; | ||
createWebhook: (workspaceSlug: string, data: Partial<IWebhook>) => Promise<WebhookWithKey>; | ||
onClose: () => void; | ||
} | ||
|
||
export const CreateWebhookModal: React.FC<ICreateWebhookModal> = (props) => { | ||
const { isOpen, onClose, currentWorkspace, createWebhook, clearSecretKey } = props; | ||
// states | ||
const [generatedWebhook, setGeneratedKey] = useState<IWebhook | null>(null); | ||
// router | ||
const router = useRouter(); | ||
const { workspaceSlug } = router.query; | ||
// toast | ||
const { setToastAlert } = useToast(); | ||
|
||
const handleCreateWebhook = async (formData: IWebhook, webhookEventType: TWebhookEventTypes) => { | ||
if (!workspaceSlug) return; | ||
|
||
let payload: Partial<IWebhook> = { | ||
url: formData.url, | ||
}; | ||
|
||
if (webhookEventType === "all") | ||
payload = { | ||
...payload, | ||
project: true, | ||
cycle: true, | ||
module: true, | ||
issue: true, | ||
issue_comment: true, | ||
}; | ||
else | ||
payload = { | ||
...payload, | ||
project: formData.project ?? false, | ||
cycle: formData.cycle ?? false, | ||
module: formData.module ?? false, | ||
issue: formData.issue ?? false, | ||
issue_comment: formData.issue_comment ?? false, | ||
}; | ||
|
||
await createWebhook(workspaceSlug.toString(), payload) | ||
.then(({ webHook, secretKey }) => { | ||
setToastAlert({ | ||
type: "success", | ||
title: "Success!", | ||
message: "Webhook created successfully.", | ||
}); | ||
|
||
setGeneratedKey(webHook); | ||
|
||
const csvData = getCurrentHookAsCSV(currentWorkspace, webHook, secretKey); | ||
csvDownload(csvData, `webhook-secret-key-${Date.now()}`); | ||
}) | ||
.catch((error) => { | ||
setToastAlert({ | ||
type: "error", | ||
title: "Error!", | ||
message: error?.error ?? "Something went wrong. Please try again.", | ||
}); | ||
}); | ||
}; | ||
|
||
const handleClose = () => { | ||
onClose(); | ||
setTimeout(() => { | ||
clearSecretKey(); | ||
setGeneratedKey(null); | ||
}, 350); | ||
}; | ||
|
||
return ( | ||
<Transition.Root show={isOpen} as={React.Fragment}> | ||
<Dialog | ||
as="div" | ||
className="relative z-20" | ||
onClose={() => { | ||
if (!generatedWebhook) handleClose(); | ||
}} | ||
> | ||
<Transition.Child | ||
as={React.Fragment} | ||
enter="ease-out duration-300" | ||
enterFrom="opacity-0" | ||
enterTo="opacity-100" | ||
leave="ease-in duration-200" | ||
leaveFrom="opacity-100" | ||
leaveTo="opacity-0" | ||
> | ||
<div className="fixed inset-0 bg-custom-backdrop bg-opacity-50 transition-opacity" /> | ||
</Transition.Child> | ||
|
||
<div className="fixed inset-0 z-20 overflow-y-auto"> | ||
<div className="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0"> | ||
<Transition.Child | ||
as={React.Fragment} | ||
enter="ease-out duration-300" | ||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" | ||
enterTo="opacity-100 translate-y-0 sm:scale-100" | ||
leave="ease-in duration-200" | ||
leaveFrom="opacity-100 translate-y-0 sm:scale-100" | ||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" | ||
> | ||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg border border-custom-border-200 bg-custom-background-100 p-6 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-2xl"> | ||
{!generatedWebhook ? ( | ||
<WebhookForm onSubmit={handleCreateWebhook} handleClose={handleClose} /> | ||
) : ( | ||
<GeneratedHookDetails webhookDetails={generatedWebhook} handleClose={handleClose} /> | ||
)} | ||
</Dialog.Panel> | ||
</Transition.Child> | ||
</div> | ||
</div> | ||
</Dialog> | ||
</Transition.Root> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// components | ||
import { WebhookSecretKey } from "./form"; | ||
// ui | ||
import { Button } from "@plane/ui"; | ||
// types | ||
import { IWebhook } from "types"; | ||
|
||
type Props = { | ||
handleClose: () => void; | ||
webhookDetails: IWebhook; | ||
}; | ||
|
||
export const GeneratedHookDetails: React.FC<Props> = (props) => { | ||
const { handleClose, webhookDetails } = props; | ||
|
||
return ( | ||
<div> | ||
<div className="space-y-3 mb-3"> | ||
<h3 className="text-lg font-medium leading-6 text-custom-text-100">Key created</h3> | ||
<p className="text-sm text-custom-text-400"> | ||
Copy and save this secret key in Plane Pages. You can{"'"}t see this key after you hit Close. A CSV file | ||
containing the key has been downloaded. | ||
</p> | ||
</div> | ||
<WebhookSecretKey data={webhookDetails} /> | ||
<div className="mt-6 flex justify-end"> | ||
<Button variant="neutral-primary" size="sm" onClick={handleClose}> | ||
Close | ||
</Button> | ||
</div> | ||
</div> | ||
); | ||
}; |
Oops, something went wrong.