pl-fe: hotfix for reports in pleroma admin api

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2025-10-19 22:49:34 +02:00
parent fc7cdea984
commit 39600920b3
5 changed files with 54 additions and 28 deletions

View File

@ -2,6 +2,7 @@ import React, { useCallback } from 'react';
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router-dom';
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
import HoverAccountWrapper from 'pl-fe/components/hover-account-wrapper';
import Avatar from 'pl-fe/components/ui/avatar';
import HStack from 'pl-fe/components/ui/hstack';
@ -23,10 +24,11 @@ const Report: React.FC<IReport> = ({ id }) => {
const report = useAppSelector((state) => getReport(state, minifiedReport));
const { account: targetAccount } = useAccount(report?.target_account_id);
if (!report) return null;
const account = report.account;
const targetAccount = report.target_account!;
const statuses = report.statuses;
const statusCount = statuses.length;
@ -35,25 +37,27 @@ const Report: React.FC<IReport> = ({ id }) => {
return (
<Link to={`/pl-fe/admin/reports/${id}`} className='block rounded-lg bg-gray-100 p-4 dark:bg-primary-800'>
<Stack space={2} className='h-full justify-between'>
<HoverAccountWrapper accountId={targetAccount.id} element='span'>
<HStack alignItems='center' space={2}>
<Avatar
src={targetAccount.avatar}
alt={targetAccount.avatar_description}
size={40}
isCat={targetAccount.is_cat}
username={targetAccount.username}
/>
<Stack>
<Text size='sm' weight='semibold' truncate>
<Emojify text={targetAccount.display_name} emojis={targetAccount.emojis} />
</Text>
<Text size='sm' theme='muted' direction='ltr' truncate>
@{targetAccount.fqn}
</Text>
</Stack>
</HStack>
</HoverAccountWrapper>
{targetAccount && (
<HoverAccountWrapper accountId={targetAccount.id} element='span'>
<HStack alignItems='center' space={2}>
<Avatar
src={targetAccount.avatar}
alt={targetAccount.avatar_description}
size={40}
isCat={targetAccount.is_cat}
username={targetAccount.username}
/>
<Stack>
<Text size='sm' weight='semibold' truncate>
<Emojify text={targetAccount.display_name} emojis={targetAccount.emojis} />
</Text>
<Text size='sm' theme='muted' direction='ltr' truncate>
@{targetAccount.fqn}
</Text>
</Stack>
</HStack>
</HoverAccountWrapper>
)}
{!!account && (
<HStack space={1} alignItems='center' wrap>

View File

@ -3,6 +3,7 @@ import { defineMessages, FormattedDate, FormattedMessage, useIntl } from 'react-
import { Link } from 'react-router-dom';
import ReactSwipeableViews from 'react-swipeable-views';
import { useAccount } from 'pl-fe/api/hooks/accounts/use-account';
import Account from 'pl-fe/components/account';
import List, { ListItem } from 'pl-fe/components/list';
import Card from 'pl-fe/components/ui/card';
@ -92,6 +93,9 @@ const ReportPage: React.FC<IReportPage> = (props) => {
const report = useAppSelector((state) => getReport(state, minifiedReport));
const { account: authorAccount } = useAccount(report?.account_id);
const { account: targetAccount } = useAccount(report?.target_account_id);
const { mutate: selfAssignReport } = useSelfAssignReport(reportId);
const { mutate: unassignReport } = useUnassignReport(reportId);
const { mutate: resolveReport } = useResolveReport(reportId);
@ -148,14 +152,14 @@ const ReportPage: React.FC<IReportPage> = (props) => {
<Column label={intl.formatMessage(messages.columnHeading, { id: reportId })}>
<div className='mb-4 grid grid-cols-1 gap-2 md:grid-cols-2'>
{report.target_account && (
<Link to={`/@${report.target_account.acct}`} className='h-fit'>
{targetAccount && (
<Link to={`/@${targetAccount.acct}`} className='h-fit'>
<Card variant='rounded'>
<Stack space={2}>
<Text size='md' weight='medium'>
<FormattedMessage id='admin.report.target_account' defaultMessage='Reported account' />
</Text>
<Account account={report.target_account} disabled hideActions />
<Account account={targetAccount} disabled hideActions />
</Stack>
</Card>
</Link>
@ -175,7 +179,7 @@ const ReportPage: React.FC<IReportPage> = (props) => {
</Text>
</td>
</tr>
{report.account && (
{authorAccount && (
<tr className='border-b border-primary-200 last:border-none dark:border-gray-800'>
<td className='p-2.5'>
<Text weight='medium' size='sm' tag='span'>
@ -186,7 +190,7 @@ const ReportPage: React.FC<IReportPage> = (props) => {
<td className='p-2.5 text-end'>
<Text size='sm' className='hover:underline'>
<Link to={`/pl-fe/admin/accounts/${report.account_id}`}>
@{report.account.acct}
@{authorAccount.acct}
</Link>
</Text>
</td>

View File

@ -22,16 +22,17 @@ const useAdminAccounts = makePaginatedResponseQuery(
'isAdmin',
);
const useAdminAccount = (accountId: string) => {
const useAdminAccount = (accountId?: string) => {
const client = useClient();
const dispatch = useAppDispatch();
const query = useQuery<AdminAccount>({
queryKey: ['admin', 'accounts', accountId],
queryFn: () => client.admin.accounts.getAccount(accountId).then(({ account, ...adminAccount }) => {
queryFn: () => client.admin.accounts.getAccount(accountId!).then(({ account, ...adminAccount }) => {
dispatch(importEntities({ accounts: [account] }));
return adminAccount as AdminAccount;
}),
enabled: !!accountId,
});
const { account } = useAccount(query.data ? accountId : undefined);

View File

@ -42,6 +42,13 @@ const minifyAdminAccountList = (response: PaginatedResponse<AdminAccount>) =>
});
const minifyAdminReport = ({ account, action_taken_by_account, assigned_account, target_account, statuses, ...adminReport }: AdminReport) => {
minifyAdminAccountList({
items: [account, action_taken_by_account, assigned_account, target_account].filter((a): a is AdminAccount => !!a),
previous: null,
next: null,
partial: false,
});
store.dispatch(importEntities({
accounts: [account.account, action_taken_by_account?.account, assigned_account?.account, target_account?.account],
statuses: statuses as any,

View File

@ -68,7 +68,17 @@
flex-direction: column;
&__counter {
@apply absolute -right-3 -top-2 flex h-5 min-w-[20px] shrink-0 items-center justify-center whitespace-nowrap break-words;
position: absolute;
right: -0.75rem;
top: -0.5rem;
display: flex;
height: 1.25rem;
min-width: 1.25rem;
flex-shrink: 0;
align-items: center;
justify-content: center;
white-space: nowrap;
word-break: break-word;
}
}