Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .oxlintrc.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,12 @@
"suspicious": "error",
"perf": "error",
},
"rules": {
"eslint/no-shadow": "off",
"react-perf/jsx-no-jsx-as-prop": "off",
"react-perf/jsx-no-new-object-as-prop": "off",
"react-perf/jsx-no-new-function-as-prop": "off",
"react-perf/jsx-no-new-array-as-prop": "off",
"unicorn/prefer-add-event-listener": "off",
},
}
1 change: 1 addition & 0 deletions apps/web/src/@types/i18next.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// oxlint-disable-next-line import/no-unassigned-import
import "i18next";
import type { resources, defaultNS } from "@abrechnung/translations";

Expand Down
1 change: 1 addition & 0 deletions apps/web/src/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LocalizationProvider } from "@mui/x-date-pickers";
import { AdapterLuxon } from "@mui/x-date-pickers/AdapterLuxon";
import * as React from "react";
import { ToastContainer } from "react-toastify";
// oxlint-disable-next-line import/no-unassigned-import
import "react-toastify/dist/ReactToastify.css";
import { Loading } from "@abrechnung/components";
import { api } from "../core/api";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,7 @@ export const AuthenticatedLayout: React.FC = () => {
</Box>
<Box
component="main"
flexGrow={1}
width={{ sm: `calc(100vw - ${drawerWidth}px)`, md: "100vw", overflow: "auto" }}
sx={{ flexGrow: 1, width: { sm: `calc(100vw - ${drawerWidth}px)`, md: "100vw", overflow: "auto" } }}
>
<Toolbar />
<Banner />
Expand Down
30 changes: 16 additions & 14 deletions apps/web/src/components/ShareSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ const ShareSelectRow: React.FC<RowProps> = ({
}}
to={getAccountLink(account.group_id, account.type, account.id)}
>
<Grid container direction="row" alignItems="center">
<Grid container direction="row" sx={{ alignItems: "center" }}>
<Grid>{getAccountIcon(account.type)}</Grid>
<Grid display="flex" flexDirection="column" sx={{ ml: 1 }}>
<Grid sx={{ display: "flex", flexDirection: "column", ml: 1 }}>
<Typography variant="body2" component="span">
{account.name}
</Typography>
Expand Down Expand Up @@ -239,22 +239,22 @@ export const ShareSelect: React.FC<ShareSelectProps> = ({
}
return true;
})
.sort(sortFn);
}, [value, showEvents, editable, searchValue, unfilteredAccounts, shouldDisplayAccount]);
.toSorted(sortFn);
}, [value, showEvents, editable, searchValue, unfilteredAccounts, shouldDisplayAccount, hideShowEventsFilter]);

React.useEffect(() => {
// set displayed split mode to evenly if we have a "shares" split with non-even shares
if (
splitMode === "shares" &&
Object.values(value).reduce((onlyDefaultShares, value) => onlyDefaultShares && value === 1, true) &&
Object.values(value).reduce((onlyDefaultShares, val) => onlyDefaultShares && val === 1, true) &&
(communistShares == null || communistShares === 1 || communistShares === 0)
) {
setFrontendSplitMode("evenly");
}
}, [splitMode, value, setFrontendSplitMode]);
}, [splitMode, value, setFrontendSplitMode, communistShares]);

