[FIX] Integrations history page not reacting to changes. (#19114)

pull/19172/head
gabriellsh 5 years ago committed by GitHub
parent 95eabd9217
commit 9a8ee39049
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      app/integrations/client/streamer.js
  2. 99
      client/admin/integrations/edit/OutgoingWebhookHistoryPage.js

@ -0,0 +1,3 @@
import { Meteor } from 'meteor/meteor';
export const integrationHistoryStreamer = new Meteor.Streamer('integrationHistory');

@ -1,5 +1,6 @@
import { Button, ButtonGroup, Icon, Skeleton, Box, Accordion, Field, FieldGroup, Pagination } from '@rocket.chat/fuselage';
import React, { useMemo, useCallback, useState } from 'react';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import React, { useMemo, useCallback, useState, useEffect } from 'react';
import Page from '../../../components/basic/Page';
import { useTranslation } from '../../../contexts/TranslationContext';
@ -10,8 +11,9 @@ import { useEndpointDataExperimental, ENDPOINT_STATES } from '../../../hooks/use
import { useRoute, useRouteParameter } from '../../../contexts/RouterContext';
import { useFormatDateAndTime } from '../../../hooks/useFormatDateAndTime';
import { useToastMessageDispatch } from '../../../contexts/ToastMessagesContext';
import { integrationHistoryStreamer } from '../../../../app/integrations/client/streamer';
function HistoryItem({ data, onChange, ...props }) {
function HistoryItem({ data, ...props }) {
const t = useTranslation();
const replayOutgoingIntegration = useMethod('replayOutgoingIntegration');
@ -34,14 +36,17 @@ function HistoryItem({ data, onChange, ...props }) {
integration: { _id: integrationId },
} = data;
const handleClickReplay = useCallback((e) => {
const createdAt = typeof _createdAt === 'string' ? _createdAt : _createdAt.toISOString();
const updatedAt = typeof _updatedAt === 'string' ? _updatedAt : _updatedAt.toISOString();
const handleClickReplay = useMutableCallback((e) => {
e.stopPropagation();
replayOutgoingIntegration({ integrationId, historyId: _id });
onChange();
}, [_id, integrationId, onChange, replayOutgoingIntegration]);
});
const formatDateAndTime = useFormatDateAndTime();
const dataSentToTriggerCode = useHighlightedCode('json', JSON.stringify(dataSentToTrigger || '', null, 2));
const prepareSentMessageCode = useHighlightedCode('json', JSON.stringify(prepareSentMessage || '', null, 2));
const processSentMessageCode = useHighlightedCode('json', JSON.stringify(processSentMessage || '', null, 2));
const httpCallDataCode = useHighlightedCode('json', JSON.stringify(httpCallData || '', null, 2));
@ -73,7 +78,7 @@ function HistoryItem({ data, onChange, ...props }) {
<Field.Label>{t('Integration_Outgoing_WebHook_History_Time_Triggered')}</Field.Label>
<Field.Row>
<Box withRichContent w='full'>
<code>{_createdAt}</code>
<code>{createdAt}</code>
</Box>
</Field.Row>
</Field>
@ -81,7 +86,7 @@ function HistoryItem({ data, onChange, ...props }) {
<Field.Label>{t('Integration_Outgoing_WebHook_History_Time_Ended_Or_Error')}</Field.Label>
<Field.Row>
<Box withRichContent w='full'>
<code>{_updatedAt}</code>
<code>{updatedAt}</code>
</Box>
</Field.Row>
</Field>
@ -101,14 +106,14 @@ function HistoryItem({ data, onChange, ...props }) {
</Box>
</Field.Row>
</Field>
<Field>
{dataSentToTrigger && <Field>
<Field.Label>{t('Integration_Outgoing_WebHook_History_Data_Passed_To_Trigger')}</Field.Label>
<Field.Row>
<Box withRichContent w='full'>
<pre><code dangerouslySetInnerHTML={{ __html: useHighlightedCode('json', JSON.stringify(dataSentToTrigger, null, 2)) }}></code></pre>
<pre><code dangerouslySetInnerHTML={{ __html: dataSentToTriggerCode }}></code></pre>
</Box>
</Field.Row>
</Field>
</Field>}
{prepareSentMessage && <Field>
<Field.Label>{t('Integration_Outgoing_WebHook_History_Messages_Sent_From_Prepare_Script')}</Field.Label>
<Field.Row>
@ -183,16 +188,15 @@ function HistoryContent({ data, state, onChange, ...props }) {
</Box>;
}
if (data.history.length < 1) {
if (data.length < 1) {
return <Box mbs='x16' {...props}>{t('Integration_Outgoing_WebHook_No_History')}</Box>;
}
return <>
<Accordion w='full' maxWidth='x600' alignSelf='center' key='content'>
{data.history.map((current) => <HistoryItem
{data.map((current) => <HistoryItem
data={current}
key={current._id}
onChange={onChange}
/>)}
</Accordion>
</>;
@ -202,22 +206,33 @@ function OutgoingWebhookHistoryPage(props) {
const dispatchToastMessage = useToastMessageDispatch();
const t = useTranslation();
const [cache, setCache] = useState();
const [currentData, setCurrentData] = useState();
const [current, setCurrent] = useState();
const [itemsPerPage, setItemsPerPage] = useState();
const onChange = useCallback(() => {
setCache(new Date());
}, []);
const [mounted, setMounted] = useState(false);
const [total, setTotal] = useState(0);
const router = useRoute('admin-integrations');
const clearHistory = useMethod('clearIntegrationHistory');
const id = useRouteParameter('id');
const query = useMemo(() => ({
id,
count: itemsPerPage,
offset: current,
}), [id, itemsPerPage, current]);
const { data, state, reload } = useEndpointDataExperimental('integrations.history', query);
const handleClearHistory = async () => {
try {
await clearHistory();
dispatchToastMessage({ type: 'success', message: t('Integration_History_Cleared') });
onChange();
reload();
setMounted(false);
} catch (e) {
dispatchToastMessage({ type: 'error', message: e });
}
@ -227,16 +242,42 @@ function OutgoingWebhookHistoryPage(props) {
router.push({ });
};
const id = useRouteParameter('id');
const handleDataChange = useMutableCallback(({ type, id, diff, data }) => {
if (type === 'inserted') {
setTotal((total) => total + 1);
setCurrentData((state) => [data].concat(state));
return;
}
const query = useMemo(() => ({
id,
count: itemsPerPage,
offset: current,
// TODO: remove cache. Is necessary for data validation
}), [id, itemsPerPage, current, cache]);
if (type === 'updated') {
setCurrentData((state) => {
const index = state.findIndex(({ _id }) => _id === id);
Object.assign(state[index], diff);
return state;
});
return;
}
if (type === 'removed') {
setCurrentData([]);
}
});
useEffect(() => {
if (state === ENDPOINT_STATES.DONE && !mounted) {
setCurrentData(data.history);
setTotal(data.total);
setMounted(true);
}
}, [data, mounted, state]);
useEffect(() => {
if (mounted) {
integrationHistoryStreamer.on(id, handleDataChange);
}
const { data, state } = useEndpointDataExperimental('integrations.history', query);
return () => integrationHistoryStreamer.removeListener(id, handleDataChange);
}, [handleDataChange, id, mounted]);
const showingResultsLabel = useCallback(({ count, current, itemsPerPage }) => t('Showing results %s - %s of %s', current + 1, Math.min(current + itemsPerPage, count), count), [t]);
@ -246,19 +287,19 @@ function OutgoingWebhookHistoryPage(props) {
<Button onClick={handleClickReturn}>
<Icon name='back' size='x16'/> {t('Back')}
</Button>
<Button primary danger onClick={handleClearHistory} disabled={!(data && data.history.length > 0)}>
<Button primary danger onClick={handleClearHistory} disabled={total === 0}>
<Icon name='trash'/> {t('clear_history')}
</Button>
</ButtonGroup>
</Page.Header>
<Page.ScrollableContentWithShadow>
<HistoryContent key='historyContent' data={data} state={state} onChange={onChange} />
<HistoryContent key='historyContent' data={currentData} state={state} />
<Pagination
current={current}
itemsPerPage={itemsPerPage}
itemsPerPageLabel={t('Items_per_page:')}
showingResultsLabel={showingResultsLabel}
count={(data && data.total) || 0}
count={total}
onSetItemsPerPage={setItemsPerPage}
onSetCurrent={setCurrent}
/>

Loading…
Cancel
Save