1
0
Fork 0
mirror of https://git.sr.ht/~ashkeel/strimertul synced 2024-09-18 01:50:50 +00:00

refactor: fix code smells

This commit is contained in:
Ash Keel 2023-05-03 18:20:52 +02:00
parent bc6c76c581
commit 4eac451432
No known key found for this signature in database
GPG key ID: BAD8D93E7314ED3E
7 changed files with 104 additions and 68 deletions

View file

@ -39,8 +39,10 @@ function log(level: string) {
} }
function start() { function start() {
if (!extFn || !kv || extensionStatus !== ExtensionStatus.Ready) if (!extFn || !kv || extensionStatus !== ExtensionStatus.Ready) {
throw new Error('extension not ready'); throw new Error('extension not ready');
}
void extFn(kv) void extFn(kv)
.then(() => { .then(() => {
setStatus(ExtensionStatus.Finished); setStatus(ExtensionStatus.Finished);
@ -51,6 +53,7 @@ function start() {
error, error,
}); });
}); });
setStatus(ExtensionStatus.Running); setStatus(ExtensionStatus.Running);
} }

View file

@ -178,7 +178,9 @@ function RecoveryDialog({ open, onOpenChange }: RecoveryDialogProps) {
defaultOpen={true} defaultOpen={true}
open={open} open={open}
onOpenChange={(state) => { onOpenChange={(state) => {
if (onOpenChange) onOpenChange(state); if (onOpenChange) {
onOpenChange(state);
}
setRestored('idle'); setRestored('idle');
}} }}
> >
@ -188,7 +190,9 @@ function RecoveryDialog({ open, onOpenChange }: RecoveryDialogProps) {
description={t('pages.crash.recovery.restore-succeeded-body')} description={t('pages.crash.recovery.restore-succeeded-body')}
actionText={t('form-actions.ok')} actionText={t('form-actions.ok')}
onAction={() => { onAction={() => {
if (onOpenChange) onOpenChange(false); if (onOpenChange) {
onOpenChange(false);
}
setRestored('idle'); setRestored('idle');
}} }}
/> />
@ -202,7 +206,9 @@ function RecoveryDialog({ open, onOpenChange }: RecoveryDialogProps) {
defaultOpen={false} defaultOpen={false}
open={!!restoreError} open={!!restoreError}
onOpenChange={(val: boolean) => { onOpenChange={(val: boolean) => {
if (!val) setRestoreError(null); if (!val) {
setRestoreError(null);
}
}} }}
> >
<AlertContent <AlertContent
@ -220,7 +226,9 @@ function RecoveryDialog({ open, onOpenChange }: RecoveryDialogProps) {
<Dialog <Dialog
open={open} open={open}
onOpenChange={(state) => { onOpenChange={(state) => {
if (onOpenChange) onOpenChange(state); if (onOpenChange) {
onOpenChange(state);
}
}} }}
> >
<DialogContent <DialogContent
@ -315,7 +323,9 @@ function ReportDialog({ open, onOpenChange, errorData }: ReportDialogProps) {
<Alert <Alert
open={open} open={open}
onOpenChange={(state) => { onOpenChange={(state) => {
if (onOpenChange) onOpenChange(state); if (onOpenChange) {
onOpenChange(state);
}
}} }}
> >
<AlertContent <AlertContent
@ -353,7 +363,9 @@ function ReportDialog({ open, onOpenChange, errorData }: ReportDialogProps) {
defaultOpen={false} defaultOpen={false}
open={!!submissionError} open={!!submissionError}
onOpenChange={(val: boolean) => { onOpenChange={(val: boolean) => {
if (!val) setSubmissionError(null); if (!val) {
setSubmissionError(null);
}
}} }}
> >
<AlertContent <AlertContent
@ -370,7 +382,9 @@ function ReportDialog({ open, onOpenChange, errorData }: ReportDialogProps) {
<Dialog <Dialog
open={open} open={open}
onOpenChange={(state) => { onOpenChange={(state) => {
if (onOpenChange) onOpenChange(state); if (onOpenChange) {
onOpenChange(state);
}
}} }}
> >
<DialogContent <DialogContent

View file

@ -1,5 +1,5 @@
import { ChevronDownIcon, ChevronUpIcon } from '@radix-ui/react-icons'; import { ChevronDownIcon, ChevronUpIcon } from '@radix-ui/react-icons';
import React, { useState } from 'react'; import React, { ReactElement, useState } from 'react';
import { SortFunction } from '~/lib/types'; import { SortFunction } from '~/lib/types';
import { styled } from '../theme'; import { styled } from '../theme';
import { Table, TableHeader } from '../theme/table'; import { Table, TableHeader } from '../theme/table';
@ -26,7 +26,7 @@ export interface DataTableProps<T> {
} }
))[]; ))[];
defaultSort: SortingOrder<T>; defaultSort: SortingOrder<T>;
view: (data: T) => React.ReactNode; rowComponent: (data: { data: T }) => ReactElement;
sort: (key: keyof T) => SortFunction<T>; sort: (key: keyof T) => SortFunction<T>;
} }
@ -45,7 +45,7 @@ export function DataTable<T>({
columns, columns,
defaultSort, defaultSort,
sort, sort,
view, rowComponent,
}: DataTableProps<T>): React.ReactElement { }: DataTableProps<T>): React.ReactElement {
const [entriesPerPage, setEntriesPerPage] = useState(15); const [entriesPerPage, setEntriesPerPage] = useState(15);
const [page, setPage] = useState(0); const [page, setPage] = useState(0);
@ -83,6 +83,8 @@ export function DataTable<T>({
const paged = sortedEntries.slice(offset, offset + entriesPerPage); const paged = sortedEntries.slice(offset, offset + entriesPerPage);
const totalPages = Math.floor(sortedEntries.length / entriesPerPage); const totalPages = Math.floor(sortedEntries.length / entriesPerPage);
const RowComponent = rowComponent;
return ( return (
<> <>
<PageList <PageList
@ -115,7 +117,11 @@ export function DataTable<T>({
))} ))}
</tr> </tr>
</thead> </thead>
<tbody>{paged.map(view)}</tbody> <tbody>
{paged.map((entry) => (
<RowComponent data={entry} />
))}
</tbody>
</Table> </Table>
<PageList <PageList
current={page + 1} current={page + 1}

View file

@ -277,7 +277,7 @@ export function LogItem({ data, expandDefault }: LogItemProps) {
{details.length > 0 && showDetails ? ( {details.length > 0 && showDetails ? (
<LogDetails level={levelStyle}> <LogDetails level={levelStyle}>
{details.map(([key, value]) => ( {details.map(([key, value]) => (
<LogDetailItem> <LogDetailItem key={key}>
<LogDetailKey level={levelStyle}>{key}</LogDetailKey> <LogDetailKey level={levelStyle}>{key}</LogDetailKey>
<LogDetailValue>{JSON.stringify(value)}</LogDetailValue> <LogDetailValue>{JSON.stringify(value)}</LogDetailValue>
</LogDetailItem> </LogDetailItem>

View file

@ -16,7 +16,9 @@ const ControlledInput = (
useEffect(() => { useEffect(() => {
const input = ref.current; const input = ref.current;
if (input) input.setSelectionRange(cursor, cursor); if (input) {
input.setSelectionRange(cursor, cursor);
}
}, [ref, cursor, value]); }, [ref, cursor, value]);
return ( return (
@ -25,7 +27,9 @@ const ControlledInput = (
value={value} value={value}
onChange={(e) => { onChange={(e) => {
setCursor(e.target.selectionStart); setCursor(e.target.selectionStart);
if (onChange) onChange(e); if (onChange) {
onChange(e);
}
}} }}
{...rest} {...rest}
/> />

View file

@ -4,6 +4,7 @@ import { useModule, useUserPoints } from '~/lib/react';
import { SortFunction } from '~/lib/types'; import { SortFunction } from '~/lib/types';
import { useAppDispatch } from '~/store'; import { useAppDispatch } from '~/store';
import { modules, removeRedeem, setUserPoints } from '~/store/api/reducer'; import { modules, removeRedeem, setUserPoints } from '~/store/api/reducer';
import { LoyaltyRedeem } from '~/store/api/types';
import { DataTable } from '../components/DataTable'; import { DataTable } from '../components/DataTable';
import DialogContent from '../components/DialogContent'; import DialogContent from '../components/DialogContent';
import { import {
@ -26,10 +27,54 @@ import {
} from '../theme'; } from '../theme';
import { TableCell, TableRow } from '../theme/table'; import { TableCell, TableRow } from '../theme/table';
function RewardQueueRow({ data }: { data: LoyaltyRedeem & { date: Date } }) {
const dispatch = useAppDispatch();
const { t } = useTranslation();
return (
<TableRow key={`${data.when.toString()}${data.username}`}>
<TableCell css={{ width: '22%', fontSize: '0.8rem' }}>
{data.date.toLocaleString()}
</TableCell>
<TableCell css={{ width: '10%' }}>{data.username}</TableCell>
<TableCell css={{ width: '18%' }}>{data.reward?.name}</TableCell>
<TableCell css={{ width: '40%' }}>{data.request_text}</TableCell>
<TableCell>
<FlexRow spacing="1">
<Button
size="small"
onClick={() => {
void dispatch(removeRedeem(data));
}}
>
{t('pages.loyalty-queue.accept')}
</Button>
<Button
size="small"
onClick={() => {
// Give points back to the viewer
void dispatch(
setUserPoints({
user: data.username,
points: data.reward.price,
relative: true,
}),
);
// Take the redeem off the list
void dispatch(removeRedeem(data));
}}
>
{t('pages.loyalty-queue.refund')}
</Button>
</FlexRow>
</TableCell>
</TableRow>
);
}
function RewardQueue() { function RewardQueue() {
const { t } = useTranslation(); const { t } = useTranslation();
const [queue] = useModule(modules.loyaltyRedeemQueue); const [queue] = useModule(modules.loyaltyRedeemQueue);
const dispatch = useAppDispatch();
// Big hack but this is required or refunds break // Big hack but this is required or refunds break
useUserPoints(); useUserPoints();
@ -98,45 +143,7 @@ function RewardQueue() {
}, },
]} ]}
defaultSort={{ key: 'when', order: 'desc' }} defaultSort={{ key: 'when', order: 'desc' }}
view={(entry) => ( rowComponent={RewardQueueRow}
<TableRow key={`${entry.when.toString()}${entry.username}`}>
<TableCell css={{ width: '22%', fontSize: '0.8rem' }}>
{entry.date.toLocaleString()}
</TableCell>
<TableCell css={{ width: '10%' }}>{entry.username}</TableCell>
<TableCell css={{ width: '18%' }}>{entry.reward?.name}</TableCell>
<TableCell css={{ width: '40%' }}>{entry.request_text}</TableCell>
<TableCell>
<FlexRow spacing="1">
<Button
size="small"
onClick={() => {
void dispatch(removeRedeem(entry));
}}
>
{t('pages.loyalty-queue.accept')}
</Button>
<Button
size="small"
onClick={() => {
// Give points back to the viewer
void dispatch(
setUserPoints({
user: entry.username,
points: entry.reward.price,
relative: true,
}),
);
// Take the redeem off the list
void dispatch(removeRedeem(entry));
}}
>
{t('pages.loyalty-queue.refund')}
</Button>
</FlexRow>
</TableCell>
</TableRow>
)}
/> />
)) || <NoneText>{t('pages.loyalty-queue.no-redeems')}</NoneText>} )) || <NoneText>{t('pages.loyalty-queue.no-redeems')}</NoneText>}
</> </>
@ -175,6 +182,18 @@ function UserList() {
} }
}; };
const UserListRow = ({ data }: { data: UserEntry }) => (
<TableRow key={data.username}>
<TableCell css={{ width: '100%' }}>{data.username}</TableCell>
<TableCell>{data.points}</TableCell>
<TableCell>
<Button onClick={() => setCurrentEntry(data)} size="small">
{t('form-actions.edit')}
</Button>
</TableCell>
</TableRow>
);
return ( return (
<> <>
<Dialog <Dialog
@ -360,17 +379,7 @@ function UserList() {
}, },
]} ]}
defaultSort={{ key: 'points', order: 'desc' }} defaultSort={{ key: 'points', order: 'desc' }}
view={(entry) => ( rowComponent={UserListRow}
<TableRow key={entry.username}>
<TableCell css={{ width: '100%' }}>{entry.username}</TableCell>
<TableCell>{entry.points}</TableCell>
<TableCell>
<Button onClick={() => setCurrentEntry(entry)} size="small">
{t('form-actions.edit')}
</Button>
</TableCell>
</TableRow>
)}
/> />
)) || <NoneText>{t('pages.loyalty-queue.no-users')}</NoneText>} )) || <NoneText>{t('pages.loyalty-queue.no-users')}</NoneText>}
</> </>

View file

@ -361,7 +361,7 @@ function RewardsPage() {
id: id:
e.target.value e.target.value
?.toLowerCase() ?.toLowerCase()
.replace(/[^a-zA-Z0-9]/gi, '-') ?? '', .replace(/[^a-z0-9]/gi, '-') ?? '',
}, },
}); });
if ( if (
@ -685,7 +685,7 @@ function GoalsPage() {
id: id:
e.target.value e.target.value
?.toLowerCase() ?.toLowerCase()
.replace(/[^a-zA-Z0-9]/gi, '-') ?? '', .replace(/[^a-z0-9]/gi, '-') ?? '',
}, },
}); });
if ( if (