translations were added
This commit is contained in:
parent
1b823190a1
commit
073b01d2cf
68
packages/client/public/locales/en/Webhooks.json
Normal file
68
packages/client/public/locales/en/Webhooks.json
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"Webhook": "Webhook",
|
||||
"Webhooks": "Webhooks",
|
||||
"CreateWebhook": "Create webhook",
|
||||
"WebhooksInfo": "Use webhooks to perform custom actions on the side of any application or website you are using based on various events in ONLYOFFICE Docspace.\r\nHere, you can create and manage all your webhooks, configure them, and browse history of every webhook to audit their performance.",
|
||||
"WebhooksGuide": "Webhooks guide",
|
||||
"WebhookCreationHint": "This webhook will be assigned to all events in DocSpace",
|
||||
"WebhookName": "Webhook name",
|
||||
"EnterWebhookName": "Enter webhook name",
|
||||
"PayloadUrl": "Payload URL",
|
||||
"EnterUrl": "Enter URL",
|
||||
"SSLVerification": "SSL verification",
|
||||
"SSLHint": "By default, we verify SSL certificates when delivering payloads.",
|
||||
"EnableSSL": "Enable SSL verification",
|
||||
"DisableSSL": "Disable (not recommended)",
|
||||
"EnterSecretKey": "Enter secret key",
|
||||
"SecretKey": "Secret key",
|
||||
"SecretKeyHint": "Setting a webhook secret allows you to verify requests sent to the payload URL.",
|
||||
"ReadMore": "Read more",
|
||||
"SecretKeyWarning": "You cannot retrieve your secret key again once it has been saved. If you've lost or forgotten this secret key, you can reset it, but all integrations using this secret will need to be updated.",
|
||||
"ResetKey": "Reset key",
|
||||
"Generate": "Generate",
|
||||
"Save": "Save",
|
||||
"Cancel": "Cancel",
|
||||
"DeleteHint": "The webhook will be deleted permanently.\r\nYou will not be able to undo this action.",
|
||||
"DeleteForever": "Delete forever",
|
||||
"NotSent": "Not sent",
|
||||
"WebhookEditedSuccessfully": "Webhook configuration edited successfully",
|
||||
"WebhookRemoved": "Webhook removed",
|
||||
"WebhookHistory": "Webhook history",
|
||||
"DeleteWebhook": "Delete webhook",
|
||||
"SettingsWebhook": "Settings webhook",
|
||||
"DeleteWebhookForeverQuestion": "Delete Webhook forever?",
|
||||
"URL": "URL",
|
||||
"State": "State",
|
||||
"WebhookRedilivered": "Webhook redelivered",
|
||||
"WebhookDetails": "Webhooks details",
|
||||
"Request": "Request",
|
||||
"Response": "Response",
|
||||
"FailedToConnect": "We couldn’t deliver this payload: failed to connect to host",
|
||||
"RequestPostHeader": "Request post header",
|
||||
"RequestPostBody": "Request post body",
|
||||
"RequestHeaderCopied": "Request post header successfully copied to clipboard",
|
||||
"RequestBodyCopied": "Request post body successfully copied to clipboard",
|
||||
"ResponsePostHeader": "Response post header",
|
||||
"ResponsePostBody": "Response post body",
|
||||
"ResponseHeaderCopied": "Response post header successfully copied to clipboard",
|
||||
"ResponseBodyCopied": "Response post body successfully copied to clipboard",
|
||||
"PayloadIsTooLarge": "Payload is too large to display.",
|
||||
"ViewRawPayload": "View raw payload",
|
||||
"Retry": "Retry",
|
||||
"UnselectAll": "Unselect all",
|
||||
"History": "History",
|
||||
"EventHint": "Deliveries are automatically deleted after 15 days",
|
||||
"NothingFound": "Nothing found",
|
||||
"NoResultsMatched": "No results match this filter. Try a different one or clear filter to view all items.",
|
||||
"SearchOptions": "Search options",
|
||||
"Apply": "Apply",
|
||||
"SelectDate": "Select date",
|
||||
"SelectDeliveryTime": "Select Delivery time",
|
||||
"DeliveryDate": "Delivery date",
|
||||
"From": "From",
|
||||
"Before": "Before",
|
||||
"Status": "Status",
|
||||
"EventID": "Event ID",
|
||||
"Delivery": "Delivery",
|
||||
"Add": "Add"
|
||||
}
|
@ -14,6 +14,7 @@ import Headline from "@docspace/common/components/Headline";
|
||||
import IconButton from "@docspace/components/icon-button";
|
||||
|
||||
import { tablet } from "@docspace/components/utils/device";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const HeaderContainer = styled.div`
|
||||
position: sticky;
|
||||
@ -42,13 +43,17 @@ const HeaderContainer = styled.div`
|
||||
|
||||
const DetailsNavigationHeader = (props) => {
|
||||
const { eventId, retryWebhookEvent } = props;
|
||||
const { t } = useTranslation(["Webhooks", "Common"]);
|
||||
const navigate = useNavigate();
|
||||
const onBack = () => {
|
||||
navigate(-1);
|
||||
};
|
||||
const handleRetryEvent = async () => {
|
||||
await retryWebhookEvent(eventId);
|
||||
toastr.success("Webhook retry again", <b>Done</b>);
|
||||
toastr.success(
|
||||
t("WebhookRedilivered", { ns: "Webhooks" }),
|
||||
<b>{t("Done", { ns: "Common" })}</b>,
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -61,7 +66,7 @@ const DetailsNavigationHeader = (props) => {
|
||||
className="arrow-button"
|
||||
/>
|
||||
<Headline type="content" truncate={true} className="headline">
|
||||
Webhook details
|
||||
{t("WebhookDetails", { ns: "Webhooks" })}
|
||||
</Headline>
|
||||
<IconButton iconName={RetryIcon} size="17" isFill={true} onClick={handleRetryEvent} />
|
||||
|
||||
|
@ -4,6 +4,7 @@ import Submenu from "@docspace/components/submenu";
|
||||
|
||||
import { RequestDetails } from "./RequestDetails";
|
||||
import { ResponseDetails } from "./ResponseDetails";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const SubmenuWrapper = styled.div`
|
||||
.sticky {
|
||||
@ -13,10 +14,11 @@ const SubmenuWrapper = styled.div`
|
||||
`;
|
||||
|
||||
export const MessagesDetails = ({ webhookDetails }) => {
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
const menuData = [
|
||||
{
|
||||
id: "webhookRequest",
|
||||
name: "Request",
|
||||
name: t("Request", { ns: "Webhooks" }),
|
||||
content: <RequestDetails webhookDetails={webhookDetails} />,
|
||||
},
|
||||
];
|
||||
@ -25,7 +27,7 @@ export const MessagesDetails = ({ webhookDetails }) => {
|
||||
webhookDetails.status < 500 &&
|
||||
menuData.push({
|
||||
id: "webhookResponse",
|
||||
name: "Response",
|
||||
name: t("Response", { ns: "Webhooks" }),
|
||||
content: <ResponseDetails webhookDetails={webhookDetails} />,
|
||||
});
|
||||
|
||||
|
@ -3,6 +3,7 @@ import styled from "styled-components";
|
||||
import { Text, Textarea } from "@docspace/components";
|
||||
|
||||
import DangerIcon from "PUBLIC_DIR/images/danger.toast.react.svg?url";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const DetailsWrapper = styled.div`
|
||||
width: 100%;
|
||||
@ -24,16 +25,17 @@ const ErrorMessageTooltip = styled.div`
|
||||
`;
|
||||
|
||||
export const RequestDetails = ({ webhookDetails }) => {
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
return (
|
||||
<DetailsWrapper>
|
||||
{webhookDetails.status === 0 && (
|
||||
<ErrorMessageTooltip>
|
||||
<img src={DangerIcon} alt="danger icon" style={{ marginRight: "8px" }} />
|
||||
We couldn’t deliver this payload: failed to connect to host
|
||||
{t("FailedToConnect", { ns: "Webhooks" })}
|
||||
</ErrorMessageTooltip>
|
||||
)}
|
||||
<Text as="h3" fontWeight={600} style={{ marginBottom: "4px" }}>
|
||||
Request post header
|
||||
{t("RequestPostHeader", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
{!webhookDetails.requestHeaders ? (
|
||||
<Textarea isDisabled />
|
||||
@ -44,12 +46,12 @@ export const RequestDetails = ({ webhookDetails }) => {
|
||||
hasNumeration
|
||||
isFullHeight
|
||||
isJSONField
|
||||
copyInfoText="Request post header successfully copied to clipboard"
|
||||
copyInfoText={t("RequestHeaderCopied", { ns: "Webhooks" })}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Text as="h3" fontWeight={600} style={{ marginBottom: "4px", marginTop: "16px" }}>
|
||||
Request post body
|
||||
{t("RequestPostBody", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
<Textarea
|
||||
value={webhookDetails.requestPayload}
|
||||
@ -57,7 +59,7 @@ export const RequestDetails = ({ webhookDetails }) => {
|
||||
enableCopy
|
||||
hasNumeration
|
||||
isFullHeight
|
||||
copyInfoText="Request post body successfully copied to clipboard"
|
||||
copyInfoText={t("RequestBodyCopied", { ns: "Webhooks" })}
|
||||
/>
|
||||
</DetailsWrapper>
|
||||
);
|
||||
|
@ -4,6 +4,7 @@ import { Text, Textarea, Button } from "@docspace/components";
|
||||
|
||||
import json_beautifier from "csvjson-json_beautifier";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const DetailsWrapper = styled.div`
|
||||
width: 100%;
|
||||
@ -48,6 +49,7 @@ function isJSON(jsonString) {
|
||||
|
||||
export const ResponseDetails = ({ webhookDetails }) => {
|
||||
const responsePayload = webhookDetails.responsePayload?.trim();
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
|
||||
const beautifiedJSON = isJSON(responsePayload)
|
||||
? json_beautifier(JSON.parse(responsePayload), {
|
||||
@ -70,7 +72,7 @@ export const ResponseDetails = ({ webhookDetails }) => {
|
||||
return (
|
||||
<DetailsWrapper>
|
||||
<Text as="h3" fontWeight={600} style={{ marginBottom: "4px" }}>
|
||||
Response post header
|
||||
{t("ResponsePostHeader", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
<Textarea
|
||||
value={webhookDetails.responseHeaders}
|
||||
@ -78,20 +80,20 @@ export const ResponseDetails = ({ webhookDetails }) => {
|
||||
hasNumeration
|
||||
isFullHeight
|
||||
isJSONField
|
||||
copyInfoText="Response post header successfully copied to clipboard"
|
||||
copyInfoText={t("ResponseHeaderCopied", { ns: "Webhooks" })}
|
||||
/>
|
||||
<Text as="h3" fontWeight={600} style={{ marginBottom: "4px", marginTop: "16px" }}>
|
||||
Response post body
|
||||
{t("ResponsePostBody", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
{responsePayload.length > 4000 || numberOfLines > 100 ? (
|
||||
<LargePayloadStub>
|
||||
<Text fontWeight={600} color="#657077">
|
||||
Payload is too large to display.
|
||||
{t("PayloadIsTooLarge", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
<Button
|
||||
size="small"
|
||||
onClick={openRawPayload}
|
||||
label="View raw payload"
|
||||
label={t("ViewRawPayload", { ns: "Webhooks" })}
|
||||
scale={isMobileOnly}
|
||||
/>
|
||||
</LargePayloadStub>
|
||||
@ -104,7 +106,7 @@ export const ResponseDetails = ({ webhookDetails }) => {
|
||||
enableCopy
|
||||
hasNumeration
|
||||
isFullHeight
|
||||
copyInfoText="Response post body successfully copied to clipboard"
|
||||
copyInfoText={t("ResponseBodyCopied", { ns: "Webhooks" })}
|
||||
/>
|
||||
) : (
|
||||
<Textarea
|
||||
@ -112,7 +114,7 @@ export const ResponseDetails = ({ webhookDetails }) => {
|
||||
enableCopy
|
||||
heightScale
|
||||
className="textareaBody"
|
||||
copyInfoText="Response post body successfully copied to clipboard"
|
||||
copyInfoText={t("ResponseBodyCopied", { ns: "Webhooks" })}
|
||||
/>
|
||||
)}
|
||||
</DetailsWrapper>
|
||||
|
@ -7,6 +7,7 @@ import { Text } from "@docspace/components";
|
||||
import { Link } from "@docspace/components";
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const EmptyFilterWrapper = styled.div`
|
||||
width: 100%;
|
||||
@ -39,6 +40,7 @@ const EmptyFilterContent = styled.div`
|
||||
|
||||
const EmptyFilter = (props) => {
|
||||
const { applyFilters, formatFilters, clearHistoryFilters } = props;
|
||||
const { t } = useTranslation(["Webhooks", "Common"]);
|
||||
|
||||
const clearFilters = () => {
|
||||
clearHistoryFilters(null);
|
||||
@ -56,15 +58,15 @@ const EmptyFilter = (props) => {
|
||||
<img src={EmptyFilterImg} alt="Empty filter" />
|
||||
<div className="emptyFilterText">
|
||||
<Text fontSize="16px" fontWeight={700} as="p" className="emptyFilterHeading">
|
||||
Nothing found
|
||||
{t("NothingFound", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
<Text fontSize="12px" color="#555F65">
|
||||
No results match this filter. Try a different one or clear filter to view all items.
|
||||
{t("NoResultsMatched", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
<span className="clearFilter" onClick={clearFilters}>
|
||||
<img src={ClearEmptyFilterIcon} alt="Clear filter" className="clearFilterIcon" />
|
||||
<img src={ClearEmptyFilterIcon} alt={t("ClearFilter", { ns: "Webhooks" })} className="clearFilterIcon" />
|
||||
<Link color="#657077" isHovered fontWeight={600}>
|
||||
Clear filter
|
||||
{t("ClearFilter", { ns: "Common" })}
|
||||
</Link>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -12,6 +12,8 @@ import { Calendar } from "@docspace/components";
|
||||
import { TimePicker } from "@docspace/components";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const TimePickerCell = styled.span`
|
||||
margin-left: 8px;
|
||||
display: inline-flex;
|
||||
@ -39,6 +41,8 @@ const DeliveryDatePicker = ({ Selectors, filters, setFilters, isApplied, setIsAp
|
||||
const [isCalendarOpen, setIsCalendarOpen] = useState(false);
|
||||
const [isTimeOpen, setIsTimeOpen] = useState(false);
|
||||
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
|
||||
const calendarRef = useRef();
|
||||
const selectorRef = useRef();
|
||||
|
||||
@ -95,9 +99,13 @@ const DeliveryDatePicker = ({ Selectors, filters, setFilters, isApplied, setIsAp
|
||||
|
||||
const DateSelector = () => (
|
||||
<div>
|
||||
<SelectorAddButton title="add" onClick={toggleCalendar} style={{ marginRight: "8px" }} />
|
||||
<SelectorAddButton
|
||||
title={t("Add", { ns: "Webhooks" })}
|
||||
onClick={toggleCalendar}
|
||||
style={{ marginRight: "8px" }}
|
||||
/>
|
||||
<Text isInline fontWeight={600} color="#A3A9AE">
|
||||
Select date
|
||||
{t("SelectDate", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
{isCalendarOpen && <CalendarElement />}
|
||||
</div>
|
||||
@ -140,9 +148,13 @@ const DeliveryDatePicker = ({ Selectors, filters, setFilters, isApplied, setIsAp
|
||||
|
||||
const TimeSelectorAdder = () => (
|
||||
<TimePickerCell>
|
||||
<SelectorAddButton title="add" onClick={showTimePicker} style={{ marginRight: "8px" }} />
|
||||
<SelectorAddButton
|
||||
title={t("Add", { ns: "Webhooks" })}
|
||||
onClick={showTimePicker}
|
||||
style={{ marginRight: "8px" }}
|
||||
/>
|
||||
<Text isInline fontWeight={600} color="#A3A9AE">
|
||||
Select Delivery time
|
||||
{t("SelectDeliveryTime", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
</TimePickerCell>
|
||||
);
|
||||
@ -160,7 +172,7 @@ const DeliveryDatePicker = ({ Selectors, filters, setFilters, isApplied, setIsAp
|
||||
return (
|
||||
<>
|
||||
<Text fontWeight={600} fontSize="15px">
|
||||
Delivery date
|
||||
{t("DeliveryDate", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
<Selectors ref={selectorRef}>
|
||||
{filters.deliveryDate === null ? (
|
||||
@ -180,7 +192,7 @@ const DeliveryDatePicker = ({ Selectors, filters, setFilters, isApplied, setIsAp
|
||||
<TimePickerCell>
|
||||
<span className="timePickerItem">
|
||||
<Text isInline fontWeight={600} color="#A3A9AE" style={{ marginRight: "8px" }}>
|
||||
From
|
||||
{t("From", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
<TimePicker
|
||||
date={filters.deliveryFrom}
|
||||
@ -190,7 +202,7 @@ const DeliveryDatePicker = ({ Selectors, filters, setFilters, isApplied, setIsAp
|
||||
/>
|
||||
</span>
|
||||
<Text isInline fontWeight={600} color="#A3A9AE" style={{ marginRight: "8px" }}>
|
||||
Before
|
||||
{t("Before", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
<TimePicker
|
||||
date={filters.deliveryTo}
|
||||
|
@ -4,6 +4,7 @@ import { inject, observer } from "mobx-react";
|
||||
|
||||
import { Text } from "@docspace/components";
|
||||
import { Button } from "@docspace/components";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const RoundedButton = styled(Button)`
|
||||
font-size: 13px;
|
||||
@ -14,11 +15,20 @@ const RoundedButton = styled(Button)`
|
||||
`;
|
||||
|
||||
const StatusPicker = ({ Selectors, filters, setFilters }) => {
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
|
||||
const StatusCodes = {
|
||||
0: "Not sent",
|
||||
200: "2XX",
|
||||
300: "3XX",
|
||||
400: "4XX",
|
||||
500: "5XX",
|
||||
};
|
||||
|
||||
const isStatusSelected = (statusCode) => {
|
||||
return filters.status.includes(statusCode);
|
||||
};
|
||||
const handleStatusClick = (e) => {
|
||||
const statusCode = e.target.textContent;
|
||||
const handleStatusClick = (statusCode) => {
|
||||
setFilters((prevFilters) => ({
|
||||
...prevFilters,
|
||||
status: prevFilters.status.includes(statusCode)
|
||||
@ -29,18 +39,34 @@ const StatusPicker = ({ Selectors, filters, setFilters }) => {
|
||||
return (
|
||||
<>
|
||||
<Text fontWeight={600} fontSize="15px">
|
||||
Status
|
||||
{t("Status", { ns: "Webhooks" })}
|
||||
</Text>
|
||||
<Selectors>
|
||||
<RoundedButton
|
||||
label="Not sent"
|
||||
onClick={handleStatusClick}
|
||||
primary={isStatusSelected("Not sent")}
|
||||
label={t("NotSent", { ns: "Webhooks" })}
|
||||
onClick={() => handleStatusClick(StatusCodes[0])}
|
||||
primary={isStatusSelected(StatusCodes[0])}
|
||||
/>
|
||||
<RoundedButton
|
||||
label={StatusCodes[200]}
|
||||
onClick={() => handleStatusClick(StatusCodes[200])}
|
||||
primary={isStatusSelected(StatusCodes[200])}
|
||||
/>
|
||||
<RoundedButton
|
||||
label={StatusCodes[300]}
|
||||
onClick={() => handleStatusClick(StatusCodes[300])}
|
||||
primary={isStatusSelected(StatusCodes[300])}
|
||||
/>
|
||||
<RoundedButton
|
||||
label={StatusCodes[400]}
|
||||
onClick={() => handleStatusClick(StatusCodes[400])}
|
||||
primary={isStatusSelected(StatusCodes[400])}
|
||||
/>
|
||||
<RoundedButton
|
||||
label={StatusCodes[500]}
|
||||
onClick={() => handleStatusClick(StatusCodes[500])}
|
||||
primary={isStatusSelected(StatusCodes[500])}
|
||||
/>
|
||||
<RoundedButton label="2XX" onClick={handleStatusClick} primary={isStatusSelected("2XX")} />
|
||||
<RoundedButton label="3XX" onClick={handleStatusClick} primary={isStatusSelected("3XX")} />
|
||||
<RoundedButton label="4XX" onClick={handleStatusClick} primary={isStatusSelected("4XX")} />
|
||||
<RoundedButton label="5XX" onClick={handleStatusClick} primary={isStatusSelected("5XX")} />
|
||||
</Selectors>
|
||||
</>
|
||||
);
|
||||
|
@ -9,6 +9,8 @@ import { Button } from "@docspace/components";
|
||||
import DeliveryDatePicker from "./DeliveryDatePicker";
|
||||
import StatusPicker from "./StatusPicker";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const Footer = styled.div`
|
||||
width: 100%;
|
||||
display: flex;
|
||||
@ -34,6 +36,7 @@ const Separator = styled.hr`
|
||||
|
||||
const FilterDialog = (props) => {
|
||||
const { visible, closeModal, applyFilters, formatFilters, setHistoryFilters } = props;
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
|
||||
const [filters, setFilters] = useState({
|
||||
deliveryDate: null,
|
||||
@ -58,7 +61,7 @@ const FilterDialog = (props) => {
|
||||
|
||||
return (
|
||||
<ModalDialog withFooterBorder visible={visible} onClose={closeModal} displayType="aside">
|
||||
<ModalDialog.Header>Search options</ModalDialog.Header>
|
||||
<ModalDialog.Header>{t("SearchOptions", { ns: "Webhooks" })}</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<DeliveryDatePicker
|
||||
Selectors={Selectors}
|
||||
@ -74,8 +77,13 @@ const FilterDialog = (props) => {
|
||||
|
||||
<ModalDialog.Footer>
|
||||
<Footer>
|
||||
<Button label="Apply" size="normal" primary={true} onClick={handleApplyFilters} />
|
||||
<Button label="Cancel" size="normal" onClick={closeModal} />
|
||||
<Button
|
||||
label={t("Apply", { ns: "Webhooks" })}
|
||||
size="normal"
|
||||
primary={true}
|
||||
onClick={handleApplyFilters}
|
||||
/>
|
||||
<Button label={t("Cancel", { ns: "Webhooks" })} size="normal" onClick={closeModal} />
|
||||
</Footer>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialog>
|
||||
|
@ -9,6 +9,7 @@ import IconButton from "@docspace/components/icon-button";
|
||||
import { useParams } from "react-router-dom";
|
||||
import FilterDialog from "./FilterDialog";
|
||||
import StatusBar from "./StatusBar";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const ListHeader = styled.header`
|
||||
display: flex;
|
||||
@ -54,6 +55,7 @@ const FilterButton = styled.div`
|
||||
|
||||
const HistoryFilterHeader = (props) => {
|
||||
const { applyFilters, historyFilters } = props;
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
const { id } = useParams();
|
||||
|
||||
const [isFiltersVisible, setIsFiltersVisible] = useState(false);
|
||||
@ -69,7 +71,9 @@ const HistoryFilterHeader = (props) => {
|
||||
return (
|
||||
<div>
|
||||
<ListHeader>
|
||||
<ListHeading>Webhook {id}</ListHeading>
|
||||
<ListHeading>
|
||||
{t("Webhook", { ns: "Webhooks" })} {id}
|
||||
</ListHeading>
|
||||
|
||||
<FilterButton onClick={openFiltersModal}>
|
||||
<IconButton iconName={FilterReactSvrUrl} size={16} />
|
||||
|
@ -17,6 +17,7 @@ import { isMobile, isMobileOnly } from "react-device-detect";
|
||||
import DropDownItem from "@docspace/components/drop-down-item";
|
||||
|
||||
import toastr from "@docspace/components/toast/toastr";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const HeaderContainer = styled.div`
|
||||
position: sticky;
|
||||
@ -97,6 +98,7 @@ const HistoryHeader = (props) => {
|
||||
const onBack = () => {
|
||||
navigate(-1);
|
||||
};
|
||||
const { t } = useTranslation(["Webhooks", "Common"]);
|
||||
|
||||
const handleGroupSelection = (isChecked) => {
|
||||
isChecked ? checkAllIds() : emptyCheckedIds();
|
||||
@ -104,13 +106,16 @@ const HistoryHeader = (props) => {
|
||||
|
||||
const handleRetryAll = async () => {
|
||||
await retryWebhookEvents(checkedEventIds);
|
||||
toastr.success(`Webhooks redelivered: ${checkedEventIds.length}`, <b>Done</b>);
|
||||
toastr.success(
|
||||
`${t("WebhookRedilivered", { ns: "Webhooks" })}: ${checkedEventIds.length}`,
|
||||
<b>{t("Done", { ns: "Common" })}</b>,
|
||||
);
|
||||
};
|
||||
|
||||
const headerMenu = [
|
||||
{
|
||||
id: "retry-event-option",
|
||||
label: "Retry",
|
||||
label: t("Retry", { ns: "Webhooks" }),
|
||||
onClick: handleRetryAll,
|
||||
iconUrl: RetryIcon,
|
||||
},
|
||||
@ -120,13 +125,13 @@ const HistoryHeader = (props) => {
|
||||
<>
|
||||
<DropDownItem
|
||||
key="select-all-event-ids"
|
||||
label="Select all"
|
||||
label={t("SelectAll", { ns: "Commmon" })}
|
||||
data-index={0}
|
||||
onClick={() => checkAllIds()}
|
||||
/>
|
||||
<DropDownItem
|
||||
key="unselect-all-event-ids"
|
||||
label="Unselect all"
|
||||
label={t("UnselectAll", { ns: "Webhooks" })}
|
||||
data-index={1}
|
||||
onClick={emptyCheckedIds}
|
||||
/>
|
||||
@ -143,10 +148,10 @@ const HistoryHeader = (props) => {
|
||||
className="arrow-button"
|
||||
/>
|
||||
<Headline type="content" truncate={true} className="headline">
|
||||
History
|
||||
{t("History", { ns: "Webhooks" })}
|
||||
</Headline>
|
||||
<Hint backgroundColor="#F8F9F9" color="#555F65">
|
||||
Deliveries are automatically deleted after 15 days
|
||||
{t("EventHint", { ns: "Webhooks" })}
|
||||
</Hint>
|
||||
</>
|
||||
);
|
||||
|
@ -11,27 +11,33 @@ import InfoIcon from "PUBLIC_DIR/images/info.outline.react.svg?url";
|
||||
|
||||
import toastr from "@docspace/components/toast/toastr";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const HistoryRow = (props) => {
|
||||
const { historyItem, sectionWidth, toggleEventId, isIdChecked, retryWebhookEvent } = props;
|
||||
const { t } = useTranslation(["Webhooks", "Common"]);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const redirectToDetails = () => navigate(window.location.pathname + `/${historyItem.id}`);
|
||||
const handleRetryEvent = async () => {
|
||||
await retryWebhookEvent(historyItem.id);
|
||||
toastr.success("Webhook redelivered", <b>Done</b>);
|
||||
toastr.success(
|
||||
t("WebhookRedilivered", { ns: "Webhooks" }),
|
||||
<b>{t("Done", { ns: "Common" })}</b>,
|
||||
);
|
||||
};
|
||||
const handleOnSelect = () => toggleEventId(historyItem.id);
|
||||
|
||||
const contextOptions = [
|
||||
{
|
||||
key: "Webhook details dropdownItem",
|
||||
label: "Webhook details",
|
||||
label: t("WebhookDetails", { ns: "Webhooks" }),
|
||||
icon: InfoIcon,
|
||||
onClick: redirectToDetails,
|
||||
},
|
||||
{
|
||||
key: "Retry dropdownItem",
|
||||
label: "Retry",
|
||||
label: t("Retry", { ns: "Webhooks" }),
|
||||
icon: RetryIcon,
|
||||
onClick: handleRetryEvent,
|
||||
},
|
||||
|
@ -1,14 +1,16 @@
|
||||
import React, { useRef } from "react";
|
||||
import TableHeader from "@docspace/components/table-container/TableHeader";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const HistoryTableHeader = (props) => {
|
||||
const { sectionWidth, tableRef } = props;
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
|
||||
const columns = useRef([
|
||||
{
|
||||
key: "Event ID",
|
||||
title: "Event ID",
|
||||
title: t("EventID", { ns: "Webhooks" }),
|
||||
resizable: true,
|
||||
enable: true,
|
||||
default: true,
|
||||
@ -16,13 +18,13 @@ const HistoryTableHeader = (props) => {
|
||||
},
|
||||
{
|
||||
key: "Status",
|
||||
title: "Status",
|
||||
title: t("Status", { ns: "Webhooks" }),
|
||||
enable: true,
|
||||
resizable: true,
|
||||
},
|
||||
{
|
||||
key: "Delivery",
|
||||
title: "Delivery",
|
||||
title: t("Delivery", { ns: "Webhooks" }),
|
||||
enable: true,
|
||||
resizable: true,
|
||||
},
|
||||
|
@ -16,6 +16,8 @@ import toastr from "@docspace/components/toast/toastr";
|
||||
import RetryIcon from "PUBLIC_DIR/images/refresh.react.svg?url";
|
||||
import InfoIcon from "PUBLIC_DIR/images/info.outline.react.svg?url";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const StyledTableRow = styled(TableRow)`
|
||||
${(props) =>
|
||||
props.isHighlight &&
|
||||
@ -32,24 +34,28 @@ const StyledWrapper = styled.div`
|
||||
|
||||
const HistoryTableRow = (props) => {
|
||||
const { item, toggleEventId, isIdChecked, retryWebhookEvent } = props;
|
||||
const { t } = useTranslation(["Webhooks", "Common"]);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const redirectToDetails = () => navigate(window.location.pathname + `/${item.id}`);
|
||||
const handleRetryEvent = async () => {
|
||||
await retryWebhookEvent(item.id);
|
||||
toastr.success("Webhook redelivered", <b>Done</b>);
|
||||
toastr.success(
|
||||
t("WebhookRedilivered", { ns: "Webhooks" }),
|
||||
<b>{t("Done", { ns: "Common" })}</b>,
|
||||
);
|
||||
};
|
||||
|
||||
const contextOptions = [
|
||||
{
|
||||
key: "Webhook details dropdownItem",
|
||||
label: "Webhook details",
|
||||
label: t("WebhookDetails", { ns: "Webhooks" }),
|
||||
icon: InfoIcon,
|
||||
onClick: redirectToDetails,
|
||||
},
|
||||
{
|
||||
key: "Retry dropdownItem",
|
||||
label: "Retry",
|
||||
label: t("Retry", { ns: "Webhooks" }),
|
||||
icon: RetryIcon,
|
||||
onClick: handleRetryEvent,
|
||||
},
|
||||
@ -71,7 +77,7 @@ const HistoryTableRow = (props) => {
|
||||
<StyledTableRow contextOptions={contextOptions} checked={isChecked}>
|
||||
<TableCell>
|
||||
<TableCell checked={isChecked} className="noPadding">
|
||||
<Checkbox onChange={onChange} isChecked={isChecked} title="TitleSelectFile" />
|
||||
<Checkbox onChange={onChange} isChecked={isChecked} />
|
||||
</TableCell>
|
||||
|
||||
<Text fontWeight={600}>{item.id}</Text>
|
||||
|
@ -11,6 +11,8 @@ import { WebhookConfigsLoader } from "./sub-components/Loaders";
|
||||
|
||||
import { isMobile } from "@docspace/components/utils/device";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const MainWrapper = styled.div`
|
||||
width: 100%;
|
||||
|
||||
@ -35,7 +37,9 @@ const Webhooks = (props) => {
|
||||
const { state, loadWebhooks, addWebhook, isWebhookExist, isWebhooksEmpty, setDocumentTitle } =
|
||||
props;
|
||||
|
||||
setDocumentTitle("Webhooks");
|
||||
const { t, ready } = useTranslation(["Webhooks", "Common"]);
|
||||
|
||||
setDocumentTitle(t("Webhooks", { ns: "Webhooks" }));
|
||||
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
@ -53,13 +57,13 @@ const Webhooks = (props) => {
|
||||
loadWebhooks();
|
||||
}, []);
|
||||
|
||||
return state === "pending" ? (
|
||||
return state === "pending" || !ready ? (
|
||||
<WebhookConfigsLoader />
|
||||
) : state === "success" ? (
|
||||
<MainWrapper>
|
||||
<WebhookInfo />
|
||||
<StyledCreateButton
|
||||
label="Create webhook"
|
||||
label={t("CreateWebhook", { ns: "Webhooks" })}
|
||||
primary
|
||||
size={isMobile() ? "normal" : "small"}
|
||||
onClick={openModal}
|
||||
@ -68,12 +72,12 @@ const Webhooks = (props) => {
|
||||
<WebhookDialog
|
||||
visible={isModalOpen}
|
||||
onClose={closeModal}
|
||||
header="Create webhook"
|
||||
header={t("CreateWebhook", { ns: "Webhooks" })}
|
||||
onSubmit={onCreateWebhook}
|
||||
/>
|
||||
</MainWrapper>
|
||||
) : state === "error" ? (
|
||||
"error"
|
||||
t("Error", { ns: "Common" })
|
||||
) : (
|
||||
""
|
||||
);
|
||||
|
@ -2,6 +2,7 @@ import React, { useEffect } from "react";
|
||||
import ModalDialog from "@docspace/components/modal-dialog";
|
||||
import Button from "@docspace/components/button";
|
||||
import styled from "styled-components";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const Footer = styled.div`
|
||||
width: 100%;
|
||||
@ -18,6 +19,8 @@ const Footer = styled.div`
|
||||
export const DeleteWebhookDialog = ({ visible, onClose, header, handleSubmit }) => {
|
||||
const onKeyPress = (e) => (e.key === "Esc" || e.key === "Escape") && onClose();
|
||||
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("keyup", onKeyPress);
|
||||
return () => window.removeEventListener("keyup", onKeyPress);
|
||||
@ -26,15 +29,17 @@ export const DeleteWebhookDialog = ({ visible, onClose, header, handleSubmit })
|
||||
return (
|
||||
<ModalDialog withFooterBorder visible={visible} onClose={onClose} displayType="modal">
|
||||
<ModalDialog.Header>{header}</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
The webhook will be deleted permanently. <br />
|
||||
You will not be able to undo this action.
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Body>{t("DeleteHint", { ns: "Webhooks" })}</ModalDialog.Body>
|
||||
|
||||
<ModalDialog.Footer>
|
||||
<Footer>
|
||||
<Button label="Delete forever" size="normal" primary={true} onClick={handleSubmit} />
|
||||
<Button label="Cancel" size="normal" onClick={onClose} />
|
||||
<Button
|
||||
label={t("DeleteForever", { ns: "Webhooks" })}
|
||||
size="normal"
|
||||
primary={true}
|
||||
onClick={handleSubmit}
|
||||
/>
|
||||
<Button label={t("Cancel", { ns: "Webhooks" })} size="normal" onClick={onClose} />
|
||||
</Footer>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialog>
|
||||
|
@ -6,6 +6,7 @@ import InfoIcon from "PUBLIC_DIR/images/info.react.svg?url";
|
||||
import RadioButtonGroup from "@docspace/components/radio-button-group";
|
||||
|
||||
import { Hint } from "../styled-components";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const Header = styled.h1`
|
||||
font-family: "Open Sans";
|
||||
@ -39,6 +40,7 @@ const InfoHint = styled(Hint)`
|
||||
|
||||
export const SSLVerification = ({ onChange, value }) => {
|
||||
const [isHintVisible, setIsHintVisible] = useState(false);
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
|
||||
const handleOnChange = (e) => {
|
||||
onChange({ target: { name: e.target.name, value: e.target.value === "true" } });
|
||||
@ -48,11 +50,12 @@ export const SSLVerification = ({ onChange, value }) => {
|
||||
return (
|
||||
<div>
|
||||
<Header>
|
||||
SSL verification <StyledInfoIcon src={InfoIcon} alt="infoIcon" onClick={toggleHint} />
|
||||
{t("SSLVerification", { ns: "Webhooks" })}{" "}
|
||||
<StyledInfoIcon src={InfoIcon} alt="infoIcon" onClick={toggleHint} />
|
||||
</Header>
|
||||
|
||||
<InfoHint hidden={!isHintVisible} onClick={toggleHint}>
|
||||
By default, we verify SSL certificates when delivering payloads.
|
||||
{t("SSLHint", { ns: "Webhooks" })}
|
||||
</InfoHint>
|
||||
|
||||
<RadioButtonGroup
|
||||
@ -62,11 +65,11 @@ export const SSLVerification = ({ onChange, value }) => {
|
||||
onClick={handleOnChange}
|
||||
options={[
|
||||
{
|
||||
label: "Enable SSL verification",
|
||||
label: t("EnableSSL", { ns: "Webhooks" }),
|
||||
value: "true",
|
||||
},
|
||||
{
|
||||
label: "Disable (not recommended)",
|
||||
label: t("DisableSSL", { ns: "Webhooks" }),
|
||||
value: "false",
|
||||
},
|
||||
]}
|
||||
|
@ -9,6 +9,8 @@ import { Hint } from "../styled-components";
|
||||
import { PasswordInput } from "@docspace/components";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const Header = styled.h1`
|
||||
font-family: "Open Sans";
|
||||
font-weight: 600;
|
||||
@ -62,6 +64,7 @@ const SecretKeyInput = (props) => {
|
||||
} = props;
|
||||
|
||||
const [isHintVisible, setIsHintVisible] = useState(false);
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
|
||||
const secretKeyInputRef = useRef(null);
|
||||
|
||||
@ -97,25 +100,24 @@ const SecretKeyInput = (props) => {
|
||||
return (
|
||||
<div>
|
||||
<Header>
|
||||
Secret key <StyledInfoIcon src={InfoIcon} alt="infoIcon" onClick={toggleHint} />
|
||||
{t("SecretKey", { ns: "Webhooks" })}{" "}
|
||||
<StyledInfoIcon src={InfoIcon} alt="infoIcon" onClick={toggleHint} />
|
||||
</Header>
|
||||
|
||||
<InfoHint hidden={!isHintVisible} onClick={handleHintDisapear}>
|
||||
Setting a webhook secret allows you to verify requests sent to the payload URL. <br />
|
||||
<ReadMore href="">Read more</ReadMore>
|
||||
{t("SecretKeyHint", { ns: "Webhooks" })} <br />
|
||||
<ReadMore href="">{t("ReadMore", { ns: "Webhooks" })}</ReadMore>
|
||||
</InfoHint>
|
||||
{isResetVisible && (
|
||||
<InfoHint>
|
||||
You cannot retrieve your secret key again once it has been saved. If you've lost or
|
||||
forgotten this secret key, you can reset it, but all integrations using this secret will
|
||||
need to be updated. <br />
|
||||
{t("SecretKeyWarning", { ns: "Webhooks" })} <br />
|
||||
<Link
|
||||
type="action"
|
||||
fontWeight={600}
|
||||
isHovered={true}
|
||||
onClick={hideReset}
|
||||
style={{ marginTop: "6px", display: "inline-block" }}>
|
||||
Reset key
|
||||
{t("ResetKey", { ns: "Webhooks" })}
|
||||
</Link>
|
||||
</InfoHint>
|
||||
)}
|
||||
@ -124,7 +126,7 @@ const SecretKeyInput = (props) => {
|
||||
onChange={handleOnChange}
|
||||
value={value}
|
||||
inputName={name}
|
||||
placeholder="Enter secret key"
|
||||
placeholder={t("EnterSecretKey", { ns: "Webhooks" })}
|
||||
onValidateInput={handleInputValidation}
|
||||
ref={secretKeyInputRef}
|
||||
hasError={!isPasswordValid}
|
||||
@ -139,7 +141,7 @@ const SecretKeyInput = (props) => {
|
||||
isHovered={true}
|
||||
onClick={generatePassword}
|
||||
style={{ marginTop: "6px", display: "inline-block" }}>
|
||||
Generate
|
||||
{t("Generate", { ns: "Webhooks" })}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,11 +1,14 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { Badge } from "@docspace/components";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export const StatusBadge = ({ status }) => {
|
||||
const [badgeColorScheme, setBadgeColorScheme] = useState({
|
||||
backgroundColor: "#2DB4821A",
|
||||
color: "#2DB482",
|
||||
});
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
|
||||
useEffect(() => {
|
||||
if (status < 200 || status > 299) {
|
||||
@ -23,7 +26,7 @@ export const StatusBadge = ({ status }) => {
|
||||
<Badge
|
||||
backgroundColor={badgeColorScheme.backgroundColor}
|
||||
color={badgeColorScheme.color}
|
||||
label={status === 0 ? "Not sent" : status.toString()}
|
||||
label={status === 0 ? t("NotSent", { ns: "Webhooks" }) : status.toString()}
|
||||
fontSize="9px"
|
||||
fontWeight={700}
|
||||
noHover
|
||||
|
@ -6,6 +6,7 @@ import styled from "styled-components";
|
||||
import { Hint } from "../styled-components";
|
||||
import { SSLVerification } from "./SSLVerification";
|
||||
import SecretKeyInput from "./SecretKeyInput";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const Footer = styled.div`
|
||||
width: 100%;
|
||||
@ -35,6 +36,8 @@ const WebhookDialog = (props) => {
|
||||
const [isUrlValid, setIsUrlValid] = useState(false);
|
||||
const [isPasswordValid, setIsPasswordValid] = useState(false);
|
||||
|
||||
const { t } = useTranslation(["Webhooks", "Common"]);
|
||||
|
||||
const [webhookInfo, setWebhookInfo] = useState({
|
||||
id: webhook ? webhook.id : 0,
|
||||
name: webhook ? webhook.name : "",
|
||||
@ -106,18 +109,18 @@ const WebhookDialog = (props) => {
|
||||
<ModalDialog.Header>{header}</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<form onSubmit={onFormSubmit}>
|
||||
<Hint>This webhook will be assigned to all events in DocSpace</Hint>
|
||||
<Hint>{t("WebhookCreationHint", { ns: "Webhooks" })}</Hint>
|
||||
<LabledInput
|
||||
label="Webhook name"
|
||||
placeholder="Enter webhook name"
|
||||
label={t("WebhookName", { ns: "Webhooks" })}
|
||||
placeholder={t("EnterWebhookName", { ns: "Webhooks" })}
|
||||
name="name"
|
||||
value={webhookInfo.name}
|
||||
onChange={onInputChange}
|
||||
required
|
||||
/>
|
||||
<LabledInput
|
||||
label="Payload URL"
|
||||
placeholder="Enter URL"
|
||||
label={t("PayloadUrl", { ns: "Webhooks" })}
|
||||
placeholder={t("EnterUrl", { ns: "Webhooks" })}
|
||||
name="uri"
|
||||
value={webhookInfo.uri}
|
||||
onChange={onInputChange}
|
||||
@ -142,12 +145,12 @@ const WebhookDialog = (props) => {
|
||||
<ModalDialog.Footer>
|
||||
<Footer>
|
||||
<Button
|
||||
label={isSettingsModal ? "Save" : "Create"}
|
||||
label={isSettingsModal ? t("Save", { ns: "Webhooks" }) : t("Create", { ns: "Common" })}
|
||||
size="normal"
|
||||
primary={true}
|
||||
onClick={handleSubmitClick}
|
||||
/>
|
||||
<Button label="Cancel" size="normal" onClick={onModalClose} />
|
||||
<Button label={t("Cancel", { ns: "Webhooks" })} size="normal" onClick={onModalClose} />
|
||||
</Footer>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialog>
|
||||
|
@ -4,26 +4,25 @@ import { InfoText } from "../styled-components";
|
||||
|
||||
import { Link } from "@docspace/components";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const InfoWrapper = styled.div`
|
||||
margin-bottom: 27px;
|
||||
`;
|
||||
|
||||
export const WebhookInfo = () => {
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
|
||||
return (
|
||||
<InfoWrapper>
|
||||
<InfoText>
|
||||
Use webhooks to perform custom actions on the side of any application or website you are
|
||||
using based on various events in ONLYOFFICE Docspace. <br />
|
||||
Here, you can create and manage all your webhooks, configure them, and browse history of
|
||||
every webhook to audit their performance.
|
||||
</InfoText>
|
||||
<InfoText>{t("WebhooksInfo", { ns: "Webhooks" })}</InfoText>
|
||||
<Link
|
||||
fontWeight={600}
|
||||
color="#316DAA"
|
||||
isHovered
|
||||
type="page"
|
||||
href="https://api.onlyoffice.com/portals/basic">
|
||||
Webhooks Guide
|
||||
{t("WebhooksGuide", { ns: "Webhooks" })}
|
||||
</Link>
|
||||
</InfoWrapper>
|
||||
);
|
||||
|
@ -13,6 +13,7 @@ import DeleteIcon from "PUBLIC_DIR/images/delete.react.svg?url";
|
||||
import toastr from "@docspace/components/toast/toastr";
|
||||
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export const WebhookRow = ({
|
||||
webhook,
|
||||
@ -22,6 +23,7 @@ export const WebhookRow = ({
|
||||
editWebhook,
|
||||
}) => {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation(["Webhooks", "Common"]);
|
||||
|
||||
const [isChecked, setIsChecked] = useState(webhook.enabled);
|
||||
const [isSettingsOpened, setIsSettingsOpened] = useState(false);
|
||||
@ -35,11 +37,14 @@ export const WebhookRow = ({
|
||||
|
||||
const handleWebhookUpdate = async (webhookInfo) => {
|
||||
editWebhook(webhook, webhookInfo);
|
||||
toastr.success("Webhook configuration edited successfully", <b>Done</b>);
|
||||
toastr.success(
|
||||
t("WebhookEditedSuccessfully", { ns: "Webhooks" }),
|
||||
<b>{t("Done", { ns: "Common" })}</b>,
|
||||
);
|
||||
};
|
||||
const handleWebhookDelete = async () => {
|
||||
await deleteWebhook(webhook);
|
||||
toastr.success("Webhook removed", <b>Done</b>);
|
||||
toastr.success(t("WebhookRemoved", { ns: "Webhooks" }), <b>{t("Done", { ns: "Common" })}</b>);
|
||||
};
|
||||
const handleToggleEnabled = () => {
|
||||
toggleEnabled(webhook);
|
||||
@ -49,13 +54,13 @@ export const WebhookRow = ({
|
||||
const contextOptions = [
|
||||
{
|
||||
key: "Settings dropdownItem",
|
||||
label: "Settings",
|
||||
label: t("Settings", { ns: "Common" }),
|
||||
icon: SettingsIcon,
|
||||
onClick: openSettings,
|
||||
},
|
||||
{
|
||||
key: "Webhook history dropdownItem",
|
||||
label: "Webhook history",
|
||||
label: t("WebhookHistory", { ns: "Webhooks" }),
|
||||
icon: HistoryIcon,
|
||||
onClick: redirectToHistory,
|
||||
},
|
||||
@ -65,7 +70,7 @@ export const WebhookRow = ({
|
||||
},
|
||||
{
|
||||
key: "Delete webhook dropdownItem",
|
||||
label: "Delete webhook",
|
||||
label: t("DeleteWebhook", { ns: "Webhooks" }),
|
||||
icon: DeleteIcon,
|
||||
onClick: onDeleteOpen,
|
||||
},
|
||||
@ -88,7 +93,7 @@ export const WebhookRow = ({
|
||||
<WebhookDialog
|
||||
visible={isSettingsOpened}
|
||||
onClose={closeSettings}
|
||||
header="Setting webhook"
|
||||
header={t("SettingsWebhook", { ns: "Webhooks" })}
|
||||
isSettingsModal={true}
|
||||
webhook={webhook}
|
||||
onSubmit={handleWebhookUpdate}
|
||||
@ -96,7 +101,7 @@ export const WebhookRow = ({
|
||||
<DeleteWebhookDialog
|
||||
visible={isDeleteOpened}
|
||||
onClose={onDeleteClose}
|
||||
header="Delete Webhook forever?"
|
||||
header={t("DeleteWebhookForeverQuestion", { ns: "Webhooks" })}
|
||||
handleSubmit={handleWebhookDelete}
|
||||
/>
|
||||
</>
|
||||
|
@ -1,11 +1,14 @@
|
||||
import React, { useRef } from "react";
|
||||
import TableHeader from "@docspace/components/table-container/TableHeader";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export const WebhookTableHeader = ({ sectionWidth, tableRef }) => {
|
||||
const { t } = useTranslation(["Webhooks", "Common"]);
|
||||
const columns = useRef([
|
||||
{
|
||||
key: "Name",
|
||||
title: "Name",
|
||||
title: t("Name", { ns: "Common" }),
|
||||
resizable: true,
|
||||
enable: true,
|
||||
default: true,
|
||||
@ -13,13 +16,13 @@ export const WebhookTableHeader = ({ sectionWidth, tableRef }) => {
|
||||
},
|
||||
{
|
||||
key: "URL",
|
||||
title: "URL",
|
||||
title: t("URL", { ns: "Webhooks" }),
|
||||
enable: true,
|
||||
resizable: true,
|
||||
},
|
||||
{
|
||||
key: "State",
|
||||
title: "State",
|
||||
title: t("State", { ns: "Webhooks" }),
|
||||
enable: true,
|
||||
resizable: true,
|
||||
},
|
||||
|
@ -16,6 +16,7 @@ import { DeleteWebhookDialog } from "../../DeleteWebhookDialog";
|
||||
import { StatusBadge } from "../../StatusBadge";
|
||||
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const StyledTableRow = styled(TableRow)`
|
||||
.mr-8 {
|
||||
@ -26,6 +27,8 @@ const StyledTableRow = styled(TableRow)`
|
||||
export const WebhooksTableRow = ({ webhook, toggleEnabled, deleteWebhook, editWebhook }) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { t } = useTranslation(["Webhooks", "Common"]);
|
||||
|
||||
const [isChecked, setIsChecked] = useState(webhook.enabled);
|
||||
const [isSettingsOpened, setIsSettingsOpened] = useState(false);
|
||||
const [isDeleteOpened, setIsDeleteOpened] = useState(false);
|
||||
@ -38,11 +41,14 @@ export const WebhooksTableRow = ({ webhook, toggleEnabled, deleteWebhook, editWe
|
||||
|
||||
const handleWebhookUpdate = async (webhookInfo) => {
|
||||
await editWebhook(webhook, webhookInfo);
|
||||
toastr.success("Webhook configuration edited successfully", <b>Done</b>);
|
||||
toastr.success(
|
||||
t("WebhookEditedSuccessfully", { ns: "Webhooks" }),
|
||||
<b>{t("Done", { ns: "Common" })}</b>,
|
||||
);
|
||||
};
|
||||
const handleWebhookDelete = async () => {
|
||||
await deleteWebhook(webhook);
|
||||
toastr.success("Webhook removed", <b>Done</b>);
|
||||
toastr.success(t("WebhookRemoved", { ns: "Webhooks" }), <b>{t("Done", { ns: "Common" })}</b>);
|
||||
};
|
||||
const handleToggleEnabled = () => {
|
||||
toggleEnabled(webhook);
|
||||
@ -52,13 +58,13 @@ export const WebhooksTableRow = ({ webhook, toggleEnabled, deleteWebhook, editWe
|
||||
const contextOptions = [
|
||||
{
|
||||
key: "Settings dropdownItem",
|
||||
label: "Settings",
|
||||
label: t("Settings", { ns: "Common" }),
|
||||
icon: SettingsIcon,
|
||||
onClick: openSettings,
|
||||
},
|
||||
{
|
||||
key: "Webhook history dropdownItem",
|
||||
label: "Webhook history",
|
||||
label: t("WebhookHistory", { ns: "Webhooks" }),
|
||||
icon: HistoryIcon,
|
||||
onClick: redirectToHistory,
|
||||
},
|
||||
@ -68,7 +74,7 @@ export const WebhooksTableRow = ({ webhook, toggleEnabled, deleteWebhook, editWe
|
||||
},
|
||||
{
|
||||
key: "Delete webhook dropdownItem",
|
||||
label: "Delete webhook",
|
||||
label: t("DeleteWebhook", { ns: "Webhooks" }),
|
||||
icon: DeleteIcon,
|
||||
onClick: onDeleteOpen,
|
||||
},
|
||||
@ -101,7 +107,7 @@ export const WebhooksTableRow = ({ webhook, toggleEnabled, deleteWebhook, editWe
|
||||
<WebhookDialog
|
||||
visible={isSettingsOpened}
|
||||
onClose={closeSettings}
|
||||
header="Setting webhook"
|
||||
header={t("SettingsWebhook", { ns: "Webhooks" })}
|
||||
isSettingsModal={true}
|
||||
webhook={webhook}
|
||||
onSubmit={handleWebhookUpdate}
|
||||
@ -109,7 +115,7 @@ export const WebhooksTableRow = ({ webhook, toggleEnabled, deleteWebhook, editWe
|
||||
<DeleteWebhookDialog
|
||||
visible={isDeleteOpened}
|
||||
onClose={onDeleteClose}
|
||||
header="Delete Webhook forever?"
|
||||
header={t("DeleteWebhookForeverQuestion", { ns: "Webhooks" })}
|
||||
handleSubmit={handleWebhookDelete}
|
||||
/>
|
||||
</>
|
||||
|
@ -12,21 +12,25 @@ import Webhooks from "./Webhooks";
|
||||
import AppLoader from "@docspace/common/components/AppLoader";
|
||||
import SSOLoader from "./sub-components/ssoLoader";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const DeveloperToolsWrapper = (props) => {
|
||||
const { loadBaseInfo } = props;
|
||||
const [currentTab, setCurrentTab] = useState(0);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { t, ready } = useTranslation(["JavascriptSdk", "Webhooks"]);
|
||||
|
||||
const data = [
|
||||
{
|
||||
id: "javascript-sdk",
|
||||
name: "Javascript sdk",
|
||||
name: t("JavascriptSdk", { ns: "JavascriptSdk" }),
|
||||
content: <JavascriptSDK />,
|
||||
},
|
||||
{
|
||||
id: "webhooks",
|
||||
name: "Webhooks",
|
||||
name: t("Webhooks", { ns: "Webhooks" }),
|
||||
content: <Webhooks />,
|
||||
},
|
||||
];
|
||||
@ -54,7 +58,7 @@ const DeveloperToolsWrapper = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
if (!isLoading) return currentTab === 0 ? <SSOLoader /> : <AppLoader />;
|
||||
if (!isLoading && !ready) return currentTab === 0 ? <SSOLoader /> : <AppLoader />;
|
||||
|
||||
return <Submenu data={data} startSelect={currentTab} onSelect={onSelect} />;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user