Rares/webhook UI changes (#2419)
# What this PR does ## Which issue(s) this PR fixes ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [ ] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required)
This commit is contained in:
parent
5cc06b7041
commit
7195646413
14 changed files with 506 additions and 261 deletions
|
|
@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Changed
|
||||
|
||||
- UI drawer updates for webhooks2 ([#2419](https://github.com/grafana/oncall/pull/2419))
|
||||
- Removed url from sms notification, changed format ([2317](https://github.com/grafana/oncall/pull/2317))
|
||||
|
||||
## v1.3.4 (2023-07-05)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
.hamburgerMenu {
|
||||
cursor: pointer;
|
||||
color: var(--primary-text-color);
|
||||
border: var(--border-weak);
|
||||
border-radius: var(--border-radius);
|
||||
background-color: var(--button-background);
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
|
@ -11,21 +8,15 @@
|
|||
justify-content: center;
|
||||
padding: 4px;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--button-hover-background);
|
||||
}
|
||||
|
||||
&--withBackground {
|
||||
height: 32px;
|
||||
width: 30px;
|
||||
cursor: pointer;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
|
||||
&--small {
|
||||
height: 24px;
|
||||
width: 22px;
|
||||
cursor: pointer;
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ export const ScheduleQualityDetails: FC<ScheduleQualityDetailsProps> = ({ qualit
|
|||
)}
|
||||
</div>
|
||||
|
||||
<div className="thin-line-break" />
|
||||
<div className={cx('thin-line-break')} />
|
||||
|
||||
<div className={cx('container', 'container--withTopPadding', 'container--withLateralPadding')}>
|
||||
<HorizontalGroup justify="space-between">
|
||||
|
|
|
|||
|
|
@ -42,9 +42,6 @@ import { UserActions } from 'utils/authorization';
|
|||
|
||||
const cx = cn.bind(styles);
|
||||
|
||||
const ACTIONS_LIST_WIDTH = 200;
|
||||
const ACTIONS_LIST_BORDER = 2;
|
||||
|
||||
interface ExpandedIntegrationRouteDisplayProps {
|
||||
alertReceiveChannelId: AlertReceiveChannel['id'];
|
||||
channelFilterId: ChannelFilter['id'];
|
||||
|
|
@ -370,7 +367,7 @@ export const RouteButtonsDisplay: React.FC<RouteButtonsDisplayProps> = ({
|
|||
</div>
|
||||
</CopyToClipboard>
|
||||
|
||||
<div className="thin-line-break" />
|
||||
<div className={cx('thin-line-break')} />
|
||||
|
||||
<WithPermissionControlTooltip key="delete" userAction={UserActions.IntegrationsWrite}>
|
||||
<div className={cx('integrations-actionItem')} onClick={onDelete}>
|
||||
|
|
@ -388,8 +385,8 @@ export const RouteButtonsDisplay: React.FC<RouteButtonsDisplayProps> = ({
|
|||
{({ openMenu }) => (
|
||||
<HamburgerMenu
|
||||
openMenu={openMenu}
|
||||
listBorder={ACTIONS_LIST_BORDER}
|
||||
listWidth={ACTIONS_LIST_WIDTH}
|
||||
listBorder={2}
|
||||
listWidth={200}
|
||||
className={'hamburgerMenu--small'}
|
||||
stopPropagation={true}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -9,3 +9,7 @@
|
|||
.content {
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
.tabs__content {
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,20 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
|
||||
import { Button, Drawer, HorizontalGroup } from '@grafana/ui';
|
||||
import { Button, ConfirmModal, ConfirmModalProps, Drawer, HorizontalGroup, Tab, TabsBar } from '@grafana/ui';
|
||||
import cn from 'classnames/bind';
|
||||
import { observer } from 'mobx-react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import GForm from 'components/GForm/GForm';
|
||||
import Text from 'components/Text/Text';
|
||||
import OutgoingWebhook2Status from 'containers/OutgoingWebhook2Status/OutgoingWebhook2Status';
|
||||
import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip';
|
||||
import { OutgoingWebhook2 } from 'models/outgoing_webhook_2/outgoing_webhook_2.types';
|
||||
import { WebhookFormActionType } from 'pages/outgoing_webhooks_2/OutgoingWebhooks2.types';
|
||||
import { useStore } from 'state/useStore';
|
||||
import { KeyValuePair } from 'utils';
|
||||
import { UserActions } from 'utils/authorization';
|
||||
import { PLUGIN_ROOT } from 'utils/consts';
|
||||
|
||||
import { form } from './OutgoingWebhook2Form.config';
|
||||
|
||||
|
|
@ -19,65 +24,221 @@ const cx = cn.bind(styles);
|
|||
|
||||
interface OutgoingWebhook2FormProps {
|
||||
id: OutgoingWebhook2['id'] | 'new';
|
||||
action: 'new' | 'update';
|
||||
action: WebhookFormActionType;
|
||||
onHide: () => void;
|
||||
onUpdate: () => void;
|
||||
onDelete: () => void;
|
||||
}
|
||||
|
||||
export const WebhookTabs = {
|
||||
Settings: new KeyValuePair('Settings', 'Settings'),
|
||||
LastRun: new KeyValuePair('LastRun', 'Last Run'),
|
||||
};
|
||||
|
||||
const OutgoingWebhook2Form = observer((props: OutgoingWebhook2FormProps) => {
|
||||
const { id, action, onUpdate, onHide } = props;
|
||||
const history = useHistory();
|
||||
const { id, action, onUpdate, onHide, onDelete } = props;
|
||||
const [activeTab, setActiveTab] = useState<string>(
|
||||
action === WebhookFormActionType.EDIT_SETTINGS ? WebhookTabs.Settings.key : WebhookTabs.LastRun.key
|
||||
);
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const { outgoingWebhook2Store } = store;
|
||||
|
||||
const data =
|
||||
id === 'new'
|
||||
? { is_webhook_enabled: true, is_legacy: false }
|
||||
: action === 'new'
|
||||
? { ...outgoingWebhook2Store.items[id], is_legacy: false, name: '' }
|
||||
: outgoingWebhook2Store.items[id];
|
||||
const { outgoingWebhook2Store } = useStore();
|
||||
const isNew = action === WebhookFormActionType.NEW;
|
||||
const isNewOrCopy = isNew || action === WebhookFormActionType.COPY;
|
||||
|
||||
const handleSubmit = useCallback(
|
||||
(data: Partial<OutgoingWebhook2>) => {
|
||||
(action === 'new' ? outgoingWebhook2Store.create(data) : outgoingWebhook2Store.update(id, data)).then(() => {
|
||||
(isNewOrCopy ? outgoingWebhook2Store.create(data) : outgoingWebhook2Store.update(id, data)).then(() => {
|
||||
onHide();
|
||||
|
||||
onUpdate();
|
||||
});
|
||||
},
|
||||
[id]
|
||||
);
|
||||
|
||||
if (
|
||||
(action === WebhookFormActionType.EDIT_SETTINGS || action === WebhookFormActionType.VIEW_LAST_RUN) &&
|
||||
!outgoingWebhook2Store.items[id]
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let data:
|
||||
| OutgoingWebhook2
|
||||
| {
|
||||
is_webhook_enabled: boolean;
|
||||
is_legacy: boolean;
|
||||
};
|
||||
|
||||
if (isNew) {
|
||||
data = { is_webhook_enabled: true, is_legacy: false };
|
||||
} else if (isNewOrCopy) {
|
||||
data = { ...outgoingWebhook2Store.items[id], is_legacy: false, name: '' };
|
||||
} else {
|
||||
data = outgoingWebhook2Store.items[id];
|
||||
}
|
||||
|
||||
if (
|
||||
(action === WebhookFormActionType.EDIT_SETTINGS || action === WebhookFormActionType.VIEW_LAST_RUN) &&
|
||||
!outgoingWebhook2Store.items[id]
|
||||
) {
|
||||
// nothing to show if we open invalid ID for edit/last_run
|
||||
return null;
|
||||
}
|
||||
|
||||
if (action === WebhookFormActionType.NEW || action === WebhookFormActionType.COPY) {
|
||||
// show just the creation form, not the tabs
|
||||
return (
|
||||
<Drawer scrollableContent title={'Create Outgoing Webhook'} onClose={onHide} closeOnMaskClick={false}>
|
||||
{renderWebhookForm()}
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
scrollableContent
|
||||
title={action === 'new' ? 'Create Outgoing Webhook' : 'Edit Outgoing Webhook'}
|
||||
onClose={onHide}
|
||||
closeOnMaskClick={false}
|
||||
>
|
||||
<div className={cx('content')} data-testid="test__outgoingWebhook2EditForm">
|
||||
<GForm form={form} data={data} onSubmit={handleSubmit} />
|
||||
<HorizontalGroup justify={'flex-end'}>
|
||||
<Button variant="secondary" onClick={onHide}>
|
||||
Cancel
|
||||
</Button>
|
||||
<WithPermissionControlTooltip userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<Button form={form.name} type="submit" disabled={data.is_legacy}>
|
||||
{action === 'new' ? 'Create' : 'Update'} Webhook
|
||||
</Button>
|
||||
</WithPermissionControlTooltip>
|
||||
</HorizontalGroup>
|
||||
</div>
|
||||
{data.is_legacy ? (
|
||||
<div className={cx('content')}>
|
||||
<Text type="secondary">Legacy migrated webhooks are not editable.</Text>
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
// show tabbed drawer (edit/live_run)
|
||||
<Drawer scrollableContent title={'Outgoing webhook details'} onClose={onHide} closeOnMaskClick={false}>
|
||||
<TabsBar>
|
||||
<Tab
|
||||
key={WebhookTabs.Settings.key}
|
||||
onChangeTab={() => {
|
||||
setActiveTab(WebhookTabs.Settings.key);
|
||||
history.push(`${PLUGIN_ROOT}/outgoing_webhooks_2/edit/${id}`);
|
||||
}}
|
||||
active={activeTab === WebhookTabs.Settings.key}
|
||||
label={WebhookTabs.Settings.value}
|
||||
/>
|
||||
|
||||
<Tab
|
||||
key={WebhookTabs.LastRun.key}
|
||||
onChangeTab={() => {
|
||||
setActiveTab(WebhookTabs.LastRun.key);
|
||||
history.push(`${PLUGIN_ROOT}/outgoing_webhooks_2/last_run/${id}`);
|
||||
}}
|
||||
active={activeTab === WebhookTabs.LastRun.key}
|
||||
label={WebhookTabs.LastRun.value}
|
||||
/>
|
||||
</TabsBar>
|
||||
|
||||
<WebhookTabsContent
|
||||
id={id}
|
||||
action={action}
|
||||
activeTab={activeTab}
|
||||
data={data}
|
||||
handleSubmit={handleSubmit}
|
||||
onDelete={onDelete}
|
||||
onHide={onHide}
|
||||
onUpdate={onUpdate}
|
||||
/>
|
||||
</Drawer>
|
||||
);
|
||||
|
||||
function renderWebhookForm() {
|
||||
return (
|
||||
<>
|
||||
<div className={cx('content')} data-testid="test__outgoingWebhook2EditForm">
|
||||
<GForm form={form} data={data} onSubmit={handleSubmit} />
|
||||
<div className={cx('buttons')}>
|
||||
<HorizontalGroup justify={'flex-end'}>
|
||||
<Button variant="secondary" onClick={onHide}>
|
||||
Cancel
|
||||
</Button>
|
||||
<WithPermissionControlTooltip userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<Button form={form.name} type="submit" disabled={data.is_legacy}>
|
||||
{isNewOrCopy ? 'Create' : 'Update'} Webhook
|
||||
</Button>
|
||||
</WithPermissionControlTooltip>
|
||||
</HorizontalGroup>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
interface WebhookTabsProps {
|
||||
id: OutgoingWebhook2['id'] | 'new';
|
||||
activeTab: string;
|
||||
action: WebhookFormActionType;
|
||||
data:
|
||||
| OutgoingWebhook2
|
||||
| {
|
||||
is_webhook_enabled: boolean;
|
||||
is_legacy: boolean;
|
||||
};
|
||||
onHide: () => void;
|
||||
onUpdate: () => void;
|
||||
onDelete: () => void;
|
||||
handleSubmit: (data: Partial<OutgoingWebhook2>) => void;
|
||||
}
|
||||
|
||||
const WebhookTabsContent: React.FC<WebhookTabsProps> = ({
|
||||
id,
|
||||
action,
|
||||
activeTab,
|
||||
data,
|
||||
handleSubmit,
|
||||
onHide,
|
||||
onUpdate,
|
||||
onDelete,
|
||||
}) => {
|
||||
const [confirmationModal, setConfirmationModal] = useState<ConfirmModalProps>(undefined);
|
||||
|
||||
return (
|
||||
<div className={cx('tabs__content')}>
|
||||
{confirmationModal && (
|
||||
<ConfirmModal {...(confirmationModal as ConfirmModalProps)} onDismiss={() => setConfirmationModal(undefined)} />
|
||||
)}
|
||||
|
||||
{activeTab === WebhookTabs.Settings.key && (
|
||||
<>
|
||||
<div className={cx('content')} data-testid="test__outgoingWebhook2EditForm">
|
||||
<GForm form={form} data={data} onSubmit={handleSubmit} />
|
||||
<div className={cx('buttons')}>
|
||||
<HorizontalGroup justify={'flex-end'}>
|
||||
<Button variant="secondary" onClick={onHide}>
|
||||
Cancel
|
||||
</Button>
|
||||
<WithPermissionControlTooltip userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<Button
|
||||
form={form.name}
|
||||
variant="destructive"
|
||||
type="button"
|
||||
disabled={data.is_legacy}
|
||||
onClick={() => {
|
||||
setConfirmationModal({
|
||||
isOpen: true,
|
||||
body: 'The action cannot be undone.',
|
||||
confirmText: 'Delete',
|
||||
dismissText: 'Cancel',
|
||||
onConfirm: onDelete,
|
||||
title: `Are you sure you want to delete webhook?`,
|
||||
} as ConfirmModalProps);
|
||||
}}
|
||||
>
|
||||
Delete Webhook
|
||||
</Button>
|
||||
</WithPermissionControlTooltip>
|
||||
<WithPermissionControlTooltip userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<Button form={form.name} type="submit" disabled={data.is_legacy}>
|
||||
{action === WebhookFormActionType.NEW ? 'Create' : 'Update'} Webhook
|
||||
</Button>
|
||||
</WithPermissionControlTooltip>
|
||||
</HorizontalGroup>
|
||||
</div>
|
||||
</div>
|
||||
{data.is_legacy ? (
|
||||
<div className={cx('content')}>
|
||||
<Text type="secondary">Legacy migrated webhooks are not editable.</Text>
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{activeTab === WebhookTabs.LastRun.key && <OutgoingWebhook2Status id={id} onUpdate={onUpdate} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OutgoingWebhook2Form;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
|
||||
import { Drawer, Label, VerticalGroup } from '@grafana/ui';
|
||||
import { Label, VerticalGroup } from '@grafana/ui';
|
||||
import cn from 'classnames/bind';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
|
|
@ -16,7 +16,6 @@ const cx = cn.bind(styles);
|
|||
|
||||
interface OutgoingWebhook2StatusProps {
|
||||
id: OutgoingWebhook2['id'];
|
||||
onHide: () => void;
|
||||
onUpdate: () => void;
|
||||
}
|
||||
|
||||
|
|
@ -49,7 +48,7 @@ function format_response_field(str) {
|
|||
}
|
||||
|
||||
const OutgoingWebhook2Status = observer((props: OutgoingWebhook2StatusProps) => {
|
||||
const { id, onHide } = props;
|
||||
const { id } = props;
|
||||
|
||||
const store = useStore();
|
||||
|
||||
|
|
@ -58,76 +57,65 @@ const OutgoingWebhook2Status = observer((props: OutgoingWebhook2StatusProps) =>
|
|||
const data = outgoingWebhook2Store.items[id];
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
scrollableContent
|
||||
title={
|
||||
<Text.Title className={cx('title')} level={4}>
|
||||
Outgoing Webhook Status
|
||||
</Text.Title>
|
||||
}
|
||||
onClose={onHide}
|
||||
closeOnMaskClick
|
||||
>
|
||||
<div className={cx('content')}>
|
||||
<VerticalGroup>
|
||||
<Label>Webhook Name</Label>
|
||||
<SourceCode showClipboardIconOnly>{data.name}</SourceCode>
|
||||
<Label>Webhook ID</Label>
|
||||
<SourceCode showClipboardIconOnly>{data.id}</SourceCode>
|
||||
<Label>Trigger Type</Label>
|
||||
<SourceCode showClipboardIconOnly>{data.trigger_type_name}</SourceCode>
|
||||
<div className={cx('content')}>
|
||||
<VerticalGroup>
|
||||
<Label>Webhook Name</Label>
|
||||
<SourceCode showClipboardIconOnly>{data.name}</SourceCode>
|
||||
<Label>Webhook ID</Label>
|
||||
<SourceCode showClipboardIconOnly>{data.id}</SourceCode>
|
||||
<Label>Trigger Type</Label>
|
||||
<SourceCode showClipboardIconOnly>{data.trigger_type_name}</SourceCode>
|
||||
|
||||
{data.last_response_log.timestamp ? (
|
||||
<VerticalGroup>
|
||||
<Label>Last Run Time</Label>
|
||||
<SourceCode showClipboardIconOnly>{data.last_response_log.timestamp}</SourceCode>
|
||||
{data.last_response_log.timestamp ? (
|
||||
<VerticalGroup>
|
||||
<Label>Last Run Time</Label>
|
||||
<SourceCode showClipboardIconOnly>{data.last_response_log.timestamp}</SourceCode>
|
||||
|
||||
{data.last_response_log.url && (
|
||||
<Debug title="URL" source={data.url} result={data.last_response_log.url}></Debug>
|
||||
)}
|
||||
{data.last_response_log.status_code && (
|
||||
<VerticalGroup>
|
||||
<Label>Response Code</Label>
|
||||
<SourceCode showClipboardIconOnly>{data.last_response_log.status_code}</SourceCode>
|
||||
</VerticalGroup>
|
||||
)}
|
||||
{data.last_response_log.url && (
|
||||
<Debug title="URL" source={data.url} result={data.last_response_log.url}></Debug>
|
||||
)}
|
||||
{data.last_response_log.status_code && (
|
||||
<VerticalGroup>
|
||||
<Label>Response Code</Label>
|
||||
<SourceCode showClipboardIconOnly>{data.last_response_log.status_code}</SourceCode>
|
||||
</VerticalGroup>
|
||||
)}
|
||||
|
||||
{data.last_response_log.content && (
|
||||
<VerticalGroup>
|
||||
<Label>Response Body</Label>
|
||||
<SourceCode showClipboardIconOnly>{format_response_field(data.last_response_log.content)}</SourceCode>
|
||||
</VerticalGroup>
|
||||
)}
|
||||
{data.last_response_log.request_trigger && (
|
||||
<Debug
|
||||
title="Trigger Template"
|
||||
source={data.trigger_template}
|
||||
result={data.last_response_log.request_trigger}
|
||||
></Debug>
|
||||
)}
|
||||
{data.last_response_log.request_headers && (
|
||||
<Debug
|
||||
title="Request Headers"
|
||||
source={data.headers}
|
||||
result={data.last_response_log.request_headers}
|
||||
></Debug>
|
||||
)}
|
||||
{data.last_response_log.request_data && (
|
||||
<Debug
|
||||
title="Request Data"
|
||||
source={data.data}
|
||||
result={format_response_field(data.last_response_log.request_data)}
|
||||
></Debug>
|
||||
)}
|
||||
</VerticalGroup>
|
||||
) : (
|
||||
<Text type="primary" size="medium">
|
||||
An event triggering this webhook has not been sent yet!
|
||||
</Text>
|
||||
)}
|
||||
</VerticalGroup>
|
||||
</div>
|
||||
</Drawer>
|
||||
{data.last_response_log.content && (
|
||||
<VerticalGroup>
|
||||
<Label>Response Body</Label>
|
||||
<SourceCode showClipboardIconOnly>{format_response_field(data.last_response_log.content)}</SourceCode>
|
||||
</VerticalGroup>
|
||||
)}
|
||||
{data.last_response_log.request_trigger && (
|
||||
<Debug
|
||||
title="Trigger Template"
|
||||
source={data.trigger_template}
|
||||
result={data.last_response_log.request_trigger}
|
||||
></Debug>
|
||||
)}
|
||||
{data.last_response_log.request_headers && (
|
||||
<Debug
|
||||
title="Request Headers"
|
||||
source={data.headers}
|
||||
result={data.last_response_log.request_headers}
|
||||
></Debug>
|
||||
)}
|
||||
{data.last_response_log.request_data && (
|
||||
<Debug
|
||||
title="Request Data"
|
||||
source={data.data}
|
||||
result={format_response_field(data.last_response_log.request_data)}
|
||||
></Debug>
|
||||
)}
|
||||
</VerticalGroup>
|
||||
) : (
|
||||
<Text type="primary" size="medium">
|
||||
An event triggering this webhook has not been sent yet!
|
||||
</Text>
|
||||
)}
|
||||
</VerticalGroup>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -88,8 +88,6 @@ interface IntegrationState extends PageBaseState {
|
|||
openRoutes: string[];
|
||||
}
|
||||
|
||||
const ACTIONS_LIST_WIDTH = 200;
|
||||
const ACTIONS_LIST_BORDER = 2;
|
||||
const NEW_ROUTE_DEFAULT = '';
|
||||
|
||||
@observer
|
||||
|
|
@ -685,7 +683,7 @@ const IntegrationSendDemoPayloadModal: React.FC<IntegrationSendDemoPayloadModalP
|
|||
<Button variant={'secondary'} onClick={onHideOrCancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<CopyToClipboard text={getCurlText()} onCopy={() => openNotification('CURL copied!')}>
|
||||
<CopyToClipboard text={getCurlText()} onCopy={() => openNotification('CURL has been copied')}>
|
||||
<Button variant={'secondary'}>Copy as CURL</Button>
|
||||
</CopyToClipboard>
|
||||
<Button variant={'primary'} onClick={sendDemoAlert} data-testid="submit-send-alert">
|
||||
|
|
@ -884,7 +882,7 @@ const IntegrationActions: React.FC<IntegrationActionsProps> = ({
|
|||
</div>
|
||||
</CopyToClipboard>
|
||||
|
||||
<div className="thin-line-break" />
|
||||
<div className={cx('thin-line-break')} />
|
||||
|
||||
<WithPermissionControlTooltip userAction={UserActions.IntegrationsWrite}>
|
||||
<div className={cx('integration__actionItem')}>
|
||||
|
|
@ -918,14 +916,7 @@ const IntegrationActions: React.FC<IntegrationActionsProps> = ({
|
|||
</div>
|
||||
)}
|
||||
>
|
||||
{({ openMenu }) => (
|
||||
<HamburgerMenu
|
||||
openMenu={openMenu}
|
||||
listBorder={ACTIONS_LIST_BORDER}
|
||||
listWidth={ACTIONS_LIST_WIDTH}
|
||||
withBackground
|
||||
/>
|
||||
)}
|
||||
{({ openMenu }) => <HamburgerMenu openMenu={openMenu} listBorder={2} listWidth={200} withBackground />}
|
||||
</WithContextMenu>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@ const cx = cn.bind(styles);
|
|||
const FILTERS_DEBOUNCE_MS = 500;
|
||||
const ITEMS_PER_PAGE = 15;
|
||||
const MAX_LINE_LENGTH = 40;
|
||||
const ACTIONS_LIST_WIDTH = 200;
|
||||
const ACTIONS_LIST_BORDER = 2;
|
||||
|
||||
interface IntegrationsState extends PageBaseState {
|
||||
integrationsFilters: Filters;
|
||||
|
|
@ -402,7 +400,7 @@ class Integrations extends React.Component<IntegrationsProps, IntegrationsState>
|
|||
</div>
|
||||
</WithPermissionControlTooltip>
|
||||
|
||||
<CopyToClipboard text={item.id} onCopy={() => openNotification('Integration ID is copied')}>
|
||||
<CopyToClipboard text={item.id} onCopy={() => openNotification('Integration ID has been copied')}>
|
||||
<div className={cx('integrations-actionItem')}>
|
||||
<HorizontalGroup spacing={'xs'}>
|
||||
<Icon name="copy" />
|
||||
|
|
@ -412,7 +410,7 @@ class Integrations extends React.Component<IntegrationsProps, IntegrationsState>
|
|||
</div>
|
||||
</CopyToClipboard>
|
||||
|
||||
<div className="thin-line-break" />
|
||||
<div className={cx('thin-line-break')} />
|
||||
|
||||
<WithPermissionControlTooltip key="delete" userAction={UserActions.IntegrationsWrite}>
|
||||
<div className={cx('integrations-actionItem')}>
|
||||
|
|
@ -447,9 +445,7 @@ class Integrations extends React.Component<IntegrationsProps, IntegrationsState>
|
|||
</div>
|
||||
)}
|
||||
>
|
||||
{({ openMenu }) => (
|
||||
<HamburgerMenu openMenu={openMenu} listBorder={ACTIONS_LIST_BORDER} listWidth={ACTIONS_LIST_WIDTH} />
|
||||
)}
|
||||
{({ openMenu }) => <HamburgerMenu openMenu={openMenu} listBorder={2} listWidth={200} />}
|
||||
</WithContextMenu>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.header__title {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.header__desc {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.header__title {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.header__desc {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.hamburgerMenu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 225px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.hamburgerMenu__item {
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
border-left: 2px solid transparent;
|
||||
cursor: pointer;
|
||||
min-width: 84px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-direction: row;
|
||||
|
||||
&:hover {
|
||||
background: var(--cards-background);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,15 @@
|
|||
import React from 'react';
|
||||
|
||||
import { Button, HorizontalGroup, Icon, IconButton, VerticalGroup } from '@grafana/ui';
|
||||
import {
|
||||
Button,
|
||||
ConfirmModal,
|
||||
ConfirmModalProps,
|
||||
HorizontalGroup,
|
||||
Icon,
|
||||
IconButton,
|
||||
VerticalGroup,
|
||||
WithContextMenu,
|
||||
} from '@grafana/ui';
|
||||
import cn from 'classnames/bind';
|
||||
import { observer } from 'mobx-react';
|
||||
import moment from 'moment-timezone';
|
||||
|
|
@ -9,6 +18,7 @@ import CopyToClipboard from 'react-copy-to-clipboard';
|
|||
import { RouteComponentProps, withRouter } from 'react-router-dom';
|
||||
|
||||
import GTable from 'components/GTable/GTable';
|
||||
import HamburgerMenu from 'components/HamburgerMenu/HamburgerMenu';
|
||||
import PageErrorHandlingWrapper, { PageBaseState } from 'components/PageErrorHandlingWrapper/PageErrorHandlingWrapper';
|
||||
import {
|
||||
getWrongTeamResponseInfo,
|
||||
|
|
@ -16,50 +26,45 @@ import {
|
|||
} from 'components/PageErrorHandlingWrapper/PageErrorHandlingWrapper.helpers';
|
||||
import PluginLink from 'components/PluginLink/PluginLink';
|
||||
import Text from 'components/Text/Text';
|
||||
import WithConfirm from 'components/WithConfirm/WithConfirm';
|
||||
import OutgoingWebhook2Form from 'containers/OutgoingWebhook2Form/OutgoingWebhook2Form';
|
||||
import OutgoingWebhook2Status from 'containers/OutgoingWebhook2Status/OutgoingWebhook2Status';
|
||||
import RemoteFilters from 'containers/RemoteFilters/RemoteFilters';
|
||||
import TeamName from 'containers/TeamName/TeamName';
|
||||
import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip';
|
||||
import { ActionDTO } from 'models/action';
|
||||
import { FiltersValues } from 'models/filters/filters.types';
|
||||
import { OutgoingWebhook } from 'models/outgoing_webhook/outgoing_webhook.types';
|
||||
import { OutgoingWebhook2 } from 'models/outgoing_webhook_2/outgoing_webhook_2.types';
|
||||
import { AppFeature } from 'state/features';
|
||||
import { PageProps, WithStoreProps } from 'state/types';
|
||||
import { withMobXProviderContext } from 'state/withStore';
|
||||
import { openErrorNotification, openNotification } from 'utils';
|
||||
import { isUserActionAllowed, UserActions } from 'utils/authorization';
|
||||
import { PLUGIN_ROOT } from 'utils/consts';
|
||||
|
||||
import styles from './OutgoingWebhooks2.module.css';
|
||||
import styles from './OutgoingWebhooks2.module.scss';
|
||||
import { WebhookFormActionType } from './OutgoingWebhooks2.types';
|
||||
|
||||
const cx = cn.bind(styles);
|
||||
|
||||
const Action = {
|
||||
STATUS: 'status',
|
||||
EDIT: 'edit',
|
||||
COPY: 'copy',
|
||||
};
|
||||
|
||||
interface OutgoingWebhooks2Props
|
||||
extends WithStoreProps,
|
||||
PageProps,
|
||||
RouteComponentProps<{ id: string; action: string }> {}
|
||||
|
||||
interface OutgoingWebhooks2State extends PageBaseState {
|
||||
outgoingWebhook2Action?: 'new' | 'update';
|
||||
outgoingWebhook2Action?: WebhookFormActionType;
|
||||
outgoingWebhook2Id?: OutgoingWebhook2['id'];
|
||||
confirmationModal: ConfirmModalProps;
|
||||
}
|
||||
|
||||
@observer
|
||||
class OutgoingWebhooks2 extends React.Component<OutgoingWebhooks2Props, OutgoingWebhooks2State> {
|
||||
state: OutgoingWebhooks2State = {
|
||||
errorData: initErrorDataState(),
|
||||
confirmationModal: undefined,
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps: OutgoingWebhooks2Props) {
|
||||
if (prevProps.match.params.id !== this.props.match.params.id) {
|
||||
if (prevProps.match.params.id !== this.props.match.params.id && !this.state.outgoingWebhook2Action) {
|
||||
this.parseQueryParams();
|
||||
}
|
||||
}
|
||||
|
|
@ -77,37 +82,36 @@ class OutgoingWebhooks2 extends React.Component<OutgoingWebhooks2Props, Outgoing
|
|||
},
|
||||
} = this.props;
|
||||
|
||||
if (!id) {
|
||||
return;
|
||||
if (action) {
|
||||
this.setState({ outgoingWebhook2Id: id, outgoingWebhook2Action: convertWebhookUrlToAction(action) });
|
||||
}
|
||||
|
||||
let outgoingWebhook2: OutgoingWebhook2 | void = undefined;
|
||||
const isNewWebhook = id === 'new';
|
||||
|
||||
if (!isNewWebhook) {
|
||||
outgoingWebhook2 = await store.outgoingWebhook2Store
|
||||
if (isNewWebhook) {
|
||||
this.setState({ outgoingWebhook2Id: id, outgoingWebhook2Action: WebhookFormActionType.NEW });
|
||||
} else if (id) {
|
||||
await store.outgoingWebhook2Store
|
||||
.loadItem(id, true)
|
||||
.catch((error) => this.setState({ errorData: { ...getWrongTeamResponseInfo(error) } }));
|
||||
}
|
||||
|
||||
if (isNewWebhook || (action === Action.COPY && outgoingWebhook2)) {
|
||||
this.setState({ outgoingWebhook2Id: id, outgoingWebhook2Action: 'new' });
|
||||
} else if (action === Action.EDIT && outgoingWebhook2) {
|
||||
this.setState({ outgoingWebhook2Id: id, outgoingWebhook2Action: 'update' });
|
||||
} else if (action === Action.STATUS && outgoingWebhook2) {
|
||||
this.setState({ outgoingWebhook2Id: id, outgoingWebhook2Action: undefined });
|
||||
.catch((error) =>
|
||||
this.setState({ errorData: { ...getWrongTeamResponseInfo(error) }, outgoingWebhook2Action: undefined })
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
update = () => {
|
||||
const { store } = this.props;
|
||||
|
||||
return store.outgoingWebhook2Store.updateItems();
|
||||
};
|
||||
|
||||
render() {
|
||||
const { store, query } = this.props;
|
||||
const { outgoingWebhook2Id, outgoingWebhook2Action, errorData } = this.state;
|
||||
const {
|
||||
store,
|
||||
history,
|
||||
match: {
|
||||
params: { id },
|
||||
},
|
||||
} = this.props;
|
||||
const { outgoingWebhook2Id, outgoingWebhook2Action, errorData, confirmationModal } = this.state;
|
||||
|
||||
const webhooks = store.outgoingWebhook2Store.getSearchResult();
|
||||
|
||||
|
|
@ -151,10 +155,21 @@ class OutgoingWebhooks2 extends React.Component<OutgoingWebhooks2Props, Outgoing
|
|||
errorData={errorData}
|
||||
objectName="outgoing webhook 2"
|
||||
pageName="outgoing_webhooks_2"
|
||||
itemNotFoundMessage={`Outgoing webhook with id=${query?.id} is not found. Please select outgoing webhook from the list.`}
|
||||
itemNotFoundMessage={`Outgoing webhook with id=${id} was not found. Please select outgoing webhook from the list.`}
|
||||
>
|
||||
{() => (
|
||||
<>
|
||||
{confirmationModal && (
|
||||
<ConfirmModal
|
||||
{...(confirmationModal as ConfirmModalProps)}
|
||||
onDismiss={() =>
|
||||
this.setState({
|
||||
confirmationModal: undefined,
|
||||
})
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className={cx('root')}>
|
||||
{this.renderOutgoingWebhooksFilters()}
|
||||
<GTable
|
||||
|
|
@ -192,19 +207,19 @@ class OutgoingWebhooks2 extends React.Component<OutgoingWebhooks2Props, Outgoing
|
|||
data={webhooks}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{outgoingWebhook2Id && outgoingWebhook2Action && (
|
||||
<OutgoingWebhook2Form
|
||||
id={outgoingWebhook2Id}
|
||||
action={outgoingWebhook2Action}
|
||||
onUpdate={this.update}
|
||||
onHide={this.handleOutgoingWebhookFormHide}
|
||||
/>
|
||||
)}
|
||||
{outgoingWebhook2Id && !outgoingWebhook2Action && (
|
||||
<OutgoingWebhook2Status
|
||||
id={outgoingWebhook2Id}
|
||||
onUpdate={this.update}
|
||||
onHide={this.handleOutgoingWebhookFormHide}
|
||||
onDelete={() => {
|
||||
this.onDeleteClick(outgoingWebhook2Id).then(() => {
|
||||
this.setState({ outgoingWebhook2Id: undefined, outgoingWebhook2Action: undefined });
|
||||
history.push(`${PLUGIN_ROOT}/outgoing_webhooks_2`);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
|
@ -245,53 +260,86 @@ class OutgoingWebhooks2 extends React.Component<OutgoingWebhooks2Props, Outgoing
|
|||
return <TeamName team={teams[record.team]} />;
|
||||
}
|
||||
|
||||
renderActionButtons = (record: ActionDTO) => {
|
||||
renderActionButtons = (record: OutgoingWebhook2) => {
|
||||
return (
|
||||
<HorizontalGroup justify="flex-end">
|
||||
<CopyToClipboard text={record.id}>
|
||||
<IconButton
|
||||
variant="primary"
|
||||
tooltip={
|
||||
<div>
|
||||
ID {record.id}
|
||||
<br />
|
||||
(click to copy ID to clipboard)
|
||||
<WithContextMenu
|
||||
renderMenuItems={() => (
|
||||
<div className={cx('hamburgerMenu')}>
|
||||
<div className={cx('hamburgerMenu__item')} onClick={() => this.onLastRunClick(record.id)}>
|
||||
<WithPermissionControlTooltip key={'status_action'} userAction={UserActions.OutgoingWebhooksRead}>
|
||||
<Text type="primary">View Last Run</Text>
|
||||
</WithPermissionControlTooltip>
|
||||
</div>
|
||||
|
||||
<div className={cx('hamburgerMenu__item')} onClick={() => this.onEditClick(record.id)}>
|
||||
<WithPermissionControlTooltip key={'edit_action'} userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<Text type="primary">Edit settings</Text>
|
||||
</WithPermissionControlTooltip>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={cx('hamburgerMenu__item')}
|
||||
onClick={() =>
|
||||
this.setState({
|
||||
confirmationModal: {
|
||||
isOpen: true,
|
||||
confirmText: 'Confirm',
|
||||
dismissText: 'Cancel',
|
||||
onConfirm: () => this.onDisableWebhook(record.id, !record.is_webhook_enabled),
|
||||
title: `Are you sure you want to ${record.is_webhook_enabled ? 'disable' : 'enable'} webhook?`,
|
||||
} as ConfirmModalProps,
|
||||
})
|
||||
}
|
||||
>
|
||||
<WithPermissionControlTooltip key={'disable_action'} userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<Text type="primary">{record.is_webhook_enabled ? 'Disable' : 'Enable'}</Text>
|
||||
</WithPermissionControlTooltip>
|
||||
</div>
|
||||
|
||||
<div className={cx('hamburgerMenu__item')} onClick={() => this.onCopyClick(record.id)}>
|
||||
<WithPermissionControlTooltip key={'copy_action'} userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<Text type="primary">Make a copy</Text>
|
||||
</WithPermissionControlTooltip>
|
||||
</div>
|
||||
|
||||
<CopyToClipboard text={record.id} onCopy={() => openNotification('Webhook ID has been copied')}>
|
||||
<div className={cx('hamburgerMenu__item')}>
|
||||
<HorizontalGroup type="primary" spacing="xs">
|
||||
<Icon name="clipboard-alt" />
|
||||
<Text type="primary">UID: {record.id}</Text>
|
||||
</HorizontalGroup>
|
||||
</div>
|
||||
}
|
||||
tooltipPlacement="top"
|
||||
name="info-circle"
|
||||
/>
|
||||
</CopyToClipboard>
|
||||
<WithPermissionControlTooltip key={'status_action'} userAction={UserActions.OutgoingWebhooksRead}>
|
||||
<IconButton
|
||||
tooltip="Status"
|
||||
tooltipPlacement="top"
|
||||
name="history"
|
||||
onClick={() => this.onStatusClick(record.id)}
|
||||
/>
|
||||
</WithPermissionControlTooltip>
|
||||
<WithPermissionControlTooltip key={'edit_action'} userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<IconButton tooltip="Edit" tooltipPlacement="top" name="cog" onClick={() => this.onEditClick(record.id)} />
|
||||
</WithPermissionControlTooltip>
|
||||
<WithPermissionControlTooltip key={'copy_action'} userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<IconButton
|
||||
tooltip="Make a copy"
|
||||
tooltipPlacement="top"
|
||||
name="copy"
|
||||
onClick={() => this.onCopyClick(record.id)}
|
||||
/>
|
||||
</WithPermissionControlTooltip>
|
||||
<WithPermissionControlTooltip key={'delete_action'} userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<WithConfirm title={`Are you sure to remove "${record.name}"?`} confirmText="Remove">
|
||||
<IconButton
|
||||
tooltip="Remove"
|
||||
tooltipPlacement="top"
|
||||
onClick={this.getDeleteClickHandler(record.id)}
|
||||
name="trash-alt"
|
||||
/>
|
||||
</WithConfirm>
|
||||
</WithPermissionControlTooltip>
|
||||
</HorizontalGroup>
|
||||
</CopyToClipboard>
|
||||
|
||||
<div className={cx('thin-line-break')} />
|
||||
|
||||
<div
|
||||
className={cx('hamburgerMenu__item')}
|
||||
onClick={() =>
|
||||
this.setState({
|
||||
confirmationModal: {
|
||||
isOpen: true,
|
||||
confirmText: 'Confirm',
|
||||
dismissText: 'Cancel',
|
||||
onConfirm: () => this.onDeleteClick(record.id),
|
||||
body: 'The action cannot be undone.',
|
||||
title: `Are you sure you want to delete webhook?`,
|
||||
} as Partial<ConfirmModalProps> as ConfirmModalProps,
|
||||
})
|
||||
}
|
||||
>
|
||||
<WithPermissionControlTooltip key={'delete_action'} userAction={UserActions.OutgoingWebhooksWrite}>
|
||||
<HorizontalGroup spacing="xs">
|
||||
<IconButton tooltip="Remove" tooltipPlacement="top" variant="destructive" name="trash-alt" />
|
||||
<Text type="danger">Delete Webhook</Text>
|
||||
</HorizontalGroup>
|
||||
</WithPermissionControlTooltip>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
>
|
||||
{({ openMenu }) => <HamburgerMenu openMenu={openMenu} listBorder={2} listWidth={225} withBackground />}
|
||||
</WithContextMenu>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
@ -331,36 +379,56 @@ class OutgoingWebhooks2 extends React.Component<OutgoingWebhooks2Props, Outgoing
|
|||
);
|
||||
}
|
||||
|
||||
getDeleteClickHandler = (id: OutgoingWebhook2['id']) => {
|
||||
onDeleteClick = (id: OutgoingWebhook2['id']): Promise<void> => {
|
||||
const { store } = this.props;
|
||||
|
||||
return () => {
|
||||
store.outgoingWebhook2Store.delete(id).then(this.update);
|
||||
};
|
||||
return store.outgoingWebhook2Store
|
||||
.delete(id)
|
||||
.then(this.update)
|
||||
.then(() => openNotification('Webhook has been removed'))
|
||||
.catch(() => openNotification('Webook could not been removed'))
|
||||
.finally(() => this.setState({ confirmationModal: undefined }));
|
||||
};
|
||||
|
||||
onEditClick = (id: OutgoingWebhook2['id']) => {
|
||||
const { history } = this.props;
|
||||
|
||||
this.setState({ outgoingWebhook2Id: id, outgoingWebhook2Action: 'update' });
|
||||
|
||||
history.push(`${PLUGIN_ROOT}/outgoing_webhooks_2/edit/${id}`);
|
||||
this.setState({ outgoingWebhook2Id: id, outgoingWebhook2Action: WebhookFormActionType.EDIT_SETTINGS }, () =>
|
||||
history.push(`${PLUGIN_ROOT}/outgoing_webhooks_2/edit/${id}`)
|
||||
);
|
||||
};
|
||||
|
||||
onCopyClick = (id: OutgoingWebhook2['id']) => {
|
||||
const { history } = this.props;
|
||||
|
||||
this.setState({ outgoingWebhook2Id: id, outgoingWebhook2Action: 'new' });
|
||||
|
||||
history.push(`${PLUGIN_ROOT}/outgoing_webhooks_2/copy/${id}`);
|
||||
this.setState({ outgoingWebhook2Id: id, outgoingWebhook2Action: WebhookFormActionType.COPY }, () =>
|
||||
history.push(`${PLUGIN_ROOT}/outgoing_webhooks_2/copy/${id}`)
|
||||
);
|
||||
};
|
||||
|
||||
onStatusClick = (id: OutgoingWebhook2['id']) => {
|
||||
onDisableWebhook = (id: OutgoingWebhook2['id'], isEnabled: boolean) => {
|
||||
const {
|
||||
store: { outgoingWebhook2Store },
|
||||
} = this.props;
|
||||
|
||||
const data = {
|
||||
...{ ...outgoingWebhook2Store.items[id], is_webhook_enabled: isEnabled },
|
||||
is_legacy: false,
|
||||
};
|
||||
|
||||
outgoingWebhook2Store
|
||||
.update(id, data)
|
||||
.then(() => this.update())
|
||||
.then(() => openNotification(`Webhook has been ${isEnabled ? 'enabled' : 'disabled'}`))
|
||||
.catch(() => openErrorNotification('Webhook could not been updated'))
|
||||
.finally(() => this.setState({ confirmationModal: undefined }));
|
||||
};
|
||||
|
||||
onLastRunClick = (id: OutgoingWebhook2['id']) => {
|
||||
const { history } = this.props;
|
||||
|
||||
this.setState({ outgoingWebhook2Id: id, outgoingWebhook2Action: undefined });
|
||||
|
||||
history.push(`${PLUGIN_ROOT}/outgoing_webhooks_2/status/${id}`);
|
||||
this.setState({ outgoingWebhook2Id: id, outgoingWebhook2Action: WebhookFormActionType.VIEW_LAST_RUN }, () =>
|
||||
history.push(`${PLUGIN_ROOT}/outgoing_webhooks_2/last_run/${id}`)
|
||||
);
|
||||
};
|
||||
|
||||
handleOutgoingWebhookFormHide = () => {
|
||||
|
|
@ -372,6 +440,18 @@ class OutgoingWebhooks2 extends React.Component<OutgoingWebhooks2Props, Outgoing
|
|||
};
|
||||
}
|
||||
|
||||
function convertWebhookUrlToAction(urlAction: string) {
|
||||
if (urlAction === 'new') {
|
||||
return WebhookFormActionType.NEW;
|
||||
} else if (urlAction === 'copy') {
|
||||
return WebhookFormActionType.COPY;
|
||||
} else if (urlAction === 'edit') {
|
||||
return WebhookFormActionType.EDIT_SETTINGS;
|
||||
} else {
|
||||
return WebhookFormActionType.VIEW_LAST_RUN;
|
||||
}
|
||||
}
|
||||
|
||||
export { OutgoingWebhooks2 };
|
||||
|
||||
export default withRouter(withMobXProviderContext(OutgoingWebhooks2));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
export enum WebhookFormActionType {
|
||||
NEW = 1,
|
||||
COPY = 2,
|
||||
VIEW_LAST_RUN = 3,
|
||||
EDIT_SETTINGS = 4,
|
||||
}
|
||||
|
|
@ -80,3 +80,7 @@
|
|||
.u-margin-right-md {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue