import { Events } from "./chunk-AD4IF7GD.js"; import { useWebhooks } from "./chunk-CI2U7W4K.js"; import { selectAdminPermissions } from "./chunk-6HMBNYS4.js"; import { useEnterprise } from "./chunk-W6ICJ5TB.js"; import { BackButton } from "./chunk-IY256CNP.js"; import { create4 as create, create6 as create2, create7 as create3, create8 as create4 } from "./chunk-XLSIZGJF.js"; import { MemoizedInputRenderer, MemoizedStringInput } from "./chunk-6AXVGFVQ.js"; import { Form, useField, useForm } from "./chunk-BFLP6DBI.js"; import { Layouts } from "./chunk-TIVRAWTC.js"; import { Page, useAPIErrorHandler } from "./chunk-5CAWUBTQ.js"; import { useTypedSelector } from "./chunk-QEGMJR7H.js"; import { isBaseQueryError } from "./chunk-LCL5TIBZ.js"; import { useNotification } from "./chunk-N55RVBRV.js"; import { Box, Button, Combobox, Field, Flex, Grid, IconButton, Main, Option, TextButton, Typography, useIntl } from "./chunk-7XB6XSWQ.js"; import { useMatch, useNavigate } from "./chunk-TUXTO2Z5.js"; import { ForwardRef$1h, ForwardRef$1j, ForwardRef$21, ForwardRef$2j, ForwardRef$45, ForwardRef$4F } from "./chunk-WRD5KPDH.js"; import { require_jsx_runtime } from "./chunk-NIAJZ5MX.js"; import { dt } from "./chunk-ACIMPXWY.js"; import { require_react } from "./chunk-MADUDGYZ.js"; import { __toESM } from "./chunk-PLDDJCW6.js"; // node_modules/@strapi/admin/dist/admin/admin/src/pages/Settings/pages/Webhooks/EditPage.mjs var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1); var React3 = __toESM(require_react(), 1); // node_modules/@strapi/admin/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1); var React2 = __toESM(require_react(), 1); // node_modules/@strapi/admin/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/EventsTable.mjs var import_jsx_runtime = __toESM(require_jsx_runtime(), 1); var EventTableCE = () => { return (0, import_jsx_runtime.jsxs)(Events.Root, { children: [ (0, import_jsx_runtime.jsx)(Events.Headers, {}), (0, import_jsx_runtime.jsx)(Events.Body, {}) ] }); }; // node_modules/@strapi/admin/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/HeadersInput.mjs var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1); var React = __toESM(require_react(), 1); var AddHeaderButton = dt(TextButton)` cursor: pointer; `; var HeadersInput = () => { const { formatMessage } = useIntl(); const addFieldRow = useForm("HeadersInput", (state) => state.addFieldRow); const removeFieldRow = useForm("HeadersInput", (state) => state.removeFieldRow); const setFieldValue = useForm("HeadersInput", (state) => state.onChange); const { value = [] } = useField("headers"); const removeRow = (index) => { if (value.length === 1) { setFieldValue("headers", [ { key: "", value: "" } ]); } else { removeFieldRow("headers", index); } }; return (0, import_jsx_runtime2.jsxs)(Flex, { direction: "column", alignItems: "stretch", gap: 1, children: [ (0, import_jsx_runtime2.jsx)(Field.Label, { children: formatMessage({ id: "Settings.webhooks.form.headers", defaultMessage: "Headers" }) }), (0, import_jsx_runtime2.jsxs)(Box, { padding: 8, background: "neutral100", hasRadius: true, children: [ value.map((val, index) => { return (0, import_jsx_runtime2.jsxs)(Grid.Root, { gap: 4, padding: 2, children: [ (0, import_jsx_runtime2.jsx)(Grid.Item, { col: 6, direction: "column", alignItems: "stretch", children: (0, import_jsx_runtime2.jsx)(HeaderCombobox, { name: `headers.${index}.key`, "aria-label": `row ${index + 1} key`, label: formatMessage({ id: "Settings.webhooks.key", defaultMessage: "Key" }) }) }), (0, import_jsx_runtime2.jsx)(Grid.Item, { col: 6, direction: "column", alignItems: "stretch", children: (0, import_jsx_runtime2.jsxs)(Flex, { alignItems: "flex-end", gap: 2, children: [ (0, import_jsx_runtime2.jsx)(Box, { style: { flex: 1 }, children: (0, import_jsx_runtime2.jsx)(MemoizedStringInput, { name: `headers.${index}.value`, "aria-label": `row ${index + 1} value`, label: formatMessage({ id: "Settings.webhooks.value", defaultMessage: "Value" }), type: "string" }) }), (0, import_jsx_runtime2.jsx)(IconButton, { width: "4rem", height: "4rem", onClick: () => removeRow(index), color: "primary600", label: formatMessage({ id: "Settings.webhooks.headers.remove", defaultMessage: "Remove header row {number}" }, { number: index + 1 }), type: "button", children: (0, import_jsx_runtime2.jsx)(ForwardRef$21, { width: "0.8rem" }) }) ] }) }) ] }, `${index}-${JSON.stringify(val.key)}`); }), (0, import_jsx_runtime2.jsx)(Box, { paddingTop: 4, children: (0, import_jsx_runtime2.jsx)(AddHeaderButton, { type: "button", onClick: () => { addFieldRow("headers", { key: "", value: "" }); }, startIcon: (0, import_jsx_runtime2.jsx)(ForwardRef$1h, {}), children: formatMessage({ id: "Settings.webhooks.create.header", defaultMessage: "Create new header" }) }) }) ] }) ] }); }; var HeaderCombobox = ({ name, label, ...restProps }) => { const [options, setOptions] = React.useState([ ...HTTP_HEADERS ]); const { value: headers } = useField("headers"); const field = useField(name); React.useEffect(() => { const headerOptions = HTTP_HEADERS.filter((key) => !(headers == null ? void 0 : headers.some((header) => header.key !== field.value && header.key === key))); setOptions(headerOptions); }, [ headers, field.value ]); const handleChange = (value) => { field.onChange(name, value); }; const handleCreateOption = (value) => { setOptions((prev) => [ ...prev, value ]); if (value) { handleChange(value); } }; return (0, import_jsx_runtime2.jsxs)(Field.Root, { name, error: field.error, children: [ (0, import_jsx_runtime2.jsx)(Field.Label, { children: label }), (0, import_jsx_runtime2.jsx)(Combobox, { ...restProps, onClear: () => handleChange(""), onChange: handleChange, onCreateOption: handleCreateOption, placeholder: "", creatable: true, value: field.value, children: options.map((key) => (0, import_jsx_runtime2.jsx)(Option, { value: key, children: key }, key)) }), (0, import_jsx_runtime2.jsx)(Field.Error, {}) ] }); }; var HTTP_HEADERS = [ "A-IM", "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language", "Accept-Datetime", "Access-Control-Request-Method", "Access-Control-Request-Headers", "Authorization", "Cache-Control", "Connection", "Content-Length", "Content-Type", "Cookie", "Date", "Expect", "Forwarded", "From", "Host", "If-Match", "If-Modified-Since", "If-None-Match", "If-Range", "If-Unmodified-Since", "Max-Forwards", "Origin", "Pragma", "Proxy-Authorization", "Range", "Referer", "TE", "User-Agent", "Upgrade", "Via", "Warning" ]; // node_modules/@strapi/admin/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/TriggerContainer.mjs var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1); var TriggerContainer = ({ isPending, onCancel, response }) => { const { statusCode, message } = response ?? {}; const { formatMessage } = useIntl(); return (0, import_jsx_runtime3.jsx)(Box, { background: "neutral0", padding: 5, shadow: "filterShadow", hasRadius: true, children: (0, import_jsx_runtime3.jsxs)(Grid.Root, { gap: 4, style: { alignItems: "center" }, children: [ (0, import_jsx_runtime3.jsx)(Grid.Item, { col: 3, direction: "column", alignItems: "stretch", children: (0, import_jsx_runtime3.jsx)(Typography, { children: formatMessage({ id: "Settings.webhooks.trigger.test", defaultMessage: "Test-trigger" }) }) }), (0, import_jsx_runtime3.jsx)(Grid.Item, { col: 3, direction: "column", alignItems: "stretch", children: (0, import_jsx_runtime3.jsx)(Status, { isPending, statusCode }) }), (0, import_jsx_runtime3.jsx)(Grid.Item, { col: 6, direction: "column", alignItems: "stretch", children: !isPending ? (0, import_jsx_runtime3.jsx)(Message, { statusCode, message }) : (0, import_jsx_runtime3.jsx)(Flex, { justifyContent: "flex-end", children: (0, import_jsx_runtime3.jsx)("button", { onClick: onCancel, type: "button", children: (0, import_jsx_runtime3.jsxs)(Flex, { gap: 2, alignItems: "center", children: [ (0, import_jsx_runtime3.jsx)(Typography, { textColor: "neutral400", children: formatMessage({ id: "Settings.webhooks.trigger.cancel", defaultMessage: "cancel" }) }), (0, import_jsx_runtime3.jsx)(ForwardRef$45, { fill: "neutral400", height: "1.2rem", width: "1.2rem" }) ] }) }) }) }) ] }) }); }; var Status = ({ isPending, statusCode }) => { const { formatMessage } = useIntl(); if (isPending || !statusCode) { return (0, import_jsx_runtime3.jsxs)(Flex, { gap: 2, alignItems: "center", children: [ (0, import_jsx_runtime3.jsx)(ForwardRef$2j, { height: "1.2rem", width: "1.2rem" }), (0, import_jsx_runtime3.jsx)(Typography, { children: formatMessage({ id: "Settings.webhooks.trigger.pending", defaultMessage: "pending" }) }) ] }); } if (statusCode >= 200 && statusCode < 300) { return (0, import_jsx_runtime3.jsxs)(Flex, { gap: 2, alignItems: "center", children: [ (0, import_jsx_runtime3.jsx)(ForwardRef$4F, { fill: "success700", height: "1.2rem", width: "1.2rem" }), (0, import_jsx_runtime3.jsx)(Typography, { children: formatMessage({ id: "Settings.webhooks.trigger.success", defaultMessage: "success" }) }) ] }); } if (statusCode >= 300) { return (0, import_jsx_runtime3.jsxs)(Flex, { gap: 2, alignItems: "center", children: [ (0, import_jsx_runtime3.jsx)(ForwardRef$45, { fill: "danger700", height: "1.2rem", width: "1.2rem" }), (0, import_jsx_runtime3.jsxs)(Typography, { children: [ formatMessage({ id: "Settings.error", defaultMessage: "error" }), " ", statusCode ] }) ] }); } return null; }; var Message = ({ statusCode, message }) => { const { formatMessage } = useIntl(); if (!statusCode) { return null; } if (statusCode >= 200 && statusCode < 300) { return (0, import_jsx_runtime3.jsx)(Flex, { justifyContent: "flex-end", children: (0, import_jsx_runtime3.jsx)(Typography, { textColor: "neutral600", ellipsis: true, children: formatMessage({ id: "Settings.webhooks.trigger.success.label", defaultMessage: "Trigger succeeded" }) }) }); } if (statusCode >= 300) { return (0, import_jsx_runtime3.jsx)(Flex, { justifyContent: "flex-end", children: (0, import_jsx_runtime3.jsx)(Flex, { maxWidth: `25rem`, justifyContent: "flex-end", title: message, children: (0, import_jsx_runtime3.jsx)(Typography, { ellipsis: true, textColor: "neutral600", children: message }) }) }); } return null; }; // node_modules/@strapi/admin/dist/admin/admin/src/pages/Settings/pages/Webhooks/components/WebhookForm.mjs var WebhookForm = ({ handleSubmit, triggerWebhook, isCreating, isTriggering, triggerResponse, data }) => { const { formatMessage } = useIntl(); const [showTriggerResponse, setShowTriggerResponse] = React2.useState(false); const EventTable = useEnterprise(EventTableCE, async () => (await import("./EventsTable-XJDCSNI6.js")).EventsTableEE); const mapHeaders = (headers) => { if (!Object.keys(headers).length) { return [ { key: "", value: "" } ]; } return Object.entries(headers).map(([key, value]) => ({ key, value })); }; if (!EventTable) { return null; } return (0, import_jsx_runtime4.jsx)(Form, { initialValues: { name: (data == null ? void 0 : data.name) || "", url: (data == null ? void 0 : data.url) || "", headers: mapHeaders((data == null ? void 0 : data.headers) || {}), events: (data == null ? void 0 : data.events) || [] }, method: isCreating ? "POST" : "PUT", onSubmit: handleSubmit, validationSchema: makeWebhookValidationSchema({ formatMessage }), children: ({ isSubmitting, modified }) => (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [ (0, import_jsx_runtime4.jsx)(Layouts.Header, { primaryAction: (0, import_jsx_runtime4.jsxs)(Flex, { gap: 2, children: [ (0, import_jsx_runtime4.jsx)(Button, { onClick: () => { triggerWebhook(); setShowTriggerResponse(true); }, variant: "tertiary", startIcon: (0, import_jsx_runtime4.jsx)(ForwardRef$1j, {}), disabled: isCreating || isTriggering, children: formatMessage({ id: "Settings.webhooks.trigger", defaultMessage: "Trigger" }) }), (0, import_jsx_runtime4.jsx)(Button, { startIcon: (0, import_jsx_runtime4.jsx)(ForwardRef$4F, {}), type: "submit", disabled: !modified, loading: isSubmitting, children: formatMessage({ id: "global.save", defaultMessage: "Save" }) }) ] }), title: isCreating ? formatMessage({ id: "Settings.webhooks.create", defaultMessage: "Create a webhook" }) : data == null ? void 0 : data.name, navigationAction: (0, import_jsx_runtime4.jsx)(BackButton, { fallback: "../webhooks" }) }), (0, import_jsx_runtime4.jsx)(Layouts.Content, { children: (0, import_jsx_runtime4.jsxs)(Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [ showTriggerResponse && (0, import_jsx_runtime4.jsx)(TriggerContainer, { isPending: isTriggering, response: triggerResponse, onCancel: () => setShowTriggerResponse(false) }), (0, import_jsx_runtime4.jsx)(Box, { background: "neutral0", padding: 8, shadow: "filterShadow", hasRadius: true, children: (0, import_jsx_runtime4.jsxs)(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [ (0, import_jsx_runtime4.jsx)(Grid.Root, { gap: 6, children: [ { label: formatMessage({ id: "global.name", defaultMessage: "Name" }), name: "name", required: true, size: 6, type: "string" }, { label: formatMessage({ id: "Settings.roles.form.input.url", defaultMessage: "Url" }), name: "url", required: true, size: 12, type: "string" } ].map(({ size, ...field }) => (0, import_jsx_runtime4.jsx)(Grid.Item, { col: size, direction: "column", alignItems: "stretch", children: (0, import_jsx_runtime4.jsx)(MemoizedInputRenderer, { ...field }) }, field.name)) }), (0, import_jsx_runtime4.jsx)(HeadersInput, {}), (0, import_jsx_runtime4.jsx)(EventTable, {}) ] }) }) ] }) }) ] }) }); }; var NAME_REGEX = /(^$)|(^[A-Za-z][_0-9A-Za-z ]*$)/; var URL_REGEX = /(^$)|((https?:\/\/.*)(d*)\/?(.*))/; var makeWebhookValidationSchema = ({ formatMessage }) => create2().shape({ name: create().nullable().required(formatMessage({ id: "Settings.webhooks.validation.name.required", defaultMessage: "Name is required" })).matches(NAME_REGEX, formatMessage({ id: "Settings.webhooks.validation.name.regex", defaultMessage: "The name must start with a letter and only contain letters, numbers, spaces and underscores" })), url: create().nullable().required(formatMessage({ id: "Settings.webhooks.validation.url.required", defaultMessage: "Url is required" })).matches(URL_REGEX, formatMessage({ id: "Settings.webhooks.validation.url.regex", defaultMessage: "The value must be a valid Url" })), headers: create4((array) => { const baseSchema = create3(); if (array.length === 1) { const { key, value } = array[0]; if (!key && !value) { return baseSchema; } } return baseSchema.of(create2().shape({ key: create().required(formatMessage({ id: "Settings.webhooks.validation.key", defaultMessage: "Key is required" })).nullable(), value: create().required(formatMessage({ id: "Settings.webhooks.validation.value", defaultMessage: "Value is required" })).nullable() })); }), events: create3() }); // node_modules/@strapi/admin/dist/admin/admin/src/pages/Settings/pages/Webhooks/EditPage.mjs var cleanData = (data) => ({ ...data, headers: data.headers.reduce((acc, { key, value }) => { if (key !== "") { acc[key] = value; } return acc; }, {}) }); var EditPage = () => { const { formatMessage } = useIntl(); const match = useMatch("/settings/webhooks/:id"); const id = match == null ? void 0 : match.params.id; const isCreating = id === "create"; const navigate = useNavigate(); const { toggleNotification } = useNotification(); const { _unstableFormatAPIError: formatAPIError, _unstableFormatValidationErrors: formatValidationErrors } = useAPIErrorHandler(); const stableFormatAPIError = React3.useCallback(formatAPIError, []); const [isTriggering, setIsTriggering] = React3.useState(false); const [triggerResponse, setTriggerResponse] = React3.useState(); const { isLoading, webhooks, error, createWebhook, updateWebhook, triggerWebhook } = useWebhooks({ id }, { skip: isCreating }); React3.useEffect(() => { if (error) { toggleNotification({ type: "danger", message: stableFormatAPIError(error) }); } }, [ error, toggleNotification, stableFormatAPIError ]); const handleTriggerWebhook = async () => { try { setIsTriggering(true); const res = await triggerWebhook(id); if ("error" in res) { toggleNotification({ type: "danger", message: formatAPIError(res.error) }); return; } setTriggerResponse(res.data); } catch { toggleNotification({ type: "danger", message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" }) }); } finally { setIsTriggering(false); } }; const handleSubmit = async (data, helpers) => { try { if (isCreating) { const res = await createWebhook(cleanData(data)); if ("error" in res) { if (isBaseQueryError(res.error) && res.error.name === "ValidationError") { helpers.setErrors(formatValidationErrors(res.error)); } else { toggleNotification({ type: "danger", message: formatAPIError(res.error) }); } return; } toggleNotification({ type: "success", message: formatMessage({ id: "Settings.webhooks.created" }) }); navigate(`../webhooks/${res.data.id}`, { replace: true }); } else { const res = await updateWebhook({ id, ...cleanData(data) }); if ("error" in res) { if (isBaseQueryError(res.error) && res.error.name === "ValidationError") { helpers.setErrors(formatValidationErrors(res.error)); } else { toggleNotification({ type: "danger", message: formatAPIError(res.error) }); } return; } toggleNotification({ type: "success", message: formatMessage({ id: "notification.form.success.fields" }) }); } } catch { toggleNotification({ type: "danger", message: formatMessage({ id: "notification.error", defaultMessage: "An error occurred" }) }); } }; if (isLoading) { return (0, import_jsx_runtime5.jsx)(Page.Loading, {}); } const [webhook] = webhooks ?? []; return (0, import_jsx_runtime5.jsxs)(Main, { children: [ (0, import_jsx_runtime5.jsx)(Page.Title, { children: formatMessage({ id: "Settings.PageTitle", defaultMessage: "Settings - {name}" }, { name: "Webhooks" }) }), (0, import_jsx_runtime5.jsx)(WebhookForm, { data: webhook, handleSubmit, triggerWebhook: handleTriggerWebhook, isCreating, isTriggering, triggerResponse }) ] }); }; var ProtectedEditPage = () => { var _a; const permissions = useTypedSelector(selectAdminPermissions); return (0, import_jsx_runtime5.jsx)(Page.Protect, { permissions: (_a = permissions.settings) == null ? void 0 : _a.webhooks.update, children: (0, import_jsx_runtime5.jsx)(EditPage, {}) }); }; export { EditPage, ProtectedEditPage }; //# sourceMappingURL=chunk-SOIQOVFG.js.map