finish removing integrations state

This commit is contained in:
nick-delirium 2024-09-18 10:57:15 +02:00
parent 5a011692f8
commit c94ca6fb88
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
16 changed files with 180 additions and 507 deletions

View file

@ -1,3 +1,4 @@
import { useStore } from "App/mstore";
import React from 'react';
import DocLink from 'Shared/DocLink/DocLink';
import AssistScript from './AssistScript';
@ -5,6 +6,7 @@ import AssistNpm from './AssistNpm';
import { Tabs, CodeBlock } from 'UI';
import { useState } from 'react';
import { connect } from 'react-redux';
import { observer } from 'mobx-react-lite'
const NPM = 'NPM';
const SCRIPT = 'SCRIPT';
@ -14,7 +16,10 @@ const TABS = [
];
const AssistDoc = (props) => {
const { projectKey } = props;
const { integrationsStore } = useStore();
const sites = props.sites ? props.sites.toJS() : []
const siteId = integrationsStore.integrations.siteId
const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
const [activeTab, setActiveTab] = useState(SCRIPT);
const renderActiveTab = () => {
@ -54,9 +59,8 @@ const AssistDoc = (props) => {
AssistDoc.displayName = 'AssistDoc';
export default connect((state) => {
const siteId = state.getIn(['integrations', 'siteId']);
const sites = state.getIn(['site', 'list']);
return {
projectKey: sites.find((site) => site.get('id') === siteId).get('projectKey'),
sites,
};
})(AssistDoc);
})(observer(AssistDoc));

View file

@ -1,77 +1,93 @@
import React from 'react';
import { connect } from 'react-redux';
import React, { useState, useEffect, useCallback } from 'react';
import { ACCESS_KEY_ID_LENGTH, SECRET_ACCESS_KEY_LENGTH } from 'Types/integrations/cloudwatchConfig';
import { edit } from 'Duck/integrations/actions';
import { observer } from 'mobx-react-lite';
import { useStore } from 'App/mstore';
import Select from 'Shared/Select';
import { withRequest } from 'HOCs';
import { integrationsService } from "App/services";
@connect(state => ({
config: state.getIn([ 'cloudwatch', 'instance' ])
}), { edit })
@withRequest({
dataName: "values",
initialData: [],
resetBeforeRequest: true,
requestName: "fetchLogGroups",
endpoint: '/integrations/cloudwatch/list_groups',
method: 'POST',
})
export default class LogGroupDropdown extends React.PureComponent {
constructor(props) {
super(props);
this.fetchLogGroups()
}
fetchLogGroups() {
const { config } = this.props;
if (config.region === "" ||
config.awsSecretAccessKey.length !== SECRET_ACCESS_KEY_LENGTH ||
config.awsAccessKeyId.length !== ACCESS_KEY_ID_LENGTH
) return;
this.props.fetchLogGroups({
region: config.region,
awsSecretAccessKey: config.awsSecretAccessKey,
awsAccessKeyId: config.awsAccessKeyId,
}).then(() => {
const { value, values, name } = this.props;
if (!values.includes(value) && values.length > 0) {
this.props.edit("cloudwatch", {
[ name ]: values[0],
});
}
});
}
componentDidUpdate(prevProps) {
const { config } = this.props;
if (prevProps.config.region !== config.region ||
prevProps.config.awsSecretAccessKey !== config.awsSecretAccessKey ||
prevProps.config.awsAccessKeyId !== config.awsAccessKeyId) {
this.fetchLogGroups();
const LogGroupDropdown = (props) => {
const { integrationsStore } = useStore();
const config = integrationsStore.cloudwatch.instance;
const edit = integrationsStore.cloudwatch.edit;
const {
value,
name,
placeholder,
onChange,
} = props;
const [values, setValues] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const { region, awsSecretAccessKey, awsAccessKeyId } = config;
const fetchLogGroups = useCallback(() => {
if (
region === '' ||
awsSecretAccessKey.length !== SECRET_ACCESS_KEY_LENGTH ||
awsAccessKeyId.length !== ACCESS_KEY_ID_LENGTH
) {
return;
}
}
onChange = (target) => {
if (typeof this.props.onChange === 'function') {
this.props.onChange({ target });
setLoading(true);
setError(false);
setValues([]); // Reset values before request
const params = {
region: region,
awsSecretAccessKey: awsSecretAccessKey,
awsAccessKeyId: awsAccessKeyId,
};
integrationsService.client
.post('/integrations/cloudwatch/list_groups', params)
.then((response) => response.json())
.then(({ errors, data }) => {
if (errors) {
setError(true);
setLoading(false);
return;
}
setValues(data);
setLoading(false);
// If current value is not in the new values list, update it
if (!data.includes(value) && data.length > 0) {
edit({
[name]: data[0],
});
}
})
.catch(() => {
setError(true);
setLoading(false);
});
}, [region, awsSecretAccessKey, awsAccessKeyId, value, name, edit]);
// Fetch log groups on mount and when config changes
useEffect(() => {
fetchLogGroups();
}, [fetchLogGroups]);
const handleChange = (target) => {
if (typeof onChange === 'function') {
onChange({ target });
}
}
render() {
const {
values,
name,
value,
placeholder,
loading,
} = this.props;
const options = values.map(g => ({ text: g, value: g }));
return (
<Select
// selection
options={ options }
name={ name }
value={ options.find(o => o.value === value) }
placeholder={ placeholder }
onChange={ this.onChange }
loading={ loading }
/>
);
}
}
};
const options = values.map((g) => ({ text: g, value: g }));
return (
<Select
options={options}
name={name}
value={options.find((o) => o.value === value)}
placeholder={placeholder}
onChange={handleChange}
loading={loading}
/>
);
};
export default observer(LogGroupDropdown);

View file

@ -1,11 +1,16 @@
import { useStore } from "App/mstore";
import React from 'react';
import { CodeBlock } from "UI";
import DocLink from 'Shared/DocLink/DocLink';
import ToggleContent from 'Shared/ToggleContent';
import { connect } from 'react-redux';
import { observer } from 'mobx-react-lite'
const GraphQLDoc = (props) => {
const { projectKey } = props;
const { integrationsStore } = useStore();
const sites = props.sites ? props.sites.toJS() : []
const siteId = integrationsStore.integrations.siteId
const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
const usage = `import OpenReplay from '@openreplay/tracker';
import trackerGraphQL from '@openreplay/tracker-graphql';
//...
@ -71,9 +76,8 @@ export const recordGraphQL = tracker.use(trackerGraphQL());`
GraphQLDoc.displayName = 'GraphQLDoc';
export default connect((state) => {
const siteId = state.getIn(['integrations', 'siteId']);
const sites = state.getIn(['site', 'list']);
return {
projectKey: sites.find((site) => site.get('id') === siteId).get('projectKey'),
sites,
};
})(GraphQLDoc);
})(observer(GraphQLDoc));

View file

@ -1,11 +1,16 @@
import { useStore } from "App/mstore";
import React from 'react';
import { CodeBlock } from "UI";
import ToggleContent from 'Shared/ToggleContent';
import DocLink from 'Shared/DocLink/DocLink';
import { connect } from 'react-redux';
import { observer } from 'mobx-react-lite'
const NgRxDoc = (props) => {
const { projectKey } = props;
const { integrationsStore } = useStore();
const sites = props.sites ? props.sites.toJS() : []
const siteId = integrationsStore.integrations.siteId
const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
const usage = `import { StoreModule } from '@ngrx/store';
import { reducers } from './reducers';
import OpenReplay from '@openreplay/tracker';
@ -81,9 +86,8 @@ const metaReducers = [tracker.use(trackerNgRx(<options>))]; // check list of ava
NgRxDoc.displayName = 'NgRxDoc';
export default connect((state) => {
const siteId = state.getIn(['integrations', 'siteId']);
const sites = state.getIn(['site', 'list']);
return {
projectKey: sites.find((site) => site.get('id') === siteId).get('projectKey'),
sites,
};
})(NgRxDoc);
})(observer(NgRxDoc));

View file

@ -1,11 +1,20 @@
import { observer } from 'mobx-react-lite';
import React from 'react';
import { CodeBlock } from "UI";
import ToggleContent from '../../../shared/ToggleContent';
import DocLink from 'Shared/DocLink/DocLink';
import { connect } from 'react-redux';
import { useStore } from 'App/mstore';
import ToggleContent from 'Components/shared/ToggleContent';
import { CodeBlock } from 'UI';
import DocLink from 'Shared/DocLink/DocLink';
const PiniaDoc = (props) => {
const { projectKey } = props;
const { integrationsStore } = useStore();
const sites = props.sites ? props.sites.toJS() : [];
const siteId = integrationsStore.integrations.siteId;
const projectKey = siteId
? sites.find((site) => site.id === siteId)?.projectKey
: sites[0]?.projectKey;
const usage = `import Vuex from 'vuex'
import OpenReplay from '@openreplay/tracker';
import trackerVuex from '@openreplay/tracker-vuex';
@ -28,7 +37,7 @@ piniaStorePlugin(examplePiniaStore)
// now you can use examplePiniaStore as
// usual pinia store
// (destructure values or return it as a whole etc)
`
`;
const usageCjs = `import Vuex from 'vuex'
import OpenReplay from '@openreplay/tracker/cjs';
import trackerVuex from '@openreplay/tracker-vuex/cjs';
@ -55,34 +64,38 @@ piniaStorePlugin(examplePiniaStore)
// now you can use examplePiniaStore as
// usual pinia store
// (destructure values or return it as a whole etc)
}`
}`;
return (
<div className="bg-white h-screen overflow-y-auto" style={{ width: '500px' }}>
<div
className="bg-white h-screen overflow-y-auto"
style={{ width: '500px' }}
>
<h3 className="p-5 text-2xl">VueX</h3>
<div className="p-5">
<div>
This plugin allows you to capture Pinia mutations + state and inspect them later on while
replaying session recordings. This is very useful for understanding and fixing issues.
This plugin allows you to capture Pinia mutations + state and inspect
them later on while replaying session recordings. This is very useful
for understanding and fixing issues.
</div>
<div className="font-bold my-2 text-lg">Installation</div>
<CodeBlock code={`npm i @openreplay/tracker-vuex --save`} language="bash" />
<CodeBlock
code={`npm i @openreplay/tracker-vuex --save`}
language="bash"
/>
<div className="font-bold my-2 text-lg">Usage</div>
<p>
Initialize the @openreplay/tracker package as usual and load the plugin into it. Then put
the generated plugin into your plugins field of your store.
Initialize the @openreplay/tracker package as usual and load the
plugin into it. Then put the generated plugin into your plugins field
of your store.
</p>
<div className="py-3" />
<ToggleContent
label="Server-Side-Rendered (SSR)?"
first={
<CodeBlock code={usage} language="js" />
}
second={
<CodeBlock code={usageCjs} language="js" />
}
first={<CodeBlock code={usage} language="js" />}
second={<CodeBlock code={usageCjs} language="js" />}
/>
<DocLink
@ -98,9 +111,8 @@ piniaStorePlugin(examplePiniaStore)
PiniaDoc.displayName = 'PiniaDoc';
export default connect((state: any) => {
const siteId = state.getIn(['integrations', 'siteId']);
const sites = state.getIn(['site', 'list']);
return {
projectKey: sites.find((site: any) => site.get('id') === siteId).get('projectKey'),
sites,
};
})(PiniaDoc);
})(observer(PiniaDoc));

View file

@ -1,13 +1,17 @@
import { useStore } from "App/mstore";
import React from 'react';
import { connect } from 'react-redux';
import { observer } from 'mobx-react-lite';
import { CodeBlock } from 'UI';
import DocLink from 'Shared/DocLink/DocLink';
import ToggleContent from 'Shared/ToggleContent';
const ProfilerDoc = (props) => {
const { projectKey } = props;
const { integrationsStore } = useStore();
const sites = props.sites ? props.sites.toJS() : []
const siteId = integrationsStore.integrations.siteId
const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
const usage = `import OpenReplay from '@openreplay/tracker';
import trackerProfiler from '@openreplay/tracker-profiler';
@ -88,11 +92,8 @@ const fn = profiler('call_name')(() => {
ProfilerDoc.displayName = 'ProfilerDoc';
export default connect((state) => {
const siteId = state.getIn(['integrations', 'siteId']);
const sites = state.getIn(['site', 'list']);
return {
projectKey: sites
.find((site) => site.get('id') === siteId)
.get('projectKey'),
sites
};
})(ProfilerDoc);
})(observer(ProfilerDoc));

View file

@ -1,11 +1,16 @@
import { useStore } from "App/mstore";
import React from 'react';
import { CodeBlock } from 'UI'
import ToggleContent from '../../../shared/ToggleContent';
import ToggleContent from 'Components/shared/ToggleContent';
import DocLink from 'Shared/DocLink/DocLink';
import { connect } from 'react-redux';
import { observer } from 'mobx-react-lite'
const ReduxDoc = (props) => {
const { projectKey } = props;
const { integrationsStore } = useStore();
const sites = props.sites ? props.sites.toJS() : []
const siteId = integrationsStore.integrations.siteId
const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
const usage = `import { applyMiddleware, createStore } from 'redux';
import OpenReplay from '@openreplay/tracker';
@ -75,9 +80,8 @@ const store = createStore(
ReduxDoc.displayName = 'ReduxDoc';
export default connect((state) => {
const siteId = state.getIn(['integrations', 'siteId']);
const sites = state.getIn(['site', 'list']);
return {
projectKey: sites.find((site) => site.get('id') === siteId).get('projectKey'),
sites
};
})(ReduxDoc);
})(observer(ReduxDoc));

View file

@ -1,11 +1,16 @@
import { useStore } from "App/mstore";
import React from 'react';
import { CodeBlock } from "UI";
import ToggleContent from '../../../shared/ToggleContent';
import ToggleContent from 'Components/shared/ToggleContent';
import DocLink from 'Shared/DocLink/DocLink';
import { connect } from 'react-redux';
import { observer } from 'mobx-react-lite';
const VueDoc = (props) => {
const { projectKey, siteId } = props;
const { integrationsStore } = useStore();
const sites = props.sites ? props.sites.toJS() : []
const siteId = integrationsStore.integrations.siteId
const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
const usage = `import Vuex from 'vuex'
import OpenReplay from '@openreplay/tracker';
@ -82,9 +87,8 @@ const store = new Vuex.Store({
VueDoc.displayName = 'VueDoc';
export default connect((state) => {
const siteId = state.getIn(['integrations', 'siteId']);
const sites = state.getIn(['site', 'list']);
return {
projectKey: sites.find((site) => site.get('id') === siteId).get('projectKey'),
sites,
};
})(VueDoc);
})(observer(VueDoc));

View file

@ -1,11 +1,16 @@
import { useStore } from "App/mstore";
import React from 'react';
import { CodeBlock } from "UI";
import ToggleContent from '../../../shared/ToggleContent';
import ToggleContent from 'Components//shared/ToggleContent';
import DocLink from 'Shared/DocLink/DocLink';
import { connect } from 'react-redux';
import { observer } from 'mobx-react-lite'
const ZustandDoc = (props) => {
const { projectKey } = props;
const { integrationsStore } = useStore();
const sites = props.sites ? props.sites.toJS() : []
const siteId = integrationsStore.integrations.siteId
const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
const usage = `import create from "zustand";
import Tracker from '@openreplay/tracker';
@ -98,9 +103,8 @@ const useBearStore = create(
ZustandDoc.displayName = 'ZustandDoc';
export default connect((state) => {
const siteId = state.getIn(['integrations', 'siteId']);
const sites = state.getIn(['site', 'list']);
return {
projectKey: sites.find((site) => site.get('id') === siteId).get('projectKey'),
sites,
};
})(ZustandDoc);
})(observer(ZustandDoc));

View file

@ -6,7 +6,6 @@ import sessions from './sessions';
import sources from './sources';
import site from './site';
import customFields from './customField';
import integrations from './integrations';
import search from './search';
import liveSearch from './liveSearch';
@ -17,7 +16,6 @@ const rootReducer = combineReducers({
customFields,
search,
liveSearch,
...integrations,
...sources
});

View file

@ -1,46 +0,0 @@
import { fetchListType, fetchType, saveType, editType, initType, removeType } from '../funcTools/types';
export function fetchList(name) {
return {
types: fetchListType(name).array,
call: (client) => client.get(`/integrations/${name}`),
name,
};
}
export function fetch(name, siteId) {
return {
types: fetchType(name).array,
call: (client) => client.get(siteId && name !== 'github' && name !== 'jira' ? `/${siteId}/integrations/${name}` : `/integrations/${name}`),
name,
};
}
export function save(name, siteId, instance) {
return {
types: saveType(name).array,
call: (client) => client.post((siteId ? `/${siteId}` : '') + `/integrations/${name}`, instance.toData()),
};
}
export function edit(name, instance) {
return {
type: editType(name),
instance,
};
}
export function init(name, instance) {
return {
type: initType(name),
instance,
};
}
export function remove(name, siteId) {
return {
types: removeType(name).array,
call: (client) => client.delete((siteId ? `/${siteId}` : '') + `/integrations/${name}`),
siteId,
};
}

View file

@ -1,37 +0,0 @@
import SentryConfig from 'Types/integrations/sentryConfig';
import DatadogConfig from 'Types/integrations/datadogConfig';
import StackdriverConfig from 'Types/integrations/stackdriverConfig';
import RollbarConfig from 'Types/integrations/rollbarConfig';
import NewrelicConfig from 'Types/integrations/newrelicConfig';
import BugsnagConfig from 'Types/integrations/bugsnagConfig';
import CloudWatch from 'Types/integrations/cloudwatchConfig';
import ElasticsearchConfig from 'Types/integrations/elasticsearchConfig';
import SumoLogicConfig from 'Types/integrations/sumoLogicConfig';
import JiraConfig from 'Types/integrations/jiraConfig';
import GithubConfig from 'Types/integrations/githubConfig';
import IssueTracker from 'Types/integrations/issueTracker';
import slack from './slack';
import integrations from './integrations';
import teams from './teams'
import { createIntegrationReducer } from './reducer';
export default {
sentry: createIntegrationReducer('sentry', SentryConfig),
datadog: createIntegrationReducer('datadog', DatadogConfig),
stackdriver: createIntegrationReducer('stackdriver', StackdriverConfig),
rollbar: createIntegrationReducer('rollbar', RollbarConfig),
newrelic: createIntegrationReducer('newrelic', NewrelicConfig),
bugsnag: createIntegrationReducer('bugsnag', BugsnagConfig),
cloudwatch: createIntegrationReducer('cloudwatch', CloudWatch),
elasticsearch: createIntegrationReducer('elasticsearch', ElasticsearchConfig),
sumologic: createIntegrationReducer('sumologic', SumoLogicConfig),
jira: createIntegrationReducer('jira', JiraConfig),
github: createIntegrationReducer('github', GithubConfig),
issues: createIntegrationReducer('issues', IssueTracker),
slack,
teams,
integrations,
};
export * from './actions';

View file

@ -1,40 +0,0 @@
import { Map } from 'immutable';
import { fetchListType } from '../funcTools/types';
import { createRequestReducer } from '../funcTools/request';
const FETCH_LIST = fetchListType('integrations/FETCH_LIST');
const SET_SITE_ID = 'integrations/SET_SITE_ID';
const initialState = Map({
list: [],
siteId: null,
});
const reducer = (state = initialState, action = {}) => {
switch (action.type) {
case FETCH_LIST.success:
return state.set('list', action.data);
case SET_SITE_ID:
return state.set('siteId', action.siteId);
}
return state;
};
export default createRequestReducer(
{
fetchRequest: FETCH_LIST,
},
reducer
);
export function fetchIntegrationList(siteID) {
return {
types: FETCH_LIST.array,
call: (client) => client.get(`/${siteID}/integrations`),
};
}
export function setSiteId(siteId) {
return {
type: SET_SITE_ID,
siteId,
};
}

View file

@ -1,52 +0,0 @@
import { List, Map } from 'immutable';
import { createRequestReducer } from '../funcTools/request';
import { fetchListType, saveType, removeType, editType, initType, fetchType } from '../funcTools/types';
import { createItemInListUpdater } from '../funcTools/tools';
const idKey = 'siteId';
const itemInListUpdater = createItemInListUpdater(idKey);
export const createIntegrationReducer = (name, Config) => {
const FETCH_LIST = fetchListType(name);
const SAVE = saveType(name);
const REMOVE = removeType(name);
const EDIT = editType(name);
const INIT = initType(name);
const FETCH = fetchType(name);
const initialState = Map({
instance: Config(),
list: List(),
fetched: false,
issuesFetched: false,
});
const reducer = (state = initialState, action = {}) => {
switch (action.type) {
case FETCH_LIST.success:
return state
.set('list', Array.isArray(action.data) ? List(action.data).map(Config) : List([new Config(action.data)]))
.set(action.name + 'Fetched', true);
case FETCH.success:
return state.set('instance', Config(action.data || {}));
case SAVE.success:
const config = Config(action.data);
return state.update('list', itemInListUpdater(config)).set('instance', config);
case REMOVE.success:
return state.update('list', (list) => list.filter((site) => site.siteId !== action.siteId)).set('instance', Config());
case EDIT:
return state.mergeIn(['instance'], action.instance);
case INIT:
return state.set('instance', Config(action.instance));
}
return state;
};
return createRequestReducer(
{
// fetchRequest: FETCH_LIST,
fetchRequest: FETCH,
saveRequest: SAVE,
removeRequest: REMOVE,
},
reducer
);
};

View file

@ -1,102 +0,0 @@
import { Map, List } from 'immutable';
import withRequestState, { RequestTypes } from 'Duck/requestStateCreator';
import Config from 'Types/integrations/slackConfig';
import { createItemInListUpdater } from '../funcTools/tools';
const SAVE = new RequestTypes('slack/SAVE');
const UPDATE = new RequestTypes('slack/UPDATE');
const REMOVE = new RequestTypes('slack/REMOVE');
const FETCH_LIST = new RequestTypes('slack/FETCH_LIST');
const SEND_MSG = new RequestTypes('slack/SEND_MSG');
const EDIT = 'slack/EDIT';
const INIT = 'slack/INIT';
const idKey = 'webhookId';
const itemInListUpdater = createItemInListUpdater(idKey);
const initialState = Map({
instance: Config(),
loaded: false,
list: List(),
});
const reducer = (state = initialState, action = {}) => {
switch (action.type) {
case FETCH_LIST.REQUEST:
return state.set('loaded', true);
case FETCH_LIST.SUCCESS:
return state.set('list', List(action.data).map(Config)).set('loaded', true)
case UPDATE.SUCCESS:
case SAVE.SUCCESS:
const config = Config(action.data);
return state.update('list', itemInListUpdater(config)).set('instance', config);
case REMOVE.SUCCESS:
return state.update('list', (list) => list.filter((item) => item.webhookId !== action.id)).set('instance', Config());
case EDIT:
return state.mergeIn(['instance'], action.instance);
case INIT:
return state.set('instance', Config(action.instance));
}
return state;
};
export default withRequestState(
{
fetchRequest: FETCH_LIST,
saveRequest: SAVE,
updateRequest: UPDATE,
removeRequest: REMOVE,
},
reducer
);
export function fetchList() {
return {
types: FETCH_LIST.toArray(),
call: (client) => client.get('/integrations/slack/channels'),
};
}
export function save(instance) {
return {
types: SAVE.toArray(),
call: (client) => client.post(`/integrations/slack`, instance.toData()),
};
}
export function update(instance) {
return {
types: UPDATE.toArray(),
call: (client) => client.post(`/integrations/slack/${instance.webhookId}`, instance.toData()),
};
}
export function edit(instance) {
return {
type: EDIT,
instance,
};
}
export function init(instance) {
return {
type: INIT,
instance,
};
}
export function remove(id) {
return {
types: REMOVE.toArray(),
call: (client) => client.delete(`/integrations/slack/${id}`),
id,
};
}
// https://api.openreplay.com/5587/integrations/slack/notify/315/sessions/7856803626558104
//
export function sendSlackMsg({ integrationId, entity, entityId, data }) {
return {
types: SEND_MSG.toArray(),
call: (client) => client.post(`/integrations/slack/notify/${integrationId}/${entity}/${entityId}`, data)
}
}

View file

@ -1,101 +0,0 @@
import { Map, List } from 'immutable';
import withRequestState, { RequestTypes } from 'Duck/requestStateCreator';
import Config from 'Types/integrations/slackConfig';
import { createItemInListUpdater } from '../funcTools/tools';
const SAVE = new RequestTypes('msteams/SAVE');
const UPDATE = new RequestTypes('msteams/UPDATE');
const REMOVE = new RequestTypes('msteams/REMOVE');
const FETCH_LIST = new RequestTypes('msteams/FETCH_LIST');
const SEND_MSG = new RequestTypes('msteams/SEND_MSG');
const EDIT = 'msteams/EDIT';
const INIT = 'msteams/INIT';
const idKey = 'webhookId';
const itemInListUpdater = createItemInListUpdater(idKey);
const initialState = Map({
instance: Config(),
list: List(),
loaded: false,
});
const reducer = (state = initialState, action = {}) => {
switch (action.type) {
case FETCH_LIST.REQUEST:
return state.set('loaded', true);
case FETCH_LIST.SUCCESS:
return state.set('list', List(action.data).map(Config)).set('loaded', true);
case UPDATE.SUCCESS:
case SAVE.SUCCESS:
const config = Config(action.data);
return state.update('list', itemInListUpdater(config)).set('instance', config);
case REMOVE.SUCCESS:
return state.update('list', (list) => list.filter((item) => item.webhookId !== action.id)).set('instance', Config());
case EDIT:
return state.mergeIn(['instance'], action.instance);
case INIT:
return state.set('instance', Config(action.instance));
}
return state;
};
export default withRequestState(
{
fetchRequest: FETCH_LIST,
saveRequest: SAVE,
updateRequest: UPDATE,
removeRequest: REMOVE,
},
reducer
);
export function fetchList() {
return {
types: FETCH_LIST.toArray(),
call: (client) => client.get('/integrations/msteams/channels'),
};
}
export function save(instance) {
return {
types: SAVE.toArray(),
call: (client) => client.post(`/integrations/msteams`, instance.toData()),
};
}
export function update(instance) {
return {
types: UPDATE.toArray(),
call: (client) => client.post(`/integrations/msteams/${instance.webhookId}`, instance.toData()),
};
}
export function edit(instance) {
return {
type: EDIT,
instance,
};
}
export function init(instance) {
return {
type: INIT,
instance,
};
}
export function remove(id) {
return {
types: REMOVE.toArray(),
call: (client) => client.delete(`/integrations/msteams/${id}`),
id,
};
}
export function sendMsTeamsMsg({ integrationId, entity, entityId, data }) {
return {
types: SEND_MSG.toArray(),
call: (client) => client.post(`/integrations/msteams/notify/${integrationId}/${entity}/${entityId}`, data)
}
}