Files
upstream-mirror 30810eecd7
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:21:02 +05:00

177 lines
4.9 KiB
TypeScript

import { isDirectMessageRoom } from '@rocket.chat/core-typings';
import { useStableCallback } from '@rocket.chat/fuselage-hooks';
import { GenericModal } from '@rocket.chat/ui-client';
import { useSetModal, useToastMessageDispatch, useEndpoint, useRoomToolbox } from '@rocket.chat/ui-contexts';
import { useCallback, useMemo, useState } from 'react';
import { useForm, FormProvider } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import PruneMessages from './PruneMessages';
import { formatDate } from '../../../../lib/utils/dateFormat';
import { useRoom } from '../../contexts/RoomContext';
const getTimeZoneOffset = (): string => {
const offset = new Date().getTimezoneOffset();
const absOffset = Math.abs(offset);
return `${offset < 0 ? '+' : '-'}${`00${Math.floor(absOffset / 60)}`.slice(-2)}:${`00${absOffset % 60}`.slice(-2)}`;
};
export const initialValues = {
newer: {
date: '',
time: '',
},
older: {
date: '',
time: '',
},
users: [],
inclusive: false,
pinned: false,
discussion: false,
threads: false,
attached: false,
};
const DEFAULT_PRUNE_LIMIT = 2000;
const PruneMessagesWithData = () => {
const { t } = useTranslation();
const room = useRoom();
const setModal = useSetModal();
const { closeTab: close } = useRoomToolbox();
const closeModal = useCallback(() => setModal(null), [setModal]);
const dispatchToastMessage = useToastMessageDispatch();
const pruneMessagesAction = useEndpoint('POST', '/v1/rooms.cleanHistory');
const [counter, setCounter] = useState(0);
const methods = useForm({ defaultValues: initialValues });
const {
newer: { date: newerDate, time: newerTime },
older: { date: olderDate, time: olderTime },
users,
inclusive,
pinned,
discussion,
threads,
attached,
} = methods.watch();
const fromDate = useMemo(() => {
return new Date(`${newerDate || '0001-01-01'}T${newerTime || '00:00'}:00${getTimeZoneOffset()}`);
}, [newerDate, newerTime]);
const toDate = useMemo(() => {
return new Date(`${olderDate || '9999-12-31'}T${olderTime || '23:59'}:59${getTimeZoneOffset()}`);
}, [olderDate, olderTime]);
const handlePrune = useStableCallback((): void => {
const handlePruneAction = async () => {
const limit = DEFAULT_PRUNE_LIMIT;
try {
if (counter === limit) {
return;
}
const { count } = await pruneMessagesAction({
roomId: room._id,
latest: toDate.toISOString(),
oldest: fromDate.toISOString(),
inclusive,
limit,
excludePinned: pinned,
filesOnly: attached,
ignoreDiscussion: discussion,
ignoreThreads: threads,
users,
});
setCounter(count);
if (count < 1) {
throw new Error(attached ? t('No_files_found_to_prune') : t('No_messages_found_to_prune'));
}
dispatchToastMessage({
type: 'success',
message: attached ? t('__count__file_pruned', { count }) : t('__count__message_pruned', { count }),
});
methods.reset();
} catch (error: unknown) {
dispatchToastMessage({ type: 'error', message: error });
} finally {
closeModal();
}
};
return setModal(
<GenericModal
variant='danger'
onClose={closeModal}
onCancel={closeModal}
onConfirm={handlePruneAction}
confirmText={t('Yes_prune_them')}
>
{t('Prune_Modal')}
</GenericModal>,
);
});
const callOutText = useMemo(() => {
const name = room && ((isDirectMessageRoom(room) && room.usernames?.join(' x ')) || room.fname || room.name);
const exceptPinned = pinned ? ` ${t('except_pinned')}` : '';
const ifFrom = users.length ? ` ${t('if_they_are_from', { users: users.map((element) => element).join(', ') })}` : '';
const filesOrMessages = attached ? t('files') : t('messages');
if (newerDate && olderDate) {
return (
t('Prune_Warning_between', {
items: filesOrMessages,
roomName: name,
fromDate: formatDate(fromDate, 'L LT'),
toDate: formatDate(toDate, 'L LT'),
}) +
exceptPinned +
ifFrom
);
}
if (newerDate) {
return (
t('Prune_Warning_after', { items: filesOrMessages, roomName: name, fromDate: formatDate(fromDate, 'L LT') }) + exceptPinned + ifFrom
);
}
if (olderDate) {
return (
t('Prune_Warning_before', { items: filesOrMessages, roomName: name, toDate: formatDate(toDate, 'L LT') }) + exceptPinned + ifFrom
);
}
return t('Prune_Warning_all', { items: filesOrMessages, roomName: name }) + exceptPinned + ifFrom;
}, [attached, fromDate, newerDate, olderDate, pinned, room, t, toDate, users]);
const validateText = useMemo(() => {
if (fromDate > toDate) {
return t('Newer_than_may_not_exceed_Older_than');
}
if (isNaN(fromDate.getTime()) || isNaN(toDate.getTime())) {
return t('error-invalid-date');
}
return undefined;
}, [fromDate, t, toDate]);
return (
<FormProvider {...methods}>
<PruneMessages callOutText={callOutText} validateText={validateText} users={users} onClickClose={close} onClickPrune={handlePrune} />
</FormProvider>
);
};
export default PruneMessagesWithData;