const { nSelectedPeople, nSelectedEvents } = React.useMemo(() => {
const nSelectedPeople = accounts.reduce((nAccs: number, acc: Account) => {
const selectedPeople = accounts.reduce((nAccs: number, acc: Account) => {
if (acc.type !== "personal") {
return nAccs;
}
Expand All @@ -263,7 +263,7 @@ export const ShareSelect: React.FC<ShareSelectProps> = ({
}
return nAccs;
}, 0);
const nSelectedEvents = accounts.reduce((nAccs: number, acc: Account) => {
const selectedEvents = accounts.reduce((nAccs: number, acc: Account) => {
if (acc.type !== "clearing") {
return nAccs;
}
Expand All @@ -273,11 +273,11 @@ export const ShareSelect: React.FC<ShareSelectProps> = ({
return nAccs;
}, 0);

return { nSelectedPeople, nSelectedEvents };
}, [unfilteredAccounts, value, shouldDisplayAccount]);
return { nSelectedPeople: selectedPeople, nSelectedEvents: selectedEvents };
}, [value, accounts]);

const nSelected = React.useMemo(() => {
return Object.values(value).reduce((nSelected, val) => nSelected + (val > 0 ? 1 : 0), 0);
return Object.values(value).reduce((selected, val) => selected + (val > 0 ? 1 : 0), 0);
}, [value]);
const isAllSelected = nSelected === accounts.length;
const showSearch = !isSmallScreen && unfilteredAccounts.length > 5;
Expand Down Expand Up @@ -307,7 +307,7 @@ export const ShareSelect: React.FC<ShareSelectProps> = ({

return (
<div>
<Grid container direction={isSmallScreen ? "column" : "row"} justifyContent="space-between">
<Stack direction={isSmallScreen ? "column" : "row"} sx={{ justifyContent: "space-between" }}>
<Stack direction="row" spacing={1} sx={{ alignItems: "center", marginY: 1 }}>
<Typography variant="subtitle1">{label}</Typography>
{nSelectedPeople > 0 && (
Expand Down Expand Up @@ -351,12 +351,14 @@ export const ShareSelect: React.FC<ShareSelectProps> = ({
select
>
{allowedSplitModes.map((mode) => (
<MenuItem value={mode}>{t(`shareSelect.split_${mode}`)}</MenuItem>
<MenuItem key={mode} value={mode}>
{t(`shareSelect.split_${mode}`)}
</MenuItem>
))}
</TextField>
</Stack>
)}
</Grid>
</Stack>
{communistShares != null &&
(frontendSplitMode === "evenly" ? (
<FormControlLabel
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/components/style/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useConfig } from "@/core/config";
export const Banner: React.FC = () => {
const cfg = useConfig();
return cfg.messages?.map((message, idx) => (
// oxlint-disable-next-line react/no-array-index-key
<Alert key={idx} sx={{ borderRadius: 0 }} color={message.type}>
{message.title && <AlertTitle>{message.title}</AlertTitle>}
{message.body}
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/components/transactions/TransactionIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PurchaseIcon, TransferIcon } from "@/components/style/AbrechnungIcons";
import { Tooltip } from "@mui/material";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { HelpOutline } from "@mui/icons-material";
import { HelpOutlined } from "@mui/icons-material";

export const TransactionIcon: React.FC<{ type: TransactionType }> = ({ type }) => {
const { t } = useTranslation();
Expand All @@ -25,7 +25,7 @@ export const TransactionIcon: React.FC<{ type: TransactionType }> = ({ type }) =

return (
<Tooltip title="Unknown Transaction Type">
<HelpOutline color="primary" />
<HelpOutlined color="primary" />
</Tooltip>
);
};
1 change: 1 addition & 0 deletions apps/web/src/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import { resources, defaultNS } from "@abrechnung/translations";

// oxlint-disable-next-line import/no-named-as-default-member
i18n.use(LanguageDetector)
.use(initReactI18next)
.init({
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { App } from "./app/app";
import { Loading } from "@abrechnung/components";
// oxlint-disable-next-line import/no-unassigned-import
import "./i18n";
import { persistor, store } from "./store";
import { ConfigProvider } from "./core/config";
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/pages/accounts/AccountDetail/AccountInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ export const AccountInfo: React.FC<Props> = ({ groupId, account }) => {

return (
<>
<Grid container justifyContent="space-between">
<Grid display="flex" alignItems="center">
<Grid container sx={{ justifyContent: "space-between" }}>
<Grid sx={{ display: "flex", alignItems: "center" }}>
<IconButton sx={{ display: { xs: "none", md: "inline-flex" } }} onClick={navigateBack}>
<ChevronLeft />
</IconButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const AccountTransactionList: React.FC<Props> = ({ groupId, account }) =>

const combinedList: ArrayAccountsAndTransactions = (transactions as ArrayAccountsAndTransactions)
.concat(clearingAccounts)
.sort((f1, f2) => DateTime.fromISO(getDate(f2)).toMillis() - DateTime.fromISO(getDate(f1)).toMillis());
.toSorted((f1, f2) => DateTime.fromISO(getDate(f2)).toMillis() - DateTime.fromISO(getDate(f1)).toMillis());

const createTransactionForAccount = (type: TransactionType) => {
dispatch(
Expand All @@ -62,9 +62,9 @@ export const AccountTransactionList: React.FC<Props> = ({ groupId, account }) =>

return (
<>
<Box display="grid" gridTemplateColumns="auto min-content" justifyContent="space-between">
<Box sx={{ display: "grid", gridTemplateColumns: "auto min-content", justifyContent: "space-between" }}>
<Typography variant="h6">{t("accounts.transactionsInvolving", "", { account })}</Typography>
<Box display="flex" flexDirection="row" alignItems="center">
<Box sx={{ display: "flex", flexDirection: "row", alignItems: "center" }}>
<Tooltip
title={t("transactions.createPurchaseForAccount", "", {
accountName: account.name,
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/pages/accounts/Balances/BalanceBarGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ type Data = {
isYou: boolean;
};

const roundTwoDecimals = (val: number) => +val.toFixed(2);

export const BalanceBarGraph: React.FC<BalanceBarGraphProps> = ({ group }) => {
const { t } = useTranslation();
const theme: Theme = useTheme();
Expand All @@ -34,8 +36,6 @@ export const BalanceBarGraph: React.FC<BalanceBarGraphProps> = ({ group }) => {
const colorGreen = theme.palette.mode === "light" ? theme.palette.success.light : theme.palette.success.dark;
const colorRed = theme.palette.mode === "light" ? theme.palette.error.light : theme.palette.error.dark;

const roundTwoDecimals = (val: number) => +val.toFixed(2);

const chartData: Data[] = personalAccounts.map((account) => {
const balance = balances[account.id];
return {
Expand Down Expand Up @@ -65,6 +65,7 @@ export const BalanceBarGraph: React.FC<BalanceBarGraphProps> = ({ group }) => {

return (
<Box
// oxlint-disable-next-line react/no-array-index-key
key={index}
sx={{
display: "grid",
Expand Down
8 changes: 4 additions & 4 deletions apps/web/src/pages/accounts/Balances/Statistics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const Statistics: React.FC<StatisticsProps> = ({ group }) => {
(totalSpendings, balance) => totalSpendings + balance.totalConsumedPurchases,
0
);
}, []);
}, [balances]);

return (
<Stack direction="column" spacing={1}>
Expand All @@ -33,7 +33,7 @@ export const Statistics: React.FC<StatisticsProps> = ({ group }) => {
{t("accounts.balances.totalGroupExpenses")}
<Help title={t("accounts.balances.totalGroupExpensesHelp")} />
</Typography>
<Typography fontSize={20}>
<Typography sx={{ fontSize: 20 }}>
<CurrencyDisplay amount={totalSpendings} currencyIdentifier={group.currency_identifier} />
</Typography>
</Box>
Expand All @@ -45,7 +45,7 @@ export const Statistics: React.FC<StatisticsProps> = ({ group }) => {
{t("accounts.balances.yourTotalDisbursements")}
<Help title={t("accounts.balances.yourTotalDisbursementsHelp")} />
</Typography>
<Typography fontSize={20}>
<Typography sx={{ fontSize: 20 }}>
<CurrencyDisplay
amount={personalBalance.totalPaidPurchases}
currencyIdentifier={group.currency_identifier}
Expand All @@ -58,7 +58,7 @@ export const Statistics: React.FC<StatisticsProps> = ({ group }) => {
{t("accounts.balances.yourTotalExpenses")}
<Help title={t("accounts.balances.yourTotalExpensesHelp")} />
</Typography>
<Typography fontSize={20}>
<Typography sx={{ fontSize: 20 }}>
<CurrencyDisplay
amount={personalBalance.totalConsumedPurchases}
currencyIdentifier={group.currency_identifier}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,13 @@ export const ClearingAccountList: React.FC<Props> = ({ groupId }) => {
<GroupArchivedDisclaimer group={group} />
<Stack
direction={{ sm: "column", md: "row" }}
alignItems={{ md: "flex-end" }}
justifyContent="space-between"
sx={{ alignItems: { md: "flex-end" }, justifyContent: "space-between" }}
>
<Stack direction={{ sm: "column", md: "row" }} justifyContent="space-between" spacing={1}>
<Stack
direction={{ sm: "column", md: "row" }}
sx={{ justifyContent: "space-between" }}
spacing={1}
>
<Input
value={searchValue}
onChange={(e) => updateFilterState({ searchValue: e.target.value })}
Expand Down Expand Up @@ -191,7 +194,7 @@ export const ClearingAccountList: React.FC<Props> = ({ groupId }) => {
{shouldShowPagination && (
<>
<Divider />
<Box justifyContent="center" display="flex">
<Box sx={{ justifyContent: "center", display: "flex" }}>
<Pagination
count={numPages}
page={currentPage + 1}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,13 @@ export const PersonalAccountList: React.FC<Props> = ({ groupId }) => {
<GroupArchivedDisclaimer group={group} />
<Stack
direction={{ sm: "column", md: "row" }}
alignItems={{ md: "flex-end" }}
justifyContent="space-between"
sx={{ alignItems: { md: "flex-end" }, justifyContent: "space-between" }}
>
<Stack direction={{ sm: "column", md: "row" }} justifyContent="space-between" spacing={1}>
<Stack
direction={{ sm: "column", md: "row" }}
sx={{ justifyContent: "space-between" }}
spacing={1}
>
<Input
value={searchValue}
onChange={(e) => updateFilterState({ searchValue: e.target.value })}
Expand Down Expand Up @@ -170,7 +173,7 @@ export const PersonalAccountList: React.FC<Props> = ({ groupId }) => {
{shouldShowPagination && (
<>
<Divider />
<Box justifyContent="center" display="flex">
<Box sx={{ justifyContent: "center", display: "flex" }}>
<Pagination
count={numPages}
page={currentPage + 1}
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/pages/auth/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const Login: React.FC = () => {
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<Box display="flex" flexDirection="column" alignItems="center">
<Box sx={{ display: "flex", flexDirection: "column", alignItems: "center" }}>
<Avatar sx={{ margin: 1, backgroundColor: "primary.main" }}>
<LockOutlined />
</Avatar>
Expand Down Expand Up @@ -94,14 +94,14 @@ export const Login: React.FC = () => {
<Button type="submit" fullWidth variant="contained" color="primary" sx={{ mt: 1 }}>
{t("auth.login.confirmButton")}
</Button>
<Grid container justifyContent="flex-end">
<Grid container sx={{ justifyContent: "flex-end" }}>
<Grid>
<Link to={`/register${queryArgsForward}`} component={RouterLink} variant="body2">
{t("auth.login.noAccountRegister")}
</Link>
</Grid>
</Grid>
<Grid container justifyContent="flex-end">
<Grid container sx={{ justifyContent: "flex-end" }}>
<Grid>
<Link to="/recover-password" component={RouterLink} variant="body2">
{t("auth.login.forgotPassword")}
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/pages/auth/Register.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export const Register: React.FC = () => {
<Button type="submit" fullWidth variant="contained" color="primary" sx={{ mt: 1 }}>
{t("auth.register.confirmButton")}
</Button>
<Grid container justifyContent="flex-end">
<Grid container sx={{ justifyContent: "flex-end" }}>
<Grid>
<Link to={`/login${queryArgsForward}`} component={RouterLink} variant="body2">
{t("auth.register.alreadyHasAccount")}
Expand Down
2 changes: 0 additions & 2 deletions apps/web/src/pages/groups/Group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import {
fetchGroupDependencies,
selectGroupAccountsStatus,
selectGroupTransactionsStatus,
setAccountStatus,
setTransactionStatus,
useGroup,
} from "@abrechnung/redux";
import React, { Suspense } from "react";
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/pages/groups/GroupActivity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ export const GroupActivity: React.FC<Props> = ({ groupId }) => {
useTitle(t("groups.log.tabTitle", { groupName: group?.name }));

const getMemberUsername = (member_id: number) => {
const member = members?.find((member) => member.user_id === member_id);
if (member === undefined) {
const foundMember = members?.find((member) => member.user_id === member_id);
if (foundMember === undefined) {
return "unknown";
}
return member.username;
return foundMember.username;
};

return (
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/pages/groups/GroupInvite.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const GroupInvite: React.FC = () => {
setError(stringifyError(err));
setGroup(null);
});
}, [setGroup, setError, inviteToken]);
}, [setGroup, setError, inviteToken, navigate]);

const join = () => {
if (!inviteToken) {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/pages/groups/GroupList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const GroupList: React.FC = () => {
<GList groups={groups} />
{!isGuest && (
<>
<Grid container justifyContent="center">
<Grid container sx={{ justifyContent: "center" }}>
<IconButton color="primary" onClick={openGroupCreateModal}>
<Add />
</IconButton>
Expand Down
Loading
Loading