mirror of
https://github.com/plankanban/planka.git
synced 2025-07-18 20:59:44 +02:00
feat: Move webhooks configuration from environment variable to UI
This commit is contained in:
parent
f0680831c2
commit
b22dba0d11
128 changed files with 2077 additions and 206 deletions
|
@ -8,6 +8,7 @@ import ActionTypes from '../constants/ActionTypes';
|
|||
const initializeCore = (
|
||||
user,
|
||||
board,
|
||||
webhooks,
|
||||
users,
|
||||
projects,
|
||||
projectManagers,
|
||||
|
@ -33,6 +34,7 @@ const initializeCore = (
|
|||
payload: {
|
||||
user,
|
||||
board,
|
||||
webhooks,
|
||||
users,
|
||||
projects,
|
||||
projectManagers,
|
||||
|
|
|
@ -8,6 +8,7 @@ import socket from './socket';
|
|||
import login from './login';
|
||||
import core from './core';
|
||||
import modals from './modals';
|
||||
import webhooks from './webhooks';
|
||||
import users from './users';
|
||||
import projects from './projects';
|
||||
import projectManagers from './project-managers';
|
||||
|
@ -35,6 +36,7 @@ export default {
|
|||
...login,
|
||||
...core,
|
||||
...modals,
|
||||
...webhooks,
|
||||
...users,
|
||||
...projects,
|
||||
...projectManagers,
|
||||
|
|
|
@ -14,6 +14,7 @@ const handleSocketReconnect = (
|
|||
config,
|
||||
user,
|
||||
board,
|
||||
webhooks,
|
||||
users,
|
||||
projects,
|
||||
projectManagers,
|
||||
|
@ -40,6 +41,7 @@ const handleSocketReconnect = (
|
|||
config,
|
||||
user,
|
||||
board,
|
||||
webhooks,
|
||||
users,
|
||||
projects,
|
||||
projectManagers,
|
||||
|
|
|
@ -67,6 +67,7 @@ const handleUserUpdate = (
|
|||
boardIds,
|
||||
config,
|
||||
board,
|
||||
webhooks,
|
||||
users,
|
||||
projects,
|
||||
projectManagers,
|
||||
|
@ -95,6 +96,7 @@ const handleUserUpdate = (
|
|||
boardIds,
|
||||
config,
|
||||
board,
|
||||
webhooks,
|
||||
users,
|
||||
projects,
|
||||
projectManagers,
|
||||
|
|
104
client/src/actions/webhooks.js
Normal file
104
client/src/actions/webhooks.js
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import ActionTypes from '../constants/ActionTypes';
|
||||
|
||||
const createWebhook = (webhook) => ({
|
||||
type: ActionTypes.WEBHOOK_CREATE,
|
||||
payload: {
|
||||
webhook,
|
||||
},
|
||||
});
|
||||
|
||||
createWebhook.success = (localId, webhook) => ({
|
||||
type: ActionTypes.WEBHOOK_CREATE__SUCCESS,
|
||||
payload: {
|
||||
localId,
|
||||
webhook,
|
||||
},
|
||||
});
|
||||
|
||||
createWebhook.failure = (localId, error) => ({
|
||||
type: ActionTypes.WEBHOOK_CREATE__FAILURE,
|
||||
payload: {
|
||||
localId,
|
||||
error,
|
||||
},
|
||||
});
|
||||
|
||||
const handleWebhookCreate = (webhook) => ({
|
||||
type: ActionTypes.WEBHOOK_CREATE_HANDLE,
|
||||
payload: {
|
||||
webhook,
|
||||
},
|
||||
});
|
||||
|
||||
const updateWebhook = (id, data) => ({
|
||||
type: ActionTypes.WEBHOOK_UPDATE,
|
||||
payload: {
|
||||
id,
|
||||
data,
|
||||
},
|
||||
});
|
||||
|
||||
updateWebhook.success = (webhook) => ({
|
||||
type: ActionTypes.WEBHOOK_UPDATE__SUCCESS,
|
||||
payload: {
|
||||
webhook,
|
||||
},
|
||||
});
|
||||
|
||||
updateWebhook.failure = (id, error) => ({
|
||||
type: ActionTypes.WEBHOOK_UPDATE__FAILURE,
|
||||
payload: {
|
||||
id,
|
||||
error,
|
||||
},
|
||||
});
|
||||
|
||||
const handleWebhookUpdate = (webhook) => ({
|
||||
type: ActionTypes.WEBHOOK_UPDATE_HANDLE,
|
||||
payload: {
|
||||
webhook,
|
||||
},
|
||||
});
|
||||
|
||||
const deleteWebhook = (id) => ({
|
||||
type: ActionTypes.WEBHOOK_DELETE,
|
||||
payload: {
|
||||
id,
|
||||
},
|
||||
});
|
||||
|
||||
deleteWebhook.success = (webhook) => ({
|
||||
type: ActionTypes.WEBHOOK_DELETE__SUCCESS,
|
||||
payload: {
|
||||
webhook,
|
||||
},
|
||||
});
|
||||
|
||||
deleteWebhook.failure = (id, error) => ({
|
||||
type: ActionTypes.WEBHOOK_DELETE__FAILURE,
|
||||
payload: {
|
||||
id,
|
||||
error,
|
||||
},
|
||||
});
|
||||
|
||||
const handleWebhookDelete = (webhook) => ({
|
||||
type: ActionTypes.WEBHOOK_DELETE_HANDLE,
|
||||
payload: {
|
||||
webhook,
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
createWebhook,
|
||||
handleWebhookCreate,
|
||||
updateWebhook,
|
||||
handleWebhookUpdate,
|
||||
deleteWebhook,
|
||||
handleWebhookDelete,
|
||||
};
|
|
@ -7,6 +7,7 @@ import http from './http';
|
|||
import socket from './socket';
|
||||
import config from './config';
|
||||
import accessTokens from './access-tokens';
|
||||
import webhooks from './webhooks';
|
||||
import users from './users';
|
||||
import projects from './projects';
|
||||
import projectManagers from './project-managers';
|
||||
|
@ -35,6 +36,7 @@ export { http, socket };
|
|||
export default {
|
||||
...config,
|
||||
...accessTokens,
|
||||
...webhooks,
|
||||
...users,
|
||||
...projects,
|
||||
...projectManagers,
|
||||
|
|
23
client/src/api/webhooks.js
Executable file
23
client/src/api/webhooks.js
Executable file
|
@ -0,0 +1,23 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import socket from './socket';
|
||||
|
||||
/* Actions */
|
||||
|
||||
const getWebhooks = (headers) => socket.get('/webhooks', undefined, headers);
|
||||
|
||||
const createWebhook = (data, headers) => socket.post('/webhooks', data, headers);
|
||||
|
||||
const updateWebhook = (id, data, headers) => socket.patch(`/webhooks/${id}`, data, headers);
|
||||
|
||||
const deleteWebhook = (id, headers) => socket.delete(`/webhooks/${id}`, undefined, headers);
|
||||
|
||||
export default {
|
||||
getWebhooks,
|
||||
createWebhook,
|
||||
updateWebhook,
|
||||
deleteWebhook,
|
||||
};
|
|
@ -12,6 +12,7 @@ import { Modal, Tab } from 'semantic-ui-react';
|
|||
import entryActions from '../../../entry-actions';
|
||||
import { useClosableModal } from '../../../hooks';
|
||||
import UsersPane from './UsersPane';
|
||||
import WebhooksPane from './WebhooksPane';
|
||||
|
||||
import styles from './AdministrationModal.module.scss';
|
||||
|
||||
|
@ -37,6 +38,12 @@ const AdministrationModal = React.memo(() => {
|
|||
}),
|
||||
render: () => <UsersPane />,
|
||||
},
|
||||
{
|
||||
menuItem: t('common.webhooks', {
|
||||
context: 'title',
|
||||
}),
|
||||
render: () => <WebhooksPane />,
|
||||
},
|
||||
];
|
||||
|
||||
const isUsersPaneActive = activeTabIndex === 0;
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { Tab } from 'semantic-ui-react';
|
||||
|
||||
import selectors from '../../../selectors';
|
||||
import entryActions from '../../../entry-actions';
|
||||
import Webhooks from '../../webhooks/Webhooks';
|
||||
|
||||
import styles from './WebhooksPane.module.scss';
|
||||
|
||||
const WebhooksPane = React.memo(() => {
|
||||
const webhookIds = useSelector(selectors.selectWebhookIds);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const handleCreate = useCallback(
|
||||
(data) => {
|
||||
dispatch(entryActions.createWebhook(data));
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
return (
|
||||
<Tab.Pane attached={false} className={styles.wrapper}>
|
||||
<Webhooks ids={webhookIds} onCreate={handleCreate} />
|
||||
</Tab.Pane>
|
||||
);
|
||||
});
|
||||
|
||||
export default WebhooksPane;
|
|
@ -0,0 +1,11 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
:global(#app) {
|
||||
.wrapper {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
|
@ -28,7 +28,10 @@ const ConfirmationStep = React.memo(
|
|||
|
||||
const [nameFieldRef, handleNameFieldRef] = useNestedRef('inputRef');
|
||||
|
||||
const handleSubmit = useCallback(() => {
|
||||
const handleSubmit = useCallback(
|
||||
(event) => {
|
||||
event.stopPropagation();
|
||||
|
||||
if (typeValue) {
|
||||
const cleanData = {
|
||||
...data,
|
||||
|
@ -42,7 +45,9 @@ const ConfirmationStep = React.memo(
|
|||
}
|
||||
|
||||
onConfirm();
|
||||
}, [typeValue, onConfirm, data, nameFieldRef]);
|
||||
},
|
||||
[typeValue, onConfirm, data, nameFieldRef],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeValue) {
|
||||
|
|
|
@ -125,7 +125,7 @@ const Item = React.memo(({ id }) => {
|
|||
dispatch(entryActions.deleteNotificationService(id));
|
||||
}, [id, dispatch]);
|
||||
|
||||
const handleUpdateSubmit = useCallback(() => {
|
||||
const handleSubmit = useCallback(() => {
|
||||
urlFieldRef.current.blur();
|
||||
}, [urlFieldRef]);
|
||||
|
||||
|
@ -153,7 +153,7 @@ const Item = React.memo(({ id }) => {
|
|||
const ConfirmationPopup = usePopupInClosableContext(ConfirmationStep);
|
||||
|
||||
return (
|
||||
<Form className={styles.wrapper} onSubmit={handleUpdateSubmit}>
|
||||
<Form className={styles.wrapper} onSubmit={handleSubmit}>
|
||||
<Input
|
||||
ref={handleUrlFieldRef}
|
||||
name="url"
|
||||
|
|
152
client/src/components/webhooks/Webhooks/Editor.jsx
Normal file
152
client/src/components/webhooks/Webhooks/Editor.jsx
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import React, { useCallback, useImperativeHandle } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Dropdown, Input } from 'semantic-ui-react';
|
||||
|
||||
import { useNestedRef } from '../../../hooks';
|
||||
import WEBHOOK_EVENTS from '../../../constants/WebhookEvents';
|
||||
|
||||
import styles from './Editor.module.scss';
|
||||
|
||||
const Editor = React.forwardRef(({ data, isReadOnly, onFieldChange }, ref) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const [nameFieldRef, handleNameFieldRef] = useNestedRef('inputRef');
|
||||
const [urlFieldRef, handleUrlFieldRef] = useNestedRef('inputRef');
|
||||
|
||||
const focusNameField = useCallback(() => {
|
||||
nameFieldRef.current.focus({
|
||||
preventScroll: true,
|
||||
});
|
||||
}, [nameFieldRef]);
|
||||
|
||||
const selectNameField = useCallback(() => {
|
||||
nameFieldRef.current.select();
|
||||
}, [nameFieldRef]);
|
||||
|
||||
const selectUrlField = useCallback(() => {
|
||||
urlFieldRef.current.select();
|
||||
}, [urlFieldRef]);
|
||||
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => ({
|
||||
focusNameField,
|
||||
selectNameField,
|
||||
selectUrlField,
|
||||
}),
|
||||
[focusNameField, selectNameField, selectUrlField],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.text}>{t('common.title')}</div>
|
||||
<Input
|
||||
fluid
|
||||
ref={handleNameFieldRef}
|
||||
name="name"
|
||||
value={data.name}
|
||||
maxLength={128}
|
||||
readOnly={isReadOnly}
|
||||
className={styles.field}
|
||||
onChange={onFieldChange}
|
||||
/>
|
||||
<div className={styles.text}>{t('common.url')}</div>
|
||||
<Input
|
||||
fluid
|
||||
ref={handleUrlFieldRef}
|
||||
name="url"
|
||||
value={data.url}
|
||||
maxLength={2048}
|
||||
readOnly={isReadOnly}
|
||||
className={styles.field}
|
||||
onChange={onFieldChange}
|
||||
/>
|
||||
<div className={styles.text}>
|
||||
{t('common.accessToken')} (
|
||||
{t('common.optional', {
|
||||
context: 'inline',
|
||||
})}
|
||||
)
|
||||
</div>
|
||||
<Input
|
||||
fluid
|
||||
name="accessToken"
|
||||
value={data.accessToken}
|
||||
maxLength={512}
|
||||
readOnly={isReadOnly}
|
||||
className={styles.field}
|
||||
onChange={onFieldChange}
|
||||
/>
|
||||
{data.excludedEvents.length === 0 && (
|
||||
<>
|
||||
<div className={styles.text}>
|
||||
{t('common.events')} (
|
||||
{t('common.optional', {
|
||||
context: 'inline',
|
||||
})}
|
||||
)
|
||||
</div>
|
||||
<Dropdown
|
||||
selection
|
||||
multiple
|
||||
fluid
|
||||
name="events"
|
||||
options={WEBHOOK_EVENTS.map((event) => ({
|
||||
text: event,
|
||||
value: event,
|
||||
}))}
|
||||
value={data.events}
|
||||
placeholder="All"
|
||||
readOnly={isReadOnly}
|
||||
className={styles.field}
|
||||
onChange={onFieldChange}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{data.events.length === 0 && (
|
||||
<>
|
||||
<div className={styles.text}>
|
||||
{t('common.excludedEvents')} (
|
||||
{t('common.optional', {
|
||||
context: 'inline',
|
||||
})}
|
||||
)
|
||||
</div>
|
||||
<Dropdown
|
||||
selection
|
||||
multiple
|
||||
fluid
|
||||
name="excludedEvents"
|
||||
options={WEBHOOK_EVENTS.map((event) => ({
|
||||
text: event,
|
||||
value: event,
|
||||
}))}
|
||||
value={data.excludedEvents}
|
||||
placeholder="None"
|
||||
readOnly={isReadOnly}
|
||||
className={styles.field}
|
||||
onChange={onFieldChange}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
Editor.propTypes = {
|
||||
data: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
isReadOnly: PropTypes.bool,
|
||||
onFieldChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
Editor.defaultProps = {
|
||||
isReadOnly: false,
|
||||
};
|
||||
|
||||
export default React.memo(Editor);
|
17
client/src/components/webhooks/Webhooks/Editor.module.scss
Normal file
17
client/src/components/webhooks/Webhooks/Editor.module.scss
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
:global(#app) {
|
||||
.field {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.text {
|
||||
color: #444444;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
}
|
137
client/src/components/webhooks/Webhooks/Item.jsx
Normal file
137
client/src/components/webhooks/Webhooks/Item.jsx
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import { dequal } from 'dequal';
|
||||
import React, { useCallback, useMemo, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Accordion, Button, Form, Icon } from 'semantic-ui-react';
|
||||
|
||||
import selectors from '../../../selectors';
|
||||
import entryActions from '../../../entry-actions';
|
||||
import { useForm, usePopupInClosableContext } from '../../../hooks';
|
||||
import { isUrl } from '../../../utils/validator';
|
||||
import Editor from './Editor';
|
||||
import ConfirmationStep from '../../common/ConfirmationStep';
|
||||
|
||||
import styles from './Item.module.scss';
|
||||
import { useToggle } from '../../../lib/hooks';
|
||||
|
||||
const Item = React.memo(({ id }) => {
|
||||
const selectWebhookById = useMemo(() => selectors.makeSelectWebhookById(), []);
|
||||
|
||||
const webhook = useSelector((state) => selectWebhookById(state, id));
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const [t] = useTranslation();
|
||||
const [isOpened, toggleOpened] = useToggle();
|
||||
|
||||
const defaultData = useMemo(
|
||||
() => ({
|
||||
name: webhook.name,
|
||||
url: webhook.url,
|
||||
accessToken: webhook.accessToken,
|
||||
events: webhook.events,
|
||||
excludedEvents: webhook.excludedEvents,
|
||||
}),
|
||||
[webhook],
|
||||
);
|
||||
|
||||
const [data, handleFieldChange] = useForm(() => ({
|
||||
name: '',
|
||||
url: '',
|
||||
...defaultData,
|
||||
accessToken: defaultData.accessToken || '',
|
||||
events: defaultData.events || [],
|
||||
excludedEvents: defaultData.excludedEvents || [],
|
||||
}));
|
||||
|
||||
const cleanData = useMemo(
|
||||
() => ({
|
||||
...data,
|
||||
name: data.name.trim(),
|
||||
url: data.url.trim(),
|
||||
accessToken: data.accessToken.trim() || null,
|
||||
events: data.events.length === 0 ? null : data.events,
|
||||
excludedEvents: data.excludedEvents.length === 0 ? null : data.excludedEvents,
|
||||
}),
|
||||
[data],
|
||||
);
|
||||
|
||||
const editorRef = useRef(null);
|
||||
|
||||
const handleDeleteConfirm = useCallback(() => {
|
||||
dispatch(entryActions.deleteWebhook(id));
|
||||
}, [id, dispatch]);
|
||||
|
||||
const handleSubmit = useCallback(() => {
|
||||
if (!cleanData.name) {
|
||||
editorRef.current.selectNameField();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cleanData.url || !isUrl(cleanData.url)) {
|
||||
editorRef.current.selectUrlField();
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(entryActions.updateWebhook(id, cleanData));
|
||||
}, [id, dispatch, cleanData]);
|
||||
|
||||
const handleOpenClick = useCallback(() => {
|
||||
toggleOpened();
|
||||
}, [toggleOpened]);
|
||||
|
||||
const ConfirmationPopup = usePopupInClosableContext(ConfirmationStep);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Accordion.Title active={isOpened} className={styles.title} onClick={handleOpenClick}>
|
||||
<Icon name="dropdown" />
|
||||
{defaultData.name}
|
||||
</Accordion.Title>
|
||||
<Accordion.Content active={isOpened}>
|
||||
<div>
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<Editor
|
||||
ref={editorRef}
|
||||
data={data}
|
||||
isReadOnly={!webhook.isPersisted}
|
||||
onFieldChange={handleFieldChange}
|
||||
/>
|
||||
<div className={styles.controls}>
|
||||
<Button
|
||||
positive
|
||||
disabled={dequal(cleanData, defaultData)}
|
||||
content={t('action.save')}
|
||||
/>
|
||||
<ConfirmationPopup
|
||||
title="common.deleteWebhook"
|
||||
content="common.areYouSureYouWantToDeleteThisWebhook"
|
||||
buttonContent="action.deleteWebhook"
|
||||
onConfirm={handleDeleteConfirm}
|
||||
>
|
||||
<Button
|
||||
type="button"
|
||||
disabled={!webhook.isPersisted}
|
||||
className={styles.deleteButton}
|
||||
>
|
||||
{t('action.delete')}
|
||||
</Button>
|
||||
</ConfirmationPopup>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</Accordion.Content>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
Item.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default Item;
|
22
client/src/components/webhooks/Webhooks/Item.module.scss
Normal file
22
client/src/components/webhooks/Webhooks/Item.module.scss
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
:global(#app) {
|
||||
.controls {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.deleteButton {
|
||||
box-shadow: 0 1px 0 #cbcccc;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
96
client/src/components/webhooks/Webhooks/Webhooks.jsx
Normal file
96
client/src/components/webhooks/Webhooks/Webhooks.jsx
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Accordion, Button, Form, Segment } from 'semantic-ui-react';
|
||||
import { useDidUpdate, useToggle } from '../../../lib/hooks';
|
||||
|
||||
import { useForm } from '../../../hooks';
|
||||
import { isUrl } from '../../../utils/validator';
|
||||
import Item from './Item';
|
||||
import Editor from './Editor';
|
||||
|
||||
const DEFAULT_DATA = {
|
||||
name: '',
|
||||
url: '',
|
||||
accessToken: '',
|
||||
events: [],
|
||||
excludedEvents: [],
|
||||
};
|
||||
|
||||
const Webhooks = React.memo(({ ids, onCreate }) => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
const [data, handleFieldChange, setData] = useForm(DEFAULT_DATA);
|
||||
const [focusNameFieldState, focusNameField] = useToggle();
|
||||
|
||||
const editorRef = useRef(null);
|
||||
|
||||
const handleCreateSubmit = useCallback(() => {
|
||||
const cleanData = {
|
||||
...data,
|
||||
name: data.name.trim(),
|
||||
url: data.url.trim(),
|
||||
accessToken: data.accessToken.trim() || null,
|
||||
events: data.events.length === 0 ? null : data.events,
|
||||
excludedEvents: data.excludedEvents.length === 0 ? null : data.excludedEvents,
|
||||
};
|
||||
|
||||
if (!cleanData.name) {
|
||||
editorRef.current.selectNameField();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cleanData.url || !isUrl(cleanData.url)) {
|
||||
editorRef.current.selectUrlField();
|
||||
return;
|
||||
}
|
||||
|
||||
onCreate(cleanData);
|
||||
setData(DEFAULT_DATA);
|
||||
focusNameField();
|
||||
}, [onCreate, data, setData, focusNameField]);
|
||||
|
||||
useEffect(() => {
|
||||
if (editorRef.current) {
|
||||
editorRef.current.focusNameField();
|
||||
}
|
||||
}, []);
|
||||
|
||||
useDidUpdate(() => {
|
||||
if (editorRef.current) {
|
||||
editorRef.current.focusNameField();
|
||||
}
|
||||
}, [focusNameFieldState]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{ids.length > 0 && (
|
||||
<Accordion styled fluid>
|
||||
{ids.map((id) => (
|
||||
<Item key={id} id={id} />
|
||||
))}
|
||||
</Accordion>
|
||||
)}
|
||||
{ids.length < 10 && (
|
||||
<Segment>
|
||||
<Form onSubmit={handleCreateSubmit}>
|
||||
<Editor ref={editorRef} data={data} onFieldChange={handleFieldChange} />
|
||||
<Button positive>{t('action.addWebhook')}</Button>
|
||||
</Form>
|
||||
</Segment>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
Webhooks.propTypes = {
|
||||
ids: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types
|
||||
onCreate: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default Webhooks;
|
8
client/src/components/webhooks/Webhooks/index.js
Normal file
8
client/src/components/webhooks/Webhooks/index.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import Webhooks from './Webhooks';
|
||||
|
||||
export default Webhooks;
|
|
@ -42,6 +42,21 @@ export default {
|
|||
MODAL_OPEN: 'MODAL_OPEN',
|
||||
MODAL_CLOSE: 'MODAL_CLOSE',
|
||||
|
||||
/* Webhooks */
|
||||
|
||||
WEBHOOK_CREATE: 'WEBHOOK_CREATE',
|
||||
WEBHOOK_CREATE__SUCCESS: 'WEBHOOK_CREATE__SUCCESS',
|
||||
WEBHOOK_CREATE__FAILURE: 'WEBHOOK_CREATE__FAILURE',
|
||||
WEBHOOK_CREATE_HANDLE: 'WEBHOOK_CREATE_HANDLE',
|
||||
WEBHOOK_UPDATE: 'WEBHOOK_UPDATE',
|
||||
WEBHOOK_UPDATE__SUCCESS: 'WEBHOOK_UPDATE__SUCCESS',
|
||||
WEBHOOK_UPDATE__FAILURE: 'WEBHOOK_UPDATE__FAILURE',
|
||||
WEBHOOK_UPDATE_HANDLE: 'WEBHOOK_UPDATE_HANDLE',
|
||||
WEBHOOK_DELETE: 'WEBHOOK_DELETE',
|
||||
WEBHOOK_DELETE__SUCCESS: 'WEBHOOK_DELETE__SUCCESS',
|
||||
WEBHOOK_DELETE__FAILURE: 'WEBHOOK_DELETE__FAILURE',
|
||||
WEBHOOK_DELETE_HANDLE: 'WEBHOOK_DELETE_HANDLE',
|
||||
|
||||
/* Users */
|
||||
|
||||
USER_CREATE: 'USER_CREATE',
|
||||
|
|
|
@ -31,6 +31,15 @@ export default {
|
|||
MODAL_OPEN: `${PREFIX}/MODAL_OPEN`,
|
||||
MODAL_CLOSE: `${PREFIX}/MODAL_CLOSE`,
|
||||
|
||||
/* Webhooks */
|
||||
|
||||
WEBHOOK_CREATE: `${PREFIX}/WEBHOOK_CREATE`,
|
||||
WEBHOOK_CREATE_HANDLE: `${PREFIX}/WEBHOOK_CREATE_HANDLE`,
|
||||
WEBHOOK_UPDATE: `${PREFIX}/WEBHOOK_UPDATE`,
|
||||
WEBHOOK_UPDATE_HANDLE: `${PREFIX}/WEBHOOK_UPDATE_HANDLE`,
|
||||
WEBHOOK_DELETE: `${PREFIX}/WEBHOOK_DELETE`,
|
||||
WEBHOOK_DELETE_HANDLE: `${PREFIX}/WEBHOOK_DELETE_HANDLE`,
|
||||
|
||||
/* Users */
|
||||
|
||||
USER_CREATE: `${PREFIX}/USER_CREATE`,
|
||||
|
|
91
client/src/constants/WebhookEvents.js
Normal file
91
client/src/constants/WebhookEvents.js
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
export default [
|
||||
'actionCreate',
|
||||
|
||||
'attachmentCreate',
|
||||
'attachmentUpdate',
|
||||
'attachmentDelete',
|
||||
|
||||
'backgroundImageCreate',
|
||||
'backgroundImageDelete',
|
||||
|
||||
'baseCustomFieldGroupCreate',
|
||||
'baseCustomFieldGroupUpdate',
|
||||
'baseCustomFieldGroupDelete',
|
||||
|
||||
'boardCreate',
|
||||
'boardUpdate',
|
||||
'boardDelete',
|
||||
|
||||
'boardMembershipCreate',
|
||||
'boardMembershipUpdate',
|
||||
'boardMembershipDelete',
|
||||
|
||||
'cardCreate',
|
||||
'cardUpdate',
|
||||
'cardDelete',
|
||||
|
||||
'cardLabelCreate',
|
||||
'cardLabelDelete',
|
||||
|
||||
'cardMembershipCreate',
|
||||
'cardMembershipDelete',
|
||||
|
||||
'commentCreate',
|
||||
'commentUpdate',
|
||||
'commentDelete',
|
||||
|
||||
'customFieldCreate',
|
||||
'customFieldUpdate',
|
||||
'customFieldDelete',
|
||||
|
||||
'customFieldGroupCreate',
|
||||
'customFieldGroupUpdate',
|
||||
'customFieldGroupDelete',
|
||||
|
||||
'customFieldValueUpdate',
|
||||
'customFieldValueDelete',
|
||||
|
||||
'labelCreate',
|
||||
'labelUpdate',
|
||||
'labelDelete',
|
||||
|
||||
'listCreate',
|
||||
'listUpdate',
|
||||
'listClear',
|
||||
'listDelete',
|
||||
|
||||
'notificationCreate',
|
||||
'notificationUpdate',
|
||||
|
||||
'notificationServiceCreate',
|
||||
'notificationServiceUpdate',
|
||||
'notificationServiceDelete',
|
||||
|
||||
'projectCreate',
|
||||
'projectUpdate',
|
||||
'projectDelete',
|
||||
|
||||
'projectManagerCreate',
|
||||
'projectManagerDelete',
|
||||
|
||||
'taskCreate',
|
||||
'taskUpdate',
|
||||
'taskDelete',
|
||||
|
||||
'taskListCreate',
|
||||
'taskListUpdate',
|
||||
'taskListDelete',
|
||||
|
||||
'userCreate',
|
||||
'userUpdate',
|
||||
'userDelete',
|
||||
|
||||
'webhookCreate',
|
||||
'webhookUpdate',
|
||||
'webhookDelete',
|
||||
];
|
|
@ -7,6 +7,7 @@ import socket from './socket';
|
|||
import login from './login';
|
||||
import core from './core';
|
||||
import modals from './modals';
|
||||
import webhooks from './webhooks';
|
||||
import users from './users';
|
||||
import projects from './projects';
|
||||
import projectManagers from './project-managers';
|
||||
|
@ -33,6 +34,7 @@ export default {
|
|||
...login,
|
||||
...core,
|
||||
...modals,
|
||||
...webhooks,
|
||||
...users,
|
||||
...projects,
|
||||
...projectManagers,
|
||||
|
|
58
client/src/entry-actions/webhooks.js
Normal file
58
client/src/entry-actions/webhooks.js
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import EntryActionTypes from '../constants/EntryActionTypes';
|
||||
|
||||
const createWebhook = (data) => ({
|
||||
type: EntryActionTypes.WEBHOOK_CREATE,
|
||||
payload: {
|
||||
data,
|
||||
},
|
||||
});
|
||||
|
||||
const handleWebhookCreate = (webhook) => ({
|
||||
type: EntryActionTypes.WEBHOOK_CREATE_HANDLE,
|
||||
payload: {
|
||||
webhook,
|
||||
},
|
||||
});
|
||||
|
||||
const updateWebhook = (id, data) => ({
|
||||
type: EntryActionTypes.WEBHOOK_UPDATE,
|
||||
payload: {
|
||||
id,
|
||||
data,
|
||||
},
|
||||
});
|
||||
|
||||
const handleWebhookUpdate = (webhook) => ({
|
||||
type: EntryActionTypes.WEBHOOK_UPDATE_HANDLE,
|
||||
payload: {
|
||||
webhook,
|
||||
},
|
||||
});
|
||||
|
||||
const deleteWebhook = (id) => ({
|
||||
type: EntryActionTypes.WEBHOOK_DELETE,
|
||||
payload: {
|
||||
id,
|
||||
},
|
||||
});
|
||||
|
||||
const handleWebhookDelete = (webhook) => ({
|
||||
type: EntryActionTypes.WEBHOOK_DELETE_HANDLE,
|
||||
payload: {
|
||||
webhook,
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
createWebhook,
|
||||
handleWebhookCreate,
|
||||
updateWebhook,
|
||||
handleWebhookUpdate,
|
||||
deleteWebhook,
|
||||
handleWebhookDelete,
|
||||
};
|
|
@ -21,6 +21,7 @@ export default {
|
|||
translation: {
|
||||
common: {
|
||||
aboutPlanka: 'About PLANKA',
|
||||
accessToken: 'Access token',
|
||||
account: 'Account',
|
||||
actions: 'Actions',
|
||||
activateUser_title: 'Activate User',
|
||||
|
@ -69,6 +70,7 @@ export default {
|
|||
areYouSureYouWantToDeleteThisTask: 'Are you sure you want to delete this task?',
|
||||
areYouSureYouWantToDeleteThisTaskList: 'Are you sure you want to delete this task list?',
|
||||
areYouSureYouWantToDeleteThisUser: 'Are you sure you want to delete this user?',
|
||||
areYouSureYouWantToDeleteThisWebhook: 'Are you sure you want to delete this webhook?',
|
||||
areYouSureYouWantToEmptyTrash: 'Are you sure you want to empty the trash?',
|
||||
areYouSureYouWantToLeaveBoard: 'Are you sure you want to leave the board?',
|
||||
areYouSureYouWantToLeaveProject: 'Are you sure you want to leave the project?',
|
||||
|
@ -152,6 +154,7 @@ export default {
|
|||
deleteTask_title: 'Delete Task',
|
||||
deleteUser_title: 'Delete User',
|
||||
deletedUser_title: 'Deleted User',
|
||||
deleteWebhook_title: 'Delete Webhook',
|
||||
description: 'Description',
|
||||
detectAutomatically: 'Detect automatically',
|
||||
display: 'Display',
|
||||
|
@ -182,6 +185,8 @@ export default {
|
|||
enterFilename: 'Enter filename',
|
||||
enterListTitle: 'Enter list title...',
|
||||
enterTaskDescription: 'Enter task description...',
|
||||
events: 'Events',
|
||||
excludedEvents: 'Excluded events',
|
||||
filterByLabels_title: 'Filter By Labels',
|
||||
filterByMembers_title: 'Filter By Members',
|
||||
forPersonalProjects: 'For personal projects.',
|
||||
|
@ -286,6 +291,7 @@ export default {
|
|||
typeTitleToConfirm: 'Type the title to confirm.',
|
||||
unsavedChanges: 'Unsaved changes',
|
||||
uploadedImages: 'Uploaded images',
|
||||
url: 'URL',
|
||||
userActions_title: 'User Actions',
|
||||
userAddedCardToList: '<0>{{user}}</0> added <2>{{card}}</2> to {{list}}',
|
||||
userAddedThisCardToList: '<0>{{user}}</0> added this card to {{list}}',
|
||||
|
@ -313,6 +319,7 @@ export default {
|
|||
userRemovedUserFromThisCard: '<0>{{actorUser}}</0> removed {{removedUser}} from this card',
|
||||
username: 'Username',
|
||||
users: 'Users',
|
||||
webhooks: 'Webhooks',
|
||||
viewer: 'Viewer',
|
||||
viewers: 'Viewers',
|
||||
visualTaskManagementWithLists: 'Visual task management with lists.',
|
||||
|
@ -338,6 +345,7 @@ export default {
|
|||
addTaskList: 'Add task list',
|
||||
addToCard: 'Add to card',
|
||||
addUser: 'Add user',
|
||||
addWebhook: 'Add webhook',
|
||||
archive: 'Archive',
|
||||
archiveCard: 'Archive card',
|
||||
archiveCard_title: 'Archive Card',
|
||||
|
@ -378,6 +386,7 @@ export default {
|
|||
deleteTask_title: 'Delete Task',
|
||||
deleteUser: 'Delete user',
|
||||
deleteUser_title: 'Delete User',
|
||||
deleteWebhook: 'Delete webhook',
|
||||
dismissAll: 'Dismiss all',
|
||||
duplicate: 'Duplicate',
|
||||
duplicateCard_title: 'Duplicate Card',
|
||||
|
|
|
@ -16,6 +16,7 @@ export default {
|
|||
translation: {
|
||||
common: {
|
||||
aboutPlanka: 'About PLANKA',
|
||||
accessToken: 'Access token',
|
||||
account: 'Account',
|
||||
actions: 'Actions',
|
||||
activateUser_title: 'Activate User',
|
||||
|
@ -64,6 +65,7 @@ export default {
|
|||
areYouSureYouWantToDeleteThisTask: 'Are you sure you want to delete this task?',
|
||||
areYouSureYouWantToDeleteThisTaskList: 'Are you sure you want to delete this task list?',
|
||||
areYouSureYouWantToDeleteThisUser: 'Are you sure you want to delete this user?',
|
||||
areYouSureYouWantToDeleteThisWebhook: 'Are you sure you want to delete this webhook?',
|
||||
areYouSureYouWantToEmptyTrash: 'Are you sure you want to empty the trash?',
|
||||
areYouSureYouWantToLeaveBoard: 'Are you sure you want to leave the board?',
|
||||
areYouSureYouWantToLeaveProject: 'Are you sure you want to leave the project?',
|
||||
|
@ -147,6 +149,7 @@ export default {
|
|||
deleteTask_title: 'Delete Task',
|
||||
deleteUser_title: 'Delete User',
|
||||
deletedUser_title: 'Deleted User',
|
||||
deleteWebhook_title: 'Delete Webhook',
|
||||
description: 'Description',
|
||||
detectAutomatically: 'Detect automatically',
|
||||
display: 'Display',
|
||||
|
@ -177,6 +180,8 @@ export default {
|
|||
enterFilename: 'Enter filename',
|
||||
enterListTitle: 'Enter list title...',
|
||||
enterTaskDescription: 'Enter task description...',
|
||||
events: 'Events',
|
||||
excludedEvents: 'Excluded events',
|
||||
filterByLabels_title: 'Filter By Labels',
|
||||
filterByMembers_title: 'Filter By Members',
|
||||
forPersonalProjects: 'For personal projects.',
|
||||
|
@ -281,6 +286,7 @@ export default {
|
|||
typeTitleToConfirm: 'Type the title to confirm.',
|
||||
unsavedChanges: 'Unsaved changes',
|
||||
uploadedImages: 'Uploaded images',
|
||||
url: 'URL',
|
||||
userActions_title: 'User Actions',
|
||||
userAddedCardToList: '<0>{{user}}</0> added <2>{{card}}</2> to {{list}}',
|
||||
userAddedThisCardToList: '<0>{{user}}</0> added this card to {{list}}',
|
||||
|
@ -308,6 +314,7 @@ export default {
|
|||
userRemovedUserFromThisCard: '<0>{{actorUser}}</0> removed {{removedUser}} from this card',
|
||||
username: 'Username',
|
||||
users: 'Users',
|
||||
webhooks: 'Webhooks',
|
||||
viewer: 'Viewer',
|
||||
viewers: 'Viewers',
|
||||
visualTaskManagementWithLists: 'Visual task management with lists.',
|
||||
|
@ -333,6 +340,7 @@ export default {
|
|||
addTaskList: 'Add task list',
|
||||
addToCard: 'Add to card',
|
||||
addUser: 'Add user',
|
||||
addWebhook: 'Add webhook',
|
||||
archive: 'Archive',
|
||||
archiveCard: 'Archive card',
|
||||
archiveCard_title: 'Archive Card',
|
||||
|
@ -373,6 +381,7 @@ export default {
|
|||
deleteTask_title: 'Delete Task',
|
||||
deleteUser: 'Delete user',
|
||||
deleteUser_title: 'Delete User',
|
||||
deleteWebhook: 'Delete webhook',
|
||||
dismissAll: 'Dismiss all',
|
||||
duplicate: 'Duplicate',
|
||||
duplicateCard_title: 'Duplicate Card',
|
||||
|
|
88
client/src/models/Webhook.js
Normal file
88
client/src/models/Webhook.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import { attr, fk } from 'redux-orm';
|
||||
|
||||
import BaseModel from './BaseModel';
|
||||
import ActionTypes from '../constants/ActionTypes';
|
||||
|
||||
export default class extends BaseModel {
|
||||
static modelName = 'Webhook';
|
||||
|
||||
static fields = {
|
||||
id: attr(),
|
||||
name: attr(),
|
||||
url: attr(),
|
||||
accessToken: attr(),
|
||||
events: attr(),
|
||||
excludedEvents: attr(),
|
||||
boardId: fk({
|
||||
to: 'Board',
|
||||
as: 'board',
|
||||
relatedName: 'webhooks',
|
||||
}),
|
||||
};
|
||||
|
||||
static reducer({ type, payload }, Webhook) {
|
||||
switch (type) {
|
||||
case ActionTypes.SOCKET_RECONNECT_HANDLE:
|
||||
Webhook.all().delete();
|
||||
|
||||
payload.webhooks.forEach((webhook) => {
|
||||
Webhook.upsert(webhook);
|
||||
});
|
||||
|
||||
break;
|
||||
case ActionTypes.CORE_INITIALIZE:
|
||||
case ActionTypes.USER_UPDATE_HANDLE:
|
||||
if (payload.webhooks) {
|
||||
payload.webhooks.forEach((webhook) => {
|
||||
Webhook.upsert(webhook);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case ActionTypes.WEBHOOK_CREATE:
|
||||
case ActionTypes.WEBHOOK_CREATE_HANDLE:
|
||||
case ActionTypes.WEBHOOK_UPDATE__SUCCESS:
|
||||
case ActionTypes.WEBHOOK_UPDATE_HANDLE:
|
||||
Webhook.upsert(payload.webhook);
|
||||
|
||||
break;
|
||||
case ActionTypes.WEBHOOK_CREATE__SUCCESS:
|
||||
Webhook.withId(payload.localId).delete();
|
||||
Webhook.upsert(payload.webhook);
|
||||
|
||||
break;
|
||||
case ActionTypes.WEBHOOK_CREATE__FAILURE:
|
||||
Webhook.withId(payload.localId).delete();
|
||||
|
||||
break;
|
||||
case ActionTypes.WEBHOOK_UPDATE:
|
||||
Webhook.withId(payload.id).update(payload.data);
|
||||
|
||||
break;
|
||||
case ActionTypes.WEBHOOK_DELETE:
|
||||
Webhook.withId(payload.id).delete();
|
||||
|
||||
break;
|
||||
case ActionTypes.WEBHOOK_DELETE__SUCCESS:
|
||||
case ActionTypes.WEBHOOK_DELETE_HANDLE: {
|
||||
const webhookModel = Webhook.withId(payload.webhook.id);
|
||||
|
||||
if (webhookModel) {
|
||||
webhookModel.delete();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
static getAllQuerySet() {
|
||||
return this.orderBy(['id.length', 'id']);
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import Webhook from './Webhook';
|
||||
import User from './User';
|
||||
import Project from './Project';
|
||||
import ProjectManager from './ProjectManager';
|
||||
|
@ -25,6 +26,7 @@ import Notification from './Notification';
|
|||
import NotificationService from './NotificationService';
|
||||
|
||||
export {
|
||||
Webhook,
|
||||
User,
|
||||
Project,
|
||||
ProjectManager,
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
Task,
|
||||
TaskList,
|
||||
User,
|
||||
Webhook,
|
||||
} from './models';
|
||||
|
||||
const orm = new ORM({
|
||||
|
@ -33,6 +34,7 @@ const orm = new ORM({
|
|||
});
|
||||
|
||||
orm.register(
|
||||
Webhook,
|
||||
User,
|
||||
Project,
|
||||
ProjectManager,
|
||||
|
|
|
@ -10,6 +10,7 @@ import request from '../request';
|
|||
import api from '../../../api';
|
||||
import mergeRecords from '../../../utils/merge-records';
|
||||
import { isUserAdminOrProjectOwner } from '../../../utils/record-helpers';
|
||||
import { UserRoles } from '../../../constants/Enums';
|
||||
|
||||
export function* fetchCore() {
|
||||
const {
|
||||
|
@ -17,6 +18,11 @@ export function* fetchCore() {
|
|||
included: { notificationServices: notificationServices1 },
|
||||
} = yield call(request, api.getCurrentUser, true);
|
||||
|
||||
let webhooks;
|
||||
if (user.role === UserRoles.ADMIN) {
|
||||
({ items: webhooks } = yield call(request, api.getWebhooks));
|
||||
}
|
||||
|
||||
let users1;
|
||||
if (isUserAdminOrProjectOwner(user)) {
|
||||
({ items: users1 } = yield call(request, api.getUsers));
|
||||
|
@ -101,6 +107,7 @@ export function* fetchCore() {
|
|||
return {
|
||||
user,
|
||||
board,
|
||||
webhooks,
|
||||
projectManagers,
|
||||
backgroundImages,
|
||||
baseCustomFieldGroups,
|
||||
|
|
|
@ -21,6 +21,7 @@ export function* initializeCore() {
|
|||
const {
|
||||
user,
|
||||
board,
|
||||
webhooks,
|
||||
users,
|
||||
projects,
|
||||
projectManagers,
|
||||
|
@ -50,6 +51,7 @@ export function* initializeCore() {
|
|||
actions.initializeCore(
|
||||
user,
|
||||
board,
|
||||
webhooks,
|
||||
users,
|
||||
projects,
|
||||
projectManagers,
|
||||
|
|
|
@ -7,6 +7,7 @@ import router from './router';
|
|||
import socket from './socket';
|
||||
import core from './core';
|
||||
import modals from './modals';
|
||||
import webhooks from './webhooks';
|
||||
import users from './users';
|
||||
import projects from './projects';
|
||||
import projectManagers from './project-managers';
|
||||
|
@ -33,6 +34,7 @@ export default {
|
|||
...socket,
|
||||
...core,
|
||||
...modals,
|
||||
...webhooks,
|
||||
...users,
|
||||
...projects,
|
||||
...projectManagers,
|
||||
|
|
|
@ -24,6 +24,7 @@ export function* handleSocketReconnect() {
|
|||
let config;
|
||||
let user;
|
||||
let board;
|
||||
let webhooks;
|
||||
let users;
|
||||
let projects;
|
||||
let projectManagers;
|
||||
|
@ -51,6 +52,7 @@ export function* handleSocketReconnect() {
|
|||
({
|
||||
user,
|
||||
board,
|
||||
webhooks,
|
||||
users,
|
||||
projects,
|
||||
projectManagers,
|
||||
|
@ -81,6 +83,7 @@ export function* handleSocketReconnect() {
|
|||
config,
|
||||
user,
|
||||
board,
|
||||
webhooks,
|
||||
users,
|
||||
projects,
|
||||
projectManagers,
|
||||
|
|
|
@ -70,6 +70,7 @@ export function* handleUserUpdate(user) {
|
|||
|
||||
let config;
|
||||
let board;
|
||||
let webhooks;
|
||||
let users1;
|
||||
let users2;
|
||||
let users3;
|
||||
|
@ -102,6 +103,7 @@ export function* handleUserUpdate(user) {
|
|||
|
||||
if (user.role === UserRoles.ADMIN) {
|
||||
({ item: config } = yield call(request, api.getConfig));
|
||||
({ items: webhooks } = yield call(request, api.getWebhooks));
|
||||
|
||||
({
|
||||
items: projects,
|
||||
|
@ -164,6 +166,7 @@ export function* handleUserUpdate(user) {
|
|||
boardIds,
|
||||
config,
|
||||
board,
|
||||
webhooks,
|
||||
mergeRecords(users1, users2, users3),
|
||||
projects,
|
||||
projectManagers,
|
||||
|
|
89
client/src/sagas/core/services/webhooks.js
Normal file
89
client/src/sagas/core/services/webhooks.js
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import { call, put } from 'redux-saga/effects';
|
||||
|
||||
import request from '../request';
|
||||
import actions from '../../../actions';
|
||||
import api from '../../../api';
|
||||
import { createLocalId } from '../../../utils/local-id';
|
||||
|
||||
export function* createWebhook(data) {
|
||||
const localId = yield call(createLocalId);
|
||||
|
||||
yield put(
|
||||
actions.createWebhook({
|
||||
...data,
|
||||
id: localId,
|
||||
}),
|
||||
);
|
||||
|
||||
let webhook;
|
||||
try {
|
||||
({ item: webhook } = yield call(request, api.createWebhook, {
|
||||
...data,
|
||||
events: data.events && data.events.join(','),
|
||||
excludedEvents: data.excludedEvents && data.excludedEvents.join(','),
|
||||
}));
|
||||
} catch (error) {
|
||||
yield put(actions.createWebhook.failure(localId, error));
|
||||
return;
|
||||
}
|
||||
|
||||
yield put(actions.createWebhook.success(localId, webhook));
|
||||
}
|
||||
|
||||
export function* handleWebhookCreate(webhook) {
|
||||
yield put(actions.handleWebhookCreate(webhook));
|
||||
}
|
||||
|
||||
export function* updateWebhook(id, data) {
|
||||
yield put(actions.updateWebhook(id, data));
|
||||
|
||||
let webhook;
|
||||
try {
|
||||
({ item: webhook } = yield call(request, api.updateWebhook, id, {
|
||||
...data,
|
||||
events: data.events && data.events.join(','),
|
||||
excludedEvents: data.excludedEvents && data.excludedEvents.join(','),
|
||||
}));
|
||||
} catch (error) {
|
||||
yield put(actions.updateWebhook.failure(id, error));
|
||||
return;
|
||||
}
|
||||
|
||||
yield put(actions.updateWebhook.success(webhook));
|
||||
}
|
||||
|
||||
export function* handleWebhookUpdate(webhook) {
|
||||
yield put(actions.handleWebhookUpdate(webhook));
|
||||
}
|
||||
|
||||
export function* deleteWebhook(id) {
|
||||
yield put(actions.deleteWebhook(id));
|
||||
|
||||
let webhook;
|
||||
try {
|
||||
({ item: webhook } = yield call(request, api.deleteWebhook, id));
|
||||
} catch (error) {
|
||||
yield put(actions.deleteWebhook.failure(id, error));
|
||||
return;
|
||||
}
|
||||
|
||||
yield put(actions.deleteWebhook.success(webhook));
|
||||
}
|
||||
|
||||
export function* handleWebhookDelete(webhook) {
|
||||
yield put(actions.handleWebhookDelete(webhook));
|
||||
}
|
||||
|
||||
export default {
|
||||
createWebhook,
|
||||
handleWebhookCreate,
|
||||
updateWebhook,
|
||||
handleWebhookUpdate,
|
||||
deleteWebhook,
|
||||
handleWebhookDelete,
|
||||
};
|
|
@ -7,6 +7,7 @@ import router from './router';
|
|||
import socket from './socket';
|
||||
import core from './core';
|
||||
import modals from './modals';
|
||||
import webhooks from './webhooks';
|
||||
import users from './users';
|
||||
import projects from './projects';
|
||||
import projectManagers from './project-managers';
|
||||
|
@ -33,6 +34,7 @@ export default [
|
|||
socket,
|
||||
core,
|
||||
modals,
|
||||
webhooks,
|
||||
users,
|
||||
projects,
|
||||
projectManagers,
|
||||
|
|
30
client/src/sagas/core/watchers/webhooks.js
Normal file
30
client/src/sagas/core/watchers/webhooks.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import { all, takeEvery } from 'redux-saga/effects';
|
||||
|
||||
import services from '../services';
|
||||
import EntryActionTypes from '../../../constants/EntryActionTypes';
|
||||
|
||||
export default function* webhooksWatchers() {
|
||||
yield all([
|
||||
takeEvery(EntryActionTypes.WEBHOOK_CREATE, ({ payload: { data } }) =>
|
||||
services.createWebhook(data),
|
||||
),
|
||||
takeEvery(EntryActionTypes.WEBHOOK_CREATE_HANDLE, ({ payload: { webhook } }) =>
|
||||
services.handleWebhookCreate(webhook),
|
||||
),
|
||||
takeEvery(EntryActionTypes.WEBHOOK_UPDATE, ({ payload: { id, data } }) =>
|
||||
services.updateWebhook(id, data),
|
||||
),
|
||||
takeEvery(EntryActionTypes.WEBHOOK_UPDATE_HANDLE, ({ payload: { webhook } }) =>
|
||||
services.handleWebhookUpdate(webhook),
|
||||
),
|
||||
takeEvery(EntryActionTypes.WEBHOOK_DELETE, ({ payload: { id } }) => services.deleteWebhook(id)),
|
||||
takeEvery(EntryActionTypes.WEBHOOK_DELETE_HANDLE, ({ payload: { webhook } }) =>
|
||||
services.handleWebhookDelete(webhook),
|
||||
),
|
||||
]);
|
||||
}
|
|
@ -8,6 +8,7 @@ import common from './common';
|
|||
import core from './core';
|
||||
import modals from './modals';
|
||||
import positioning from './positioning';
|
||||
import webhooks from './webhooks';
|
||||
import users from './users';
|
||||
import projects from './projects';
|
||||
import projectManagers from './project-managers';
|
||||
|
@ -35,6 +36,7 @@ export default {
|
|||
...core,
|
||||
...modals,
|
||||
...positioning,
|
||||
...webhooks,
|
||||
...users,
|
||||
...projects,
|
||||
...projectManagers,
|
||||
|
|
41
client/src/selectors/webhooks.js
Normal file
41
client/src/selectors/webhooks.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
import { createSelector } from 'redux-orm';
|
||||
|
||||
import orm from '../orm';
|
||||
import { isLocalId } from '../utils/local-id';
|
||||
|
||||
export const makeSelectWebhookById = () =>
|
||||
createSelector(
|
||||
orm,
|
||||
(_, id) => id,
|
||||
({ Webhook }, id) => {
|
||||
const webhookModel = Webhook.withId(id);
|
||||
|
||||
if (!webhookModel) {
|
||||
return webhookModel;
|
||||
}
|
||||
|
||||
return {
|
||||
...webhookModel.ref,
|
||||
isPersisted: !isLocalId(webhookModel.id),
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
export const selectWebhookById = makeSelectWebhookById();
|
||||
|
||||
export const selectWebhookIds = createSelector(orm, ({ Webhook }) =>
|
||||
Webhook.getAllQuerySet()
|
||||
.toRefArray()
|
||||
.map((webhook) => webhook.id),
|
||||
);
|
||||
|
||||
export default {
|
||||
makeSelectWebhookById,
|
||||
selectWebhookById,
|
||||
selectWebhookIds,
|
||||
};
|
|
@ -80,15 +80,6 @@ services:
|
|||
# - SMTP_PASSWORD=
|
||||
# - SMTP_FROM="Demo Demo" <demo@demo.demo>
|
||||
# - SMTP_TLS_REJECT_UNAUTHORIZED=false
|
||||
|
||||
# Optional fields: accessToken, events, excludedEvents
|
||||
# - |
|
||||
# WEBHOOKS=[{
|
||||
# "url": "http://localhost:3001",
|
||||
# "accessToken": "notaccesstoken",
|
||||
# "events": ["cardCreate", "cardUpdate", "cardDelete"],
|
||||
# "excludedEvents": ["notificationCreate", "notificationUpdate"]
|
||||
# }]
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
|
|
|
@ -100,15 +100,6 @@ services:
|
|||
# - SMTP_PASSWORD__FILE=/run/secrets/smtp_password
|
||||
# - SMTP_FROM="Demo Demo" <demo@demo.demo>
|
||||
# - SMTP_TLS_REJECT_UNAUTHORIZED=false
|
||||
|
||||
# Optional fields: accessToken, events, excludedEvents
|
||||
# - |
|
||||
# WEBHOOKS=[{
|
||||
# "url": "http://localhost:3001",
|
||||
# "accessToken": "notaccesstoken",
|
||||
# "events": ["cardCreate", "cardUpdate", "cardDelete"],
|
||||
# "excludedEvents": ["notificationCreate", "notificationUpdate"]
|
||||
# }]
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
|
|
|
@ -72,14 +72,6 @@ SECRET_KEY=notsecretkey
|
|||
# SMTP_FROM="Demo Demo" <demo@demo.demo>
|
||||
# SMTP_TLS_REJECT_UNAUTHORIZED=false
|
||||
|
||||
# Optional fields: accessToken, events, excludedEvents
|
||||
# WEBHOOKS='[{
|
||||
# "url": "http://localhost:3001",
|
||||
# "accessToken": "notaccesstoken",
|
||||
# "events": ["cardCreate", "cardUpdate", "cardDelete"],
|
||||
# "excludedEvents": ["notificationCreate", "notificationUpdate"]
|
||||
# }]'
|
||||
|
||||
## Do not edit this
|
||||
|
||||
TZ=UTC
|
||||
|
|
76
server/api/controllers/webhooks/create.js
Normal file
76
server/api/controllers/webhooks/create.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
const { isUrl } = require('../../../utils/validators');
|
||||
|
||||
const Errors = {
|
||||
LIMIT_REACHED: {
|
||||
limitReached: 'Limit reached',
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
inputs: {
|
||||
name: {
|
||||
type: 'string',
|
||||
maxLength: 128,
|
||||
required: true,
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
maxLength: 2048,
|
||||
custom: isUrl,
|
||||
required: true,
|
||||
},
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
isNotEmptyString: true,
|
||||
maxLength: 512,
|
||||
allowNull: true,
|
||||
},
|
||||
events: {
|
||||
type: 'string',
|
||||
isNotEmptyString: true,
|
||||
maxLength: 2048,
|
||||
allowNull: true,
|
||||
},
|
||||
excludedEvents: {
|
||||
type: 'string',
|
||||
isNotEmptyString: true,
|
||||
maxLength: 2048,
|
||||
allowNull: true,
|
||||
},
|
||||
},
|
||||
|
||||
exits: {
|
||||
limitReached: {
|
||||
responseType: 'conflict',
|
||||
},
|
||||
},
|
||||
|
||||
async fn(inputs) {
|
||||
const { currentUser } = this.req;
|
||||
|
||||
const values = _.pick(inputs, ['name', 'url', 'accessToken']);
|
||||
const events = inputs.events && inputs.events.split(',');
|
||||
const excludedEvents = inputs.excludedEvents && inputs.excludedEvents.split(',');
|
||||
|
||||
const webhook = await sails.helpers.webhooks.createOne
|
||||
.with({
|
||||
values: {
|
||||
...values,
|
||||
events,
|
||||
excludedEvents,
|
||||
},
|
||||
actorUser: currentUser,
|
||||
request: this.req,
|
||||
})
|
||||
.intercept('limitReached', () => Errors.LIMIT_REACHED);
|
||||
|
||||
return {
|
||||
item: webhook,
|
||||
};
|
||||
},
|
||||
};
|
51
server/api/controllers/webhooks/delete.js
Normal file
51
server/api/controllers/webhooks/delete.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
const { idInput } = require('../../../utils/inputs');
|
||||
|
||||
const Errors = {
|
||||
WEBHOOK_NOT_FOUND: {
|
||||
webhookNotFound: 'Webhook not found',
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
inputs: {
|
||||
id: {
|
||||
...idInput,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
exits: {
|
||||
webhookNotFound: {
|
||||
responseType: 'notFound',
|
||||
},
|
||||
},
|
||||
|
||||
async fn(inputs) {
|
||||
const { currentUser } = this.req;
|
||||
|
||||
let webhook = await Webhook.qm.getOneById(inputs.id);
|
||||
|
||||
if (!webhook) {
|
||||
throw Errors.WEBHOOK_NOT_FOUND;
|
||||
}
|
||||
|
||||
webhook = await sails.helpers.webhooks.deleteOne.with({
|
||||
record: webhook,
|
||||
actorUser: currentUser,
|
||||
request: this.req,
|
||||
});
|
||||
|
||||
if (!webhook) {
|
||||
throw Errors.WEBHOOK_NOT_FOUND;
|
||||
}
|
||||
|
||||
return {
|
||||
item: webhook,
|
||||
};
|
||||
},
|
||||
};
|
14
server/api/controllers/webhooks/index.js
Normal file
14
server/api/controllers/webhooks/index.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
async fn() {
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
return {
|
||||
items: webhooks,
|
||||
};
|
||||
},
|
||||
};
|
89
server/api/controllers/webhooks/update.js
Normal file
89
server/api/controllers/webhooks/update.js
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*!
|
||||
* Copyright (c) 2024 PLANKA Software GmbH
|
||||
* Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md
|
||||
*/
|
||||
|
||||
const { isUrl } = require('../../../utils/validators');
|
||||
const { idInput } = require('../../../utils/inputs');
|
||||
|
||||
const Errors = {
|
||||
WEBHOOK_NOT_FOUND: {
|
||||
webhookNotFound: 'Webhook not found',
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
inputs: {
|
||||
id: {
|
||||
...idInput,
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
type: 'string',
|
||||
isNotEmptyString: true,
|
||||
maxLength: 128,
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
maxLength: 2048,
|
||||
custom: isUrl,
|
||||
},
|
||||
accessToken: {
|
||||
type: 'string',
|
||||
isNotEmptyString: true,
|
||||
maxLength: 512,
|
||||
allowNull: true,
|
||||
},
|
||||
events: {
|
||||
type: 'string',
|
||||
isNotEmptyString: true,
|
||||
maxLength: 2048,
|
||||
allowNull: true,
|
||||
},
|
||||
excludedEvents: {
|
||||
type: 'string',
|
||||
isNotEmptyString: true,
|
||||
maxLength: 2048,
|
||||
allowNull: true,
|
||||
},
|
||||
},
|
||||
|
||||
exits: {
|
||||
webhookNotFound: {
|
||||
responseType: 'notFound',
|
||||
},
|
||||
},
|
||||
|
||||
async fn(inputs) {
|
||||
const { currentUser } = this.req;
|
||||
|
||||
let webhook = await Webhook.qm.getOneById(inputs.id);
|
||||
|
||||
if (!webhook) {
|
||||
throw Errors.WEBHOOK_NOT_FOUND;
|
||||
}
|
||||
|
||||
const values = _.pick(inputs, ['name', 'url', 'accessToken']);
|
||||
const events = inputs.events && inputs.events.split(',');
|
||||
const excludedEvents = inputs.excludedEvents && inputs.excludedEvents.split(',');
|
||||
|
||||
webhook = await sails.helpers.webhooks.updateOne.with({
|
||||
record: webhook,
|
||||
values: {
|
||||
...values,
|
||||
events,
|
||||
excludedEvents,
|
||||
},
|
||||
actorUser: currentUser,
|
||||
request: this.req,
|
||||
});
|
||||
|
||||
if (!webhook) {
|
||||
throw Errors.WEBHOOK_NOT_FOUND;
|
||||
}
|
||||
|
||||
return {
|
||||
item: webhook,
|
||||
};
|
||||
},
|
||||
};
|
|
@ -105,6 +105,10 @@ module.exports = {
|
|||
type: 'ref',
|
||||
required: true,
|
||||
},
|
||||
webhooks: {
|
||||
type: 'ref',
|
||||
required: true,
|
||||
},
|
||||
request: {
|
||||
type: 'ref',
|
||||
},
|
||||
|
@ -130,7 +134,8 @@ module.exports = {
|
|||
);
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'actionCreate',
|
||||
webhooks: inputs.webhooks,
|
||||
event: Webhook.Events.ACTION_CREATE,
|
||||
buildData: () => ({
|
||||
item: action,
|
||||
included: {
|
||||
|
@ -158,6 +163,7 @@ module.exports = {
|
|||
project: inputs.project,
|
||||
board: inputs.board,
|
||||
list: inputs.list,
|
||||
webhooks: inputs.webhooks,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
@ -187,6 +193,7 @@ module.exports = {
|
|||
project: inputs.project,
|
||||
board: inputs.board,
|
||||
list: inputs.list,
|
||||
webhooks: inputs.webhooks,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -48,8 +48,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'attachmentCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.ATTACHMENT_CREATE,
|
||||
buildData: () => ({
|
||||
item: sails.helpers.attachments.presentOne(attachment),
|
||||
included: {
|
||||
|
@ -65,6 +68,7 @@ module.exports = {
|
|||
if (!values.card.coverAttachmentId) {
|
||||
if (attachment.type === Attachment.Types.FILE && attachment.data.image) {
|
||||
await sails.helpers.cards.updateOne.with({
|
||||
webhooks,
|
||||
record: values.card,
|
||||
values: {
|
||||
coverAttachmentId: attachment.id,
|
||||
|
|
|
@ -37,6 +37,7 @@ module.exports = {
|
|||
async fn(inputs) {
|
||||
if (inputs.record.id === inputs.card.coverAttachmentId) {
|
||||
await sails.helpers.cards.updateOne.with({
|
||||
webhooks,
|
||||
record: inputs.card,
|
||||
values: {
|
||||
coverAttachmentId: null,
|
||||
|
@ -66,8 +67,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'attachmentDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.ATTACHMENT_DELETE,
|
||||
buildData: () => ({
|
||||
item: sails.helpers.attachments.presentOne(attachment),
|
||||
included: {
|
||||
|
|
|
@ -53,8 +53,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'attachmentUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.ATTACHMENT_UPDATE,
|
||||
buildData: () => ({
|
||||
item: sails.helpers.attachments.presentOne(attachment),
|
||||
included: {
|
||||
|
|
|
@ -47,8 +47,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'backgroundImageCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.BACKGROUND_IMAGE_CREATE,
|
||||
buildData: () => ({
|
||||
item: sails.helpers.backgroundImages.presentOne(backgroundImage),
|
||||
included: {
|
||||
|
@ -60,6 +63,7 @@ module.exports = {
|
|||
|
||||
await sails.helpers.projects.updateOne.with({
|
||||
scoper,
|
||||
webhooks,
|
||||
record: values.project,
|
||||
values: {
|
||||
backgroundImage,
|
||||
|
|
|
@ -31,6 +31,7 @@ module.exports = {
|
|||
if (inputs.record.id === inputs.project.backgroundImageId) {
|
||||
await sails.helpers.projects.updateOne.with({
|
||||
scoper,
|
||||
webhooks,
|
||||
record: inputs.project,
|
||||
values: {
|
||||
backgroundType: null,
|
||||
|
@ -58,8 +59,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'backgroundImageDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.BACKGROUND_IMAGE_DELETE,
|
||||
buildData: () => ({
|
||||
item: sails.helpers.backgroundImages.presentOne(backgroundImage),
|
||||
included: {
|
||||
|
|
|
@ -43,8 +43,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'baseCustomFieldGroupCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.BASE_CUSTOM_FIELD_GROUP_CREATE,
|
||||
buildData: () => ({
|
||||
item: baseCustomFieldGroup,
|
||||
included: {
|
||||
|
|
|
@ -45,8 +45,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'baseCustomFieldGroupDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.BASE_CUSTOM_FIELD_GROUP_DELETE,
|
||||
buildData: () => ({
|
||||
item: baseCustomFieldGroup,
|
||||
included: {
|
||||
|
|
|
@ -49,8 +49,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'baseCustomFieldGroupUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.BASE_CUSTOM_FIELD_GROUP_UPDATE,
|
||||
buildData: () => ({
|
||||
item: baseCustomFieldGroup,
|
||||
included: {
|
||||
|
|
|
@ -86,8 +86,11 @@ module.exports = {
|
|||
});
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'boardMembershipCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.BOARD_MEMBERSHIP_CREATE,
|
||||
buildData: () => ({
|
||||
item: boardMembership,
|
||||
included: {
|
||||
|
|
|
@ -106,8 +106,11 @@ module.exports = {
|
|||
});
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'boardMembershipDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.BOARD_MEMBERSHIP_DELETE,
|
||||
buildData: () => ({
|
||||
item: boardMembership,
|
||||
included: {
|
||||
|
|
|
@ -75,8 +75,11 @@ module.exports = {
|
|||
});
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'boardMembershipUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.BOARD_MEMBERSHIP_UPDATE,
|
||||
buildData: () => ({
|
||||
item: boardMembership,
|
||||
included: {
|
||||
|
|
|
@ -108,8 +108,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'boardCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.BOARD_CREATE,
|
||||
buildData: () => ({
|
||||
item: board,
|
||||
included: {
|
||||
|
|
|
@ -49,8 +49,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'boardDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.BOARD_DELETE,
|
||||
buildData: () => ({
|
||||
item: board,
|
||||
included: {
|
||||
|
|
|
@ -104,8 +104,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'boardUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.BOARD_UPDATE,
|
||||
buildData: () => ({
|
||||
item: board,
|
||||
included: {
|
||||
|
|
|
@ -61,8 +61,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'cardLabelCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CARD_LABEL_CREATE,
|
||||
buildData: () => ({
|
||||
item: cardLabel,
|
||||
included: {
|
||||
|
|
|
@ -47,8 +47,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'cardLabelDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.CARD_LABEL_DELETE,
|
||||
buildData: () => ({
|
||||
item: cardLabel,
|
||||
included: {
|
||||
|
|
|
@ -61,8 +61,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'cardMembershipCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CARD_MEMBERSHIP_CREATE,
|
||||
buildData: () => ({
|
||||
item: cardMembership,
|
||||
included: {
|
||||
|
@ -106,6 +109,7 @@ module.exports = {
|
|||
}
|
||||
|
||||
await sails.helpers.actions.createOne.with({
|
||||
webhooks,
|
||||
values: {
|
||||
type: Action.Types.ADD_MEMBER_TO_CARD,
|
||||
data: {
|
||||
|
|
|
@ -51,8 +51,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'cardMembershipDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.CARD_MEMBERSHIP_DELETE,
|
||||
buildData: () => ({
|
||||
item: cardMembership,
|
||||
included: {
|
||||
|
@ -82,6 +85,7 @@ module.exports = {
|
|||
}
|
||||
|
||||
await sails.helpers.actions.createOne.with({
|
||||
webhooks,
|
||||
values: {
|
||||
type: Action.Types.REMOVE_MEMBER_FROM_CARD,
|
||||
data: {
|
||||
|
|
|
@ -84,8 +84,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'cardCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CARD_CREATE,
|
||||
buildData: () => ({
|
||||
item: card,
|
||||
included: {
|
||||
|
@ -120,6 +123,7 @@ module.exports = {
|
|||
}
|
||||
|
||||
await sails.helpers.actions.createOne.with({
|
||||
webhooks,
|
||||
values: {
|
||||
card,
|
||||
type: Action.Types.CREATE_CARD,
|
||||
|
|
|
@ -45,8 +45,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'cardDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.CARD_DELETE,
|
||||
buildData: () => ({
|
||||
item: card,
|
||||
included: {
|
||||
|
|
|
@ -228,8 +228,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'cardCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CARD_CREATE,
|
||||
buildData: () => ({
|
||||
item: card,
|
||||
included: {
|
||||
|
@ -272,6 +275,7 @@ module.exports = {
|
|||
}
|
||||
|
||||
await sails.helpers.actions.createOne.with({
|
||||
webhooks,
|
||||
values: {
|
||||
card,
|
||||
type: Action.Types.CREATE_CARD, // TODO: introduce separate type?
|
||||
|
|
|
@ -31,6 +31,8 @@ module.exports = {
|
|||
},
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
notifications.forEach((notification) => {
|
||||
sails.sockets.broadcast(
|
||||
`user:${notification.userId}`,
|
||||
|
@ -43,7 +45,8 @@ module.exports = {
|
|||
|
||||
// TODO: with prevData?
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'notificationUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.NOTIFICATION_UPDATE,
|
||||
buildData: () => ({
|
||||
item: notification,
|
||||
}),
|
||||
|
|
|
@ -31,6 +31,9 @@ module.exports = {
|
|||
type: 'ref',
|
||||
required: true,
|
||||
},
|
||||
webhooks: {
|
||||
type: 'ref',
|
||||
},
|
||||
request: {
|
||||
type: 'ref',
|
||||
},
|
||||
|
@ -104,6 +107,8 @@ module.exports = {
|
|||
if (_.isEmpty(values)) {
|
||||
card = inputs.record;
|
||||
} else {
|
||||
const { webhooks = await Webhook.qm.getAll() } = inputs;
|
||||
|
||||
if (!_.isNil(values.position)) {
|
||||
const cards = await Card.qm.getByListId(list.id, {
|
||||
exceptIdOrIds: inputs.record.id,
|
||||
|
@ -402,6 +407,7 @@ module.exports = {
|
|||
|
||||
const { id } = await sails.helpers.labels.createOne.with({
|
||||
project,
|
||||
webhooks,
|
||||
values: {
|
||||
..._.omit(label, ['id', 'boardId', 'createdAt', 'updatedAt']),
|
||||
board,
|
||||
|
@ -459,6 +465,7 @@ module.exports = {
|
|||
|
||||
if (values.list) {
|
||||
await sails.helpers.actions.createOne.with({
|
||||
webhooks,
|
||||
values: {
|
||||
card,
|
||||
type: Action.Types.MOVE_CARD,
|
||||
|
@ -477,7 +484,8 @@ module.exports = {
|
|||
}
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'cardUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CARD_UPDATE,
|
||||
buildData: () => ({
|
||||
item: card,
|
||||
included: {
|
||||
|
|
|
@ -79,8 +79,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'commentCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.COMMENT_CREATE,
|
||||
buildData: () => ({
|
||||
item: comment,
|
||||
included: {
|
||||
|
@ -125,6 +128,7 @@ module.exports = {
|
|||
await Promise.all(
|
||||
notifiableUserIds.map((userId) =>
|
||||
sails.helpers.notifications.createOne.with({
|
||||
webhooks,
|
||||
values: {
|
||||
userId,
|
||||
comment,
|
||||
|
|
|
@ -47,8 +47,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'commentDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.COMMENT_DELETE,
|
||||
buildData: () => ({
|
||||
item: comment,
|
||||
included: {
|
||||
|
|
|
@ -53,8 +53,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'commentUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.COMMENT_UPDATE,
|
||||
buildData: () => ({
|
||||
item: comment,
|
||||
included: {
|
||||
|
|
|
@ -87,8 +87,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldGroupCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_GROUP_CREATE,
|
||||
buildData: () => ({
|
||||
item: customFieldGroup,
|
||||
included: {
|
||||
|
|
|
@ -95,8 +95,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldGroupCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_GROUP_CREATE,
|
||||
buildData: () => ({
|
||||
item: customFieldGroup,
|
||||
included: {
|
||||
|
|
|
@ -41,8 +41,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldGroupDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_GROUP_DELETE,
|
||||
buildData: () => ({
|
||||
item: customFieldGroup,
|
||||
included: {
|
||||
|
|
|
@ -49,8 +49,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldGroupDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_GROUP_DELETE,
|
||||
buildData: () => ({
|
||||
item: customFieldGroup,
|
||||
included: {
|
||||
|
|
|
@ -91,8 +91,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldGroupUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_GROUP_UPDATE,
|
||||
buildData: () => ({
|
||||
item: customFieldGroup,
|
||||
included: {
|
||||
|
|
|
@ -99,8 +99,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldGroupUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_GROUP_UPDATE,
|
||||
buildData: () => ({
|
||||
item: customFieldGroup,
|
||||
included: {
|
||||
|
|
|
@ -49,9 +49,12 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
// TODO: with prevData?
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldValueUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_VALUE_UPDATE,
|
||||
buildData: () => ({
|
||||
item: customFieldValue,
|
||||
included: {
|
||||
|
|
|
@ -51,8 +51,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldValueDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_VALUE_DELETE,
|
||||
buildData: () => ({
|
||||
item: customFieldValue,
|
||||
included: {
|
||||
|
|
|
@ -93,8 +93,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_CREATE,
|
||||
buildData: () => ({
|
||||
item: customField,
|
||||
included: {
|
||||
|
|
|
@ -103,8 +103,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_CREATE,
|
||||
buildData: () => ({
|
||||
item: customField,
|
||||
included: {
|
||||
|
|
|
@ -49,8 +49,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_DELETE,
|
||||
buildData: () => ({
|
||||
item: customField,
|
||||
included: {
|
||||
|
|
|
@ -66,8 +66,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_DELETE,
|
||||
buildData: () => ({
|
||||
item: customField,
|
||||
included: {
|
||||
|
|
|
@ -94,8 +94,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_UPDATE,
|
||||
buildData: () => ({
|
||||
item: customField,
|
||||
included: {
|
||||
|
|
|
@ -109,8 +109,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'customFieldUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CUSTOM_FIELD_UPDATE,
|
||||
buildData: () => ({
|
||||
item: customField,
|
||||
included: {
|
||||
|
|
|
@ -17,6 +17,9 @@ module.exports = {
|
|||
type: 'ref',
|
||||
required: true,
|
||||
},
|
||||
webhooks: {
|
||||
type: 'ref',
|
||||
},
|
||||
request: {
|
||||
type: 'ref',
|
||||
},
|
||||
|
@ -70,8 +73,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const { webhooks = await Webhook.qm.getAll() } = inputs;
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'labelCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.LABEL_CREATE,
|
||||
buildData: () => ({
|
||||
item: label,
|
||||
included: {
|
||||
|
|
|
@ -41,8 +41,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'labelDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.LABEL_DELETE,
|
||||
buildData: () => ({
|
||||
item: label,
|
||||
included: {
|
||||
|
|
|
@ -81,8 +81,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'labelUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.LABEL_UPDATE,
|
||||
buildData: () => ({
|
||||
item: label,
|
||||
included: {
|
||||
|
|
|
@ -38,8 +38,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'listClear',
|
||||
webhooks,
|
||||
event: Webhook.Events.LIST_CLEAR,
|
||||
buildData: () => ({
|
||||
item: inputs.record,
|
||||
included: {
|
||||
|
|
|
@ -72,8 +72,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'listCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.LIST_CREATE,
|
||||
buildData: () => ({
|
||||
item: list,
|
||||
included: {
|
||||
|
|
|
@ -57,8 +57,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'listDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.LIST_DELETE,
|
||||
buildData: () => ({
|
||||
item: list,
|
||||
included: {
|
||||
|
|
|
@ -91,10 +91,13 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
cards.forEach((card) => {
|
||||
// TODO: with prevData?
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'cardUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CARD_UPDATE,
|
||||
buildData: () => ({
|
||||
item: card,
|
||||
included: {
|
||||
|
|
|
@ -100,10 +100,13 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
cards.forEach((card) => {
|
||||
// TODO: with prevData?
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'cardUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.CARD_UPDATE,
|
||||
buildData: () => ({
|
||||
item: card,
|
||||
included: {
|
||||
|
|
|
@ -84,8 +84,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'listUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.LIST_UPDATE,
|
||||
buildData: () => ({
|
||||
item: list,
|
||||
included: {
|
||||
|
|
|
@ -62,8 +62,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'notificationServiceCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.NOTIFICATION_SERVICE_CREATE,
|
||||
buildData: () => ({
|
||||
item: notificationService,
|
||||
included: {
|
||||
|
|
|
@ -48,8 +48,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'notificationServiceCreate',
|
||||
webhooks,
|
||||
event: Webhook.Events.NOTIFICATION_SERVICE_CREATE,
|
||||
buildData: () => ({
|
||||
item: notificationService,
|
||||
included: {
|
||||
|
|
|
@ -49,8 +49,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'notificationServiceDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.NOTIFICATION_SERVICE_DELETE,
|
||||
buildData: () => ({
|
||||
item: notificationService,
|
||||
included: {
|
||||
|
|
|
@ -35,8 +35,11 @@ module.exports = {
|
|||
inputs.request,
|
||||
);
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'notificationServiceDelete',
|
||||
webhooks,
|
||||
event: Webhook.Events.NOTIFICATION_SERVICE_DELETE,
|
||||
buildData: () => ({
|
||||
item: notificationService,
|
||||
included: {
|
||||
|
|
|
@ -55,8 +55,11 @@ module.exports = {
|
|||
);
|
||||
});
|
||||
|
||||
const webhooks = await Webhook.qm.getAll();
|
||||
|
||||
sails.helpers.utils.sendWebhooks.with({
|
||||
event: 'notificationServiceUpdate',
|
||||
webhooks,
|
||||
event: Webhook.Events.NOTIFICATION_SERVICE_UPDATE,
|
||||
buildData: () => ({
|
||||
item: notificationService,
|
||||
included: {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue