Skip to content

Commit

Permalink
Merge branch 'develop' into OC-715
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored May 26, 2023
2 parents ecc9858 + eeee52f commit e937e78
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 85 deletions.
5 changes: 5 additions & 0 deletions .changeset/polite-clouds-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

chore: update room on `cleanRoomHistory` only if any message has been deleted
12 changes: 12 additions & 0 deletions apps/meteor/client/components/LoadingIndicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Box, Throbber } from '@rocket.chat/fuselage';
import React from 'react';

const LoadingIndicator = () => {
return (
<Box display='flex' height='100%' width='100%' alignItems='center' justifyContent='center' position='absolute'>
<Throbber />
</Box>
);
};

export default LoadingIndicator;
86 changes: 42 additions & 44 deletions apps/meteor/client/views/marketplace/AppsProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { AppStatus } from '@rocket.chat/apps-engine/definition/AppStatus';
import { usePermission } from '@rocket.chat/ui-contexts';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import type { FC } from 'react';
Expand Down Expand Up @@ -45,36 +44,19 @@ const AppsProvider: FC = ({ children }) => {
useEffect(() => {
const listeners = {
APP_ADDED: (): void => {
queryClient.invalidateQueries(['apps-instance', isAdminUser]);
queryClient.invalidateQueries(['apps-stored', isAdminUser]);
queryClient.invalidateQueries(['marketplace', 'apps-instance']);
},
APP_UPDATED: (): void => {
queryClient.invalidateQueries(['apps-instance', isAdminUser]);
queryClient.invalidateQueries(['apps-stored', isAdminUser]);
queryClient.invalidateQueries(['marketplace', 'apps-instance']);
},
APP_REMOVED: (appId: string): void => {
queryClient.setQueryData<App[]>(['apps-instance', isAdminUser], (data) => {
return data?.filter((app) => app.id !== appId);
});
queryClient.invalidateQueries(['apps-stored', isAdminUser]);
APP_REMOVED: (): void => {
queryClient.invalidateQueries(['marketplace', 'apps-instance']);
},
APP_STATUS_CHANGE: ({ appId, status }: { appId: string; status: AppStatus }): void => {
queryClient.setQueryData<App[]>(['apps-instance', isAdminUser], (data) => {
return data?.map((app) => {
if (app.id !== appId) {
return app;
}
return {
...app,
status,
};
});
});
queryClient.invalidateQueries(['apps-stored', isAdminUser]);
APP_STATUS_CHANGE: (): void => {
queryClient.invalidateQueries(['marketplace', 'apps-instance']);
},
APP_SETTING_UPDATED: (): void => {
queryClient.invalidateQueries(['apps-instance', isAdminUser]);
queryClient.invalidateQueries(['apps-stored', isAdminUser]);
queryClient.invalidateQueries(['marketplace', 'apps-instance']);
},
};
const unregisterListeners = registerListeners(listeners);
Expand All @@ -83,26 +65,42 @@ const AppsProvider: FC = ({ children }) => {
return unregisterListeners;
}, [invalidateAppsCountQuery, isAdminUser, queryClient]);

const marketplace = useQuery(['apps-marketplace', isAdminUser], () => Apps.getAppsFromMarketplace(isAdminUser ? 'true' : 'false'), {
staleTime: Infinity,
refetchOnWindowFocus: false,
keepPreviousData: true,
});
const marketplace = useQuery(
['marketplace', 'apps-marketplace', isAdminUser],
() => {
const result = Apps.getAppsFromMarketplace(isAdminUser ? 'true' : 'false');
queryClient.invalidateQueries(['marketplace', 'apps-stored']);
return result;
},
{
staleTime: Infinity,
refetchOnWindowFocus: false,
keepPreviousData: true,
onSettled: () => queryClient.invalidateQueries(['marketplace', 'apps-stored']),
},
);

const instance = useQuery(
['apps-instance', isAdminUser],
() =>
Apps.getInstalledApps().then((result: App[]) =>
['marketplace', 'apps-instance', isAdminUser],
async () => {
const result = await Apps.getInstalledApps().then((result: App[]) =>
result.map((current: App) => ({
...current,
installed: true,
})),
),
{ staleTime: Infinity, refetchOnWindowFocus: false, keepPreviousData: true },
);
return result;
},
{
staleTime: Infinity,
refetchOnWindowFocus: false,
keepPreviousData: true,
onSettled: () => queryClient.invalidateQueries(['marketplace', 'apps-stored']),
},
);

const store = useQuery(
['apps-stored', isAdminUser],
['marketplace', 'apps-stored', isAdminUser],
() => {
if (!marketplace.isSuccess || !instance.isSuccess) {
throw new Error('Apps not loaded');
Expand All @@ -112,9 +110,11 @@ const AppsProvider: FC = ({ children }) => {
const installedApps: App[] = [];
const privateApps: App[] = [];

const clonedData = [...instance.data];

sortByName(marketplace.data).forEach((app) => {
const appIndex = instance.data.findIndex(({ id }) => id === app.id);
const [installedApp] = appIndex > -1 ? instance.data.splice(appIndex, 1) : [];
const appIndex = clonedData.findIndex(({ id }) => id === app.id);
const [installedApp] = appIndex > -1 ? clonedData.splice(appIndex, 1) : [];

const record = {
...app,
Expand All @@ -140,7 +140,7 @@ const AppsProvider: FC = ({ children }) => {
marketplaceApps.push(record);
});

sortByName(instance.data).forEach((app) => {
sortByName(clonedData).forEach((app) => {
if (app.private) {
privateApps.push(app);
}
Expand All @@ -149,7 +149,8 @@ const AppsProvider: FC = ({ children }) => {
return [marketplaceApps, installedApps, privateApps];
},
{
enabled: marketplace.isSuccess && instance.isSuccess,
enabled: marketplace.isSuccess && instance.isSuccess && !instance.isRefetching,
refetchOnWindowFocus: false,
keepPreviousData: true,
},
);
Expand All @@ -166,10 +167,7 @@ const AppsProvider: FC = ({ children }) => {
marketplaceApps: { phase: AsyncStatePhase.RESOLVED, value: { apps: store.data[0] } },
privateApps: { phase: AsyncStatePhase.RESOLVED, value: { apps: store.data[2] } },
reload: async () => {
await Promise.all([
queryClient.invalidateQueries(['apps-marketplace', isAdminUser]),
queryClient.invalidateQueries(['apps-instance', isAdminUser]),
]);
await Promise.all([queryClient.invalidateQueries(['marketplace'])]);
},
}}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import type { ReactElement } from 'react';
import React from 'react';

const LoadingMessagesIndicator = (): ReactElement => (
<div className='loading-animation'>
<div className='bounce bounce1' />
<div className='bounce bounce2' />
<div className='bounce bounce3' />
</div>
);
import LoadingIndicator from '../../../../components/LoadingIndicator';

const LoadingMessagesIndicator = (): ReactElement => <LoadingIndicator />;

export default LoadingMessagesIndicator;
8 changes: 3 additions & 5 deletions apps/meteor/client/views/root/PageLoading.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import type { FC } from 'react';
import React from 'react';

import LoadingIndicator from '../../components/LoadingIndicator';

const PageLoading: FC = () => (
<div className='page-loading' role='alert' aria-busy='true' aria-live='polite' aria-label='loading'>
<div className='loading-animation'>
<div className='bounce bounce1'></div>
<div className='bounce bounce2'></div>
<div className='bounce bounce3'></div>
</div>
<LoadingIndicator />
</div>
);

Expand Down
12 changes: 8 additions & 4 deletions apps/meteor/server/models/raw/Messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1354,8 +1354,10 @@ export class MessagesRaw extends BaseRaw<IMessage> implements IMessagesModel {
if (!limit) {
const count = (await this.deleteMany(query)).deletedCount;

// decrease message count
await Rooms.decreaseMessageCountById(rid, count);
if (count) {
// decrease message count
await Rooms.decreaseMessageCountById(rid, count);
}

return count;
}
Expand All @@ -1377,8 +1379,10 @@ export class MessagesRaw extends BaseRaw<IMessage> implements IMessagesModel {
})
).deletedCount;

// decrease message count
await Rooms.decreaseMessageCountById(rid, count);
if (count) {
// decrease message count
await Rooms.decreaseMessageCountById(rid, count);
}

return count;
}
Expand Down
121 changes: 121 additions & 0 deletions apps/meteor/tests/end-to-end/api/24-methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,127 @@ describe('Meteor.methods', function () {
});
});

describe('[@cleanRoomHistory]', () => {
let rid = false;

let channelName = false;

before('create room', (done) => {
channelName = `methods-test-channel-${Date.now()}`;
request
.post(api('groups.create'))
.set(credentials)
.send({
name: channelName,
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
expect(res.body).to.have.nested.property('group._id');
expect(res.body).to.have.nested.property('group.name', channelName);
expect(res.body).to.have.nested.property('group.t', 'p');
expect(res.body).to.have.nested.property('group.msgs', 0);
rid = res.body.group._id;
})
.end(done);
});

before('send sample message', (done) => {
request
.post(api('chat.sendMessage'))
.set(credentials)
.send({
message: {
text: 'Sample message',
rid,
},
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
})
.end(done);
});

before('send another sample message', (done) => {
request
.post(api('chat.sendMessage'))
.set(credentials)
.send({
message: {
text: 'Second Sample message',
rid,
},
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
})
.end(done);
});

it('should not change the _updatedAt value when nothing is changed on the room', async () => {
const roomBefore = await request.get(api('groups.info')).set(credentials).query({
roomId: rid,
});

await request
.post(api('rooms.cleanHistory'))
.set(credentials)
.send({
roomId: rid,
latest: '2016-12-09T13:42:25.304Z',
oldest: '2016-08-30T13:42:25.304Z',
excludePinned: false,
filesOnly: false,
ignoreThreads: false,
ignoreDiscussion: false,
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('count', 0);
});

const roomAfter = await request.get(api('groups.info')).set(credentials).query({
roomId: rid,
});
expect(roomBefore.body.group._updatedAt).to.be.equal(roomAfter.body.group._updatedAt);
});

it('should change the _updatedAt value when room is cleaned', async () => {
const roomBefore = await request.get(api('groups.info')).set(credentials).query({
roomId: rid,
});

await request
.post(api('rooms.cleanHistory'))
.set(credentials)
.send({
roomId: rid,
latest: '9999-12-31T23:59:59.000Z',
oldest: '0001-01-01T00:00:00.000Z',
excludePinned: false,
filesOnly: false,
ignoreThreads: false,
ignoreDiscussion: false,
})
.expect(200)
.expect((res) => {
expect(res.body).to.have.a.property('success', true);
expect(res.body).to.have.a.property('count', 2);
});

const roomAfter = await request.get(api('groups.info')).set(credentials).query({
roomId: rid,
});
expect(roomBefore.body.group._updatedAt).to.not.be.equal(roomAfter.body.group._updatedAt);
});
});

describe('[@loadHistory]', () => {
let rid = false;
let postMessageDate = false;
Expand Down
Loading

0 comments on commit e937e78

Please sign in to comment.