nicolium: oxlint and oxfmt migration, remove eslint

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2026-02-15 13:30:55 +01:00
parent 81132cbd57
commit 9f98b5b07d
774 changed files with 23981 additions and 15283 deletions

View File

@ -58,12 +58,27 @@ const Counter: React.FC<ICounter> = ({
);
} else {
const measure = data[0];
const percentChange = measure.previous_total !== undefined && percIncrease(measure.previous_total * 1, measure.total * 1) || 0;
const percentChange =
(measure.previous_total !== undefined &&
percIncrease(measure.previous_total * 1, measure.total * 1)) ||
0;
content = (
<>
<Text tag='span' align='center' size='2xl' weight='medium'>{measure.human_value ?? <FormattedNumber value={measure.total} />}</Text>
{measure.previous_total !== undefined && (<span className={clsx('text-lg', { 'text-green-600': percentChange > 0, 'text-danger-600': percentChange < 0 })}>{percentChange > 0 && '+'}<FormattedNumber value={percentChange} style='percent' /></span>)}
<Text tag='span' align='center' size='2xl' weight='medium'>
{measure.human_value ?? <FormattedNumber value={measure.total} />}
</Text>
{measure.previous_total !== undefined && (
<span
className={clsx('text-lg', {
'text-green-600': percentChange > 0,
'text-danger-600': percentChange < 0,
})}
>
{percentChange > 0 && '+'}
<FormattedNumber value={percentChange} style='percent' />
</span>
)}
</>
);
}
@ -74,12 +89,10 @@ const Counter: React.FC<ICounter> = ({
{content}
</div>
<Text align='center'>
{label}
</Text>
<Text align='center'>{label}</Text>
<div className='mt-auto'>
<Sparklines width={259} height={55} data={data?.[0].data.map(x => x.value * 1) ?? []}>
<Sparklines width={259} height={55} data={data?.[0].data.map((x) => x.value * 1) ?? []}>
<SparklinesCurve />
</Sparklines>
</div>
@ -90,16 +103,16 @@ const Counter: React.FC<ICounter> = ({
if ('to' in rest) {
return (
<Link {...rest} className={clsx(className, 'transition-transform hover:-translate-y-1')} target={target}>
<Link
{...rest}
className={clsx(className, 'transition-transform hover:-translate-y-1')}
target={target}
>
{inner}
</Link>
);
} else {
return (
<div className={className}>
{inner}
</div>
);
return <div className={className}>{inner}</div>;
}
};

View File

@ -12,7 +12,6 @@ type IDashCounter = {
/** Displays a (potentially clickable) dashboard statistic. */
const DashCounter: React.FC<IDashCounter> = ({ count, label, percent = false, ...rest }) => {
if (!isNumber(count)) {
return null;
}
@ -27,9 +26,7 @@ const DashCounter: React.FC<IDashCounter> = ({ count, label, percent = false, ..
numberingSystem='latn'
/>
</p>
<p className='⁂-dashcounter__label'>
{label}
</p>
<p className='⁂-dashcounter__label'>{label}</p>
</>
);
@ -50,12 +47,7 @@ interface IDashCounters {
/** Wrapper container for dash counters. */
const DashCounters: React.FC<IDashCounters> = ({ children }) => (
<div className='⁂-dashboard__counters'>
{children}
</div>
<div className='⁂-dashboard__counters'>{children}</div>
);
export {
DashCounter,
DashCounters,
};
export { DashCounter, DashCounters };

View File

@ -14,13 +14,7 @@ interface IDimension {
params: AdminGetDimensionsParams;
}
const Dimension: React.FC<IDimension> = ({
dimension,
startAt,
endAt,
label,
params,
}) => {
const Dimension: React.FC<IDimension> = ({ dimension, startAt, endAt, label, params }) => {
const { data } = useDimensions([dimension], { ...params, start_at: startAt, end_at: endAt });
let content;
@ -31,37 +25,42 @@ const Dimension: React.FC<IDimension> = ({
<tbody>
{Array.from(Array(params.limit)).map((_, i) => (
<tr key={i}>
<td>
{/* <Skeleton width={100} /> */}
</td>
<td>{/* <Skeleton width={100} /> */}</td>
<td>
{/* <Skeleton width={60} /> */}
</td>
<td>{/* <Skeleton width={60} /> */}</td>
</tr>
))}
</tbody>
</table>
);
} else {
const sum = data[0].data.reduce((sum, cur) => sum + (+cur.value * 1), 0);
const sum = data[0].data.reduce((sum, cur) => sum + +cur.value * 1, 0);
content = (
<table className='w-full'>
<tbody>
{data[0].data.map(item => (
<tr className='border-b border-primary-200 last:border-none dark:border-gray-800' key={item.key}>
{data[0].data.map((item) => (
<tr
className='border-b border-primary-200 last:border-none dark:border-gray-800'
key={item.key}
>
<td className='p-2.5'>
<span
className='mr-2 inline-block size-2 rounded-full bg-green-500 shadow-sm'
style={{ opacity: +item.value / sum }}
/>
<Text title={item.key} weight='medium' size='xs' tag='span'>{item.human_key}</Text>
<Text title={item.key} weight='medium' size='xs' tag='span'>
{item.human_key}
</Text>
</td>
<td className='p-2.5 text-end'>
<Text size='xs'>
{typeof item.human_value !== 'undefined' ? item.human_value : <FormattedNumber value={+item.value} />}
{typeof item.human_value !== 'undefined' ? (
item.human_value
) : (
<FormattedNumber value={+item.value} />
)}
</Text>
</td>
</tr>
@ -74,7 +73,13 @@ const Dimension: React.FC<IDimension> = ({
return (
<div>
{label && (
<Text className='border-b border-primary-200 pb-1 dark:border-gray-800' weight='medium' size='sm'>{label}</Text>
<Text
className='border-b border-primary-200 pb-1 dark:border-gray-800'
weight='medium'
size='sm'
>
{label}
</Text>
)}
{content}

View File

@ -7,7 +7,10 @@ import AccountContainer from '@/containers/account-container';
import { useAdminAccounts } from '@/queries/admin/use-accounts';
const messages = defineMessages({
expand: { id: 'admin.latest_accounts_panel.more', defaultMessage: 'Click to see {count, plural, one {# account} other {# accounts}}' },
expand: {
id: 'admin.latest_accounts_panel.more',
defaultMessage: 'Click to see {count, plural, one {# account} other {# accounts}}',
},
});
interface ILatestAccountsPanel {
@ -32,7 +35,9 @@ const LatestAccountsPanel: React.FC<ILatestAccountsPanel> = ({ limit = 5 }) => {
return (
<Widget
title={<FormattedMessage id='admin.latest_accounts_panel.title' defaultMessage='Latest accounts' />}
title={
<FormattedMessage id='admin.latest_accounts_panel.title' defaultMessage='Latest accounts' />
}
onActionClick={handleAction}
actionTitle={intl.formatMessage(messages.expand, { count: total })}
>

View File

@ -16,16 +16,24 @@ const messages = defineMessages({
const generateConfig = (mode: RegistrationMode) => {
const configMap = {
open: [{ tuple: [':registrations_open', true] }, { tuple: [':account_approval_required', false] }],
approval: [{ tuple: [':registrations_open', true] }, { tuple: [':account_approval_required', true] }],
open: [
{ tuple: [':registrations_open', true] },
{ tuple: [':account_approval_required', false] },
],
approval: [
{ tuple: [':registrations_open', true] },
{ tuple: [':account_approval_required', true] },
],
closed: [{ tuple: [':registrations_open', false] }],
};
return [{
group: ':pleroma',
key: ':instance',
value: configMap[mode],
}];
return [
{
group: ':pleroma',
key: ':instance',
value: configMap[mode],
},
];
};
const modeFromInstance = ({ registrations }: Instance): RegistrationMode => {
@ -41,30 +49,62 @@ const RegistrationModePicker: React.FC = () => {
const mode = modeFromInstance(instance);
const onChange: React.ChangeEventHandler<HTMLInputElement> = e => {
const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
const config = generateConfig(e.target.value as RegistrationMode);
dispatch(updateConfig(config)).then(() => {
toast.success(intl.formatMessage(messages.saved));
}).catch(() => {});
dispatch(updateConfig(config))
.then(() => {
toast.success(intl.formatMessage(messages.saved));
})
.catch(() => {});
};
return (
<RadioGroup onChange={onChange}>
<RadioItem
label={<FormattedMessage id='admin.dashboard.registration_mode.open_label' defaultMessage='Open' />}
hint={<FormattedMessage id='admin.dashboard.registration_mode.open_hint' defaultMessage='Anyone can join.' />}
label={
<FormattedMessage
id='admin.dashboard.registration_mode.open_label'
defaultMessage='Open'
/>
}
hint={
<FormattedMessage
id='admin.dashboard.registration_mode.open_hint'
defaultMessage='Anyone can join.'
/>
}
checked={mode === 'open'}
value='open'
/>
<RadioItem
label={<FormattedMessage id='admin.dashboard.registration_mode.approval_label' defaultMessage='Approval Required' />}
hint={<FormattedMessage id='admin.dashboard.registration_mode.approval_hint' defaultMessage='Users can sign up, but their account only gets activated when an admin approves it.' />}
label={
<FormattedMessage
id='admin.dashboard.registration_mode.approval_label'
defaultMessage='Approval Required'
/>
}
hint={
<FormattedMessage
id='admin.dashboard.registration_mode.approval_hint'
defaultMessage='Users can sign up, but their account only gets activated when an admin approves it.'
/>
}
checked={mode === 'approval'}
value='approval'
/>
<RadioItem
label={<FormattedMessage id='admin.dashboard.registration_mode.closed_label' defaultMessage='Closed' />}
hint={<FormattedMessage id='admin.dashboard.registration_mode.closed_hint' defaultMessage='Nobody can sign up. You can still invite people.' />}
label={
<FormattedMessage
id='admin.dashboard.registration_mode.closed_label'
defaultMessage='Closed'
/>
}
hint={
<FormattedMessage
id='admin.dashboard.registration_mode.closed_hint'
defaultMessage='Nobody can sign up. You can still invite people.'
/>
}
checked={mode === 'closed'}
value='closed'
/>

View File

@ -35,7 +35,11 @@ const Report: React.FC<IReport> = ({ id }) => {
const reporterAcct = account?.acct;
return (
<Link to='/pl-fe/admin/reports/$reportId' params={{ reportId: id }} className='block rounded-lg bg-gray-100 p-4 dark:bg-primary-800'>
<Link
to='/pl-fe/admin/reports/$reportId'
params={{ reportId: id }}
className='block rounded-lg bg-gray-100 p-4 dark:bg-primary-800'
>
<Stack space={2} className='h-full justify-between'>
{targetAccount && (
<HoverAccountWrapper accountId={targetAccount.id} element='span'>
@ -62,10 +66,7 @@ const Report: React.FC<IReport> = ({ id }) => {
{!!account && (
<HStack space={1} alignItems='center' wrap>
<Text size='sm' theme='muted'>
<FormattedMessage
id='admin.reports.account'
defaultMessage='Reported by:'
/>
<FormattedMessage id='admin.reports.account' defaultMessage='Reported by:' />
</Text>
<HoverAccountWrapper accountId={account.id} element='span'>
<Link to='/pl-fe/admin/accounts/$accountId' params={{ accountId: account.id }}>
@ -78,10 +79,7 @@ const Report: React.FC<IReport> = ({ id }) => {
{!!report.comment && report.comment.length > 0 && (
<HStack space={1} alignItems='center' wrap>
<Text size='sm' theme='muted'>
<FormattedMessage
id='admin.reports.comment'
defaultMessage='Comment:'
/>
<FormattedMessage id='admin.reports.comment' defaultMessage='Comment:' />
</Text>
{report.comment}
</HStack>
@ -90,10 +88,7 @@ const Report: React.FC<IReport> = ({ id }) => {
{statusCount > 0 && (
<HStack space={1} alignItems='center' wrap>
<Text size='sm' theme='muted'>
<FormattedMessage
id='admin.reports.statuses'
defaultMessage='Reported posts:'
/>
<FormattedMessage id='admin.reports.statuses' defaultMessage='Reported posts:' />
</Text>
{statusCount}
</HStack>

View File

@ -12,7 +12,9 @@ const dateForCohort = (cohort: AdminCohort) => {
case 'day':
return <FormattedDate value={cohort.period} month='long' day='2-digit' timeZone={timeZone} />;
default:
return <FormattedDate value={cohort.period} month='long' year='numeric' timeZone={timeZone} />;
return (
<FormattedDate value={cohort.period} month='long' year='numeric' timeZone={timeZone} />
);
}
};
@ -36,21 +38,25 @@ const Retention: React.FC<IRetention> = ({ startAt, endAt, frequency }) => {
<tr>
<th>
<div className='p-2.5 pl-0 font-bold'>
<FormattedMessage id='admin.dashboard.retention.cohort' defaultMessage='Sign-up month' />
<FormattedMessage
id='admin.dashboard.retention.cohort'
defaultMessage='Sign-up month'
/>
</div>
</th>
<th>
<div className='p-2.5 font-bold'>
<FormattedMessage id='admin.dashboard.retention.cohort_size' defaultMessage='New users' />
<FormattedMessage
id='admin.dashboard.retention.cohort_size'
defaultMessage='New users'
/>
</div>
</th>
{data[0].data.slice(1).map((retention, i) => (
<th key={retention.date} className='w-14'>
<div className='p-2.5 font-bold'>
{i + 1}
</div>
<div className='p-2.5 font-bold'>{i + 1}</div>
</th>
))}
</tr>
@ -64,16 +70,29 @@ const Retention: React.FC<IRetention> = ({ startAt, endAt, frequency }) => {
<td>
<div className='p-2.5 text-center'>
<FormattedNumber value={data.reduce((sum, cohort, i) => sum + ((cohort.data[0].value * 1) - sum) / (i + 1), 0)} maximumFractionDigits={0} />
<FormattedNumber
value={data.reduce(
(sum, cohort, i) => sum + (cohort.data[0].value * 1 - sum) / (i + 1),
0,
)}
maximumFractionDigits={0}
/>
</div>
</td>
{data[0].data.slice(1).map((retention, i) => {
const average = data.reduce((sum, cohort, k) => cohort.data[i + 1] ? sum + (cohort.data[i + 1].rate - sum) / (k + 1) : sum, 0);
const average = data.reduce(
(sum, cohort, k) =>
cohort.data[i + 1] ? sum + (cohort.data[i + 1].rate - sum) / (k + 1) : sum,
0,
);
return (
<td key={retention.date}>
<div className='bg-primary-200 p-2.5 font-medium dark:bg-gray-800' style={{ ['--tw-bg-opacity' as any]: 0.5 + average / 2 }}>
<div
className='bg-primary-200 p-2.5 font-medium dark:bg-gray-800'
style={{ ['--tw-bg-opacity' as any]: 0.5 + average / 2 }}
>
<FormattedNumber value={average} style='percent' />
</div>
</td>
@ -83,12 +102,10 @@ const Retention: React.FC<IRetention> = ({ startAt, endAt, frequency }) => {
</thead>
<tbody>
{data.slice(0, -1).map(cohort => (
{data.slice(0, -1).map((cohort) => (
<tr key={cohort.period}>
<td>
<div className='p-2.5 pl-0'>
{dateForCohort(cohort)}
</div>
<div className='p-2.5 pl-0'>{dateForCohort(cohort)}</div>
</td>
<td>
@ -97,9 +114,12 @@ const Retention: React.FC<IRetention> = ({ startAt, endAt, frequency }) => {
</div>
</td>
{cohort.data.slice(1).map(retention => (
{cohort.data.slice(1).map((retention) => (
<td key={retention.date}>
<div className='bg-primary-200 p-2.5 font-medium dark:bg-gray-800' style={{ ['--tw-bg-opacity' as any]: 0.5 + retention.rate / 2 }}>
<div
className='bg-primary-200 p-2.5 font-medium dark:bg-gray-800'
style={{ ['--tw-bg-opacity' as any]: 0.5 + retention.rate / 2 }}
>
<FormattedNumber value={retention.rate} style='percent' />
</div>
</td>
@ -114,15 +134,31 @@ const Retention: React.FC<IRetention> = ({ startAt, endAt, frequency }) => {
let title = null;
switch (frequency) {
case 'day':
title = <FormattedMessage id='admin.dashboard.daily_retention' defaultMessage='User retention rate by day after sign-up' />;
title = (
<FormattedMessage
id='admin.dashboard.daily_retention'
defaultMessage='User retention rate by day after sign-up'
/>
);
break;
default:
title = <FormattedMessage id='admin.dashboard.monthly_retention' defaultMessage='User retention rate by month after sign-up' />;
title = (
<FormattedMessage
id='admin.dashboard.monthly_retention'
defaultMessage='User retention rate by month after sign-up'
/>
);
}
return (
<div className='col-span-2'>
<Text className='border-b border-primary-200 pb-1 dark:border-gray-800' weight='medium' size='sm'>{title}</Text>
<Text
className='border-b border-primary-200 pb-1 dark:border-gray-800'
weight='medium'
size='sm'
>
{title}
</Text>
{content}
</div>

View File

@ -4,7 +4,11 @@ import { AuthorizeRejectButtons } from '@/components/authorize-reject-buttons';
import HStack from '@/components/ui/hstack';
import Stack from '@/components/ui/stack';
import Text from '@/components/ui/text';
import { useAdminAccount, useAdminApproveAccountMutation, useAdminRejectAccountMutation } from '@/queries/admin/use-accounts';
import {
useAdminAccount,
useAdminApproveAccountMutation,
useAdminRejectAccountMutation,
} from '@/queries/admin/use-accounts';
interface IUnapprovedAccount {
accountId: string;
@ -24,9 +28,7 @@ const UnapprovedAccount: React.FC<IUnapprovedAccount> = ({ accountId }) => {
return (
<HStack space={4} justifyContent='between'>
<Stack space={1}>
<Text weight='semibold'>
@{account.acct}
</Text>
<Text weight='semibold'>@{account.acct}</Text>
<Text tag='blockquote' size='sm'>
{adminAccount?.invite_request ?? ''}
</Text>
@ -34,10 +36,10 @@ const UnapprovedAccount: React.FC<IUnapprovedAccount> = ({ accountId }) => {
<Stack justifyContent='center'>
<AuthorizeRejectButtons
onAuthorize={() =>{
onAuthorize={() => {
approveAccount();
}}
onReject={() =>{
onReject={() => {
rejectAccount();
}}
countdown={3000}