Files
2024-02-15 17:01:50 +00:00

149 lines
4.4 KiB
TypeScript

import {Fragment, useCallback, useMemo} from 'react';
import type {RouteComponentProps} from 'react-router';
import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
import type {
TContext,
TData,
TError,
TVariables,
} from 'sentry/components/feedback/useMutateActivity';
import useMutateActivity from 'sentry/components/feedback/useMutateActivity';
import * as Layout from 'sentry/components/layouts/thirds';
import ReprocessedBox from 'sentry/components/reprocessedBox';
import {t} from 'sentry/locale';
import GroupStore from 'sentry/stores/groupStore';
import type {
Group,
GroupActivity as GroupActivityType,
GroupActivityNote,
GroupActivityReprocess,
User,
} from 'sentry/types';
import type {NoteType} from 'sentry/types/alerts';
import type {MutateOptions} from 'sentry/utils/queryClient';
import useOrganization from 'sentry/utils/useOrganization';
import ActivitySection from 'sentry/views/issueDetails/activitySection';
import {
getGroupMostRecentActivity,
getGroupReprocessingStatus,
ReprocessingStatus,
} from 'sentry/views/issueDetails/utils';
type Props = {
group: Group;
} & RouteComponentProps<{}, {}>;
function GroupActivity({group}: Props) {
const organization = useOrganization();
const {activity: activities, count, id: groupId} = group;
const groupCount = Number(count);
const mostRecentActivity = getGroupMostRecentActivity(activities);
const reprocessingStatus = getGroupReprocessingStatus(group, mostRecentActivity);
const mutators = useMutateActivity({
organization,
group,
});
const deleteOptions: MutateOptions<TData, TError, TVariables, TContext> =
useMemo(() => {
return {
onError: () => {
addErrorMessage(t('Failed to delete comment'));
},
onSuccess: () => {
addSuccessMessage(t('Comment removed'));
},
};
}, []);
const createOptions: MutateOptions<TData, TError, TVariables, TContext> =
useMemo(() => {
return {
onError: () => {
addErrorMessage(t('Unable to post comment'));
},
onSuccess: data => {
GroupStore.addActivity(group.id, data);
addSuccessMessage(t('Comment posted'));
},
};
}, [group.id]);
const updateOptions: MutateOptions<TData, TError, TVariables, TContext> =
useMemo(() => {
return {
onError: () => {
addErrorMessage(t('Unable to update comment'));
},
onSuccess: data => {
const d = data as GroupActivityNote;
GroupStore.updateActivity(group.id, data.id, {text: d.data.text});
addSuccessMessage(t('Comment updated'));
},
};
}, [group.id]);
const handleDelete = useCallback(
(item: GroupActivityType) => {
const restore = group.activity.find(activity => activity.id === item.id);
const index = GroupStore.removeActivity(group.id, item.id);
if (index === -1 || restore === undefined) {
addErrorMessage(t('Failed to delete comment'));
return;
}
mutators.handleDelete(
item.id,
group.activity.filter(a => a.id !== item.id),
deleteOptions
);
},
[deleteOptions, group.activity, mutators, group.id]
);
const handleCreate = useCallback(
(n: NoteType, _me: User) => {
mutators.handleCreate(n, group.activity, createOptions);
},
[createOptions, group.activity, mutators]
);
const handleUpdate = useCallback(
(item: GroupActivityType, n: NoteType) => {
mutators.handleUpdate(n, item.id, group.activity, updateOptions);
},
[updateOptions, group.activity, mutators]
);
return (
<Fragment>
{(reprocessingStatus === ReprocessingStatus.REPROCESSED_AND_HASNT_EVENT ||
reprocessingStatus === ReprocessingStatus.REPROCESSED_AND_HAS_EVENT) && (
<ReprocessedBox
reprocessActivity={mostRecentActivity as GroupActivityReprocess}
groupCount={groupCount}
orgSlug={organization.slug}
groupId={groupId}
/>
)}
<Layout.Body>
<Layout.Main>
<ActivitySection
group={group}
onDelete={handleDelete}
onCreate={handleCreate}
onUpdate={handleUpdate}
placeholderText={t(
'Add details or updates to this event. \nTag users with @, or teams with #'
)}
/>
</Layout.Main>
</Layout.Body>
</Fragment>
);
}
export default GroupActivity;