Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
caeff985c2 | |||
bed538793d | |||
602f20ad18 | |||
457c96b37e | |||
a3f2b77548 |
@ -7,13 +7,13 @@ edition = "2024"
|
|||||||
env_logger = "0.11.8"
|
env_logger = "0.11.8"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
diesel = { version = "2.2.10", features = ["postgres", "r2d2"] }
|
diesel = { version = "2.2.10", features = ["postgres", "r2d2"] }
|
||||||
diesel_migrations = "2.1.0"
|
diesel_migrations = "2.2.0"
|
||||||
clap = { version = "4.5.38", features = ["env", "derive"] }
|
clap = { version = "4.5.38", features = ["env", "derive"] }
|
||||||
actix-web = "4.11.0"
|
actix-web = "4.11.0"
|
||||||
actix-cors = "0.7.1"
|
actix-cors = "0.7.1"
|
||||||
actix-multipart = "0.7.2"
|
actix-multipart = "0.7.2"
|
||||||
actix-remote-ip = "0.1.0"
|
actix-remote-ip = "0.1.0"
|
||||||
actix-session = { version = "0.10.0", features = ["redis-session"] }
|
actix-session = { version = "0.10.1", features = ["redis-session"] }
|
||||||
actix-files = "0.6.6"
|
actix-files = "0.6.6"
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
|
@ -78,12 +78,15 @@ pub async fn finances_manager_import(auth: AuthExtractor, file: FileExtractor) -
|
|||||||
|
|
||||||
/// Export data to a [FinancesManager](https://gitlab.com/pierre42100/cpp-financesmanager) file
|
/// Export data to a [FinancesManager](https://gitlab.com/pierre42100/cpp-financesmanager) file
|
||||||
pub async fn finances_manager_export(auth: AuthExtractor) -> HttpResult {
|
pub async fn finances_manager_export(auth: AuthExtractor) -> HttpResult {
|
||||||
let accounts = accounts_service::get_list_user(auth.user_id()).await?;
|
let mut accounts = accounts_service::get_list_user(auth.user_id()).await?;
|
||||||
|
accounts.sort_by_key(|a| a.id());
|
||||||
|
|
||||||
let mut out = FinancesManagerFile { accounts: vec![] };
|
let mut out = FinancesManagerFile { accounts: vec![] };
|
||||||
|
|
||||||
for account in accounts {
|
for account in accounts {
|
||||||
let movements = movements_service::get_list_account(account.id()).await?;
|
let mut movements = movements_service::get_list_account(account.id()).await?;
|
||||||
|
movements.sort_by(|a, b| b.time.cmp(&a.time));
|
||||||
|
|
||||||
let mut file_account = FinancesManagerAccount {
|
let mut file_account = FinancesManagerAccount {
|
||||||
name: account.name,
|
name: account.name,
|
||||||
movements: Vec::with_capacity(movements.len()),
|
movements: Vec::with_capacity(movements.len()),
|
||||||
|
2
moneymgr_web/package-lock.json
generated
2
moneymgr_web/package-lock.json
generated
@ -36,7 +36,7 @@
|
|||||||
"@vitejs/plugin-react": "^4.4.1",
|
"@vitejs/plugin-react": "^4.4.1",
|
||||||
"eslint": "^9.26.0",
|
"eslint": "^9.26.0",
|
||||||
"eslint-plugin-react-dom": "^1.49.0",
|
"eslint-plugin-react-dom": "^1.49.0",
|
||||||
"eslint-plugin-react-hooks": "^5.1.0",
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
"eslint-plugin-react-refresh": "^00.4.20",
|
"eslint-plugin-react-refresh": "^00.4.20",
|
||||||
"eslint-plugin-react-x": "^1.49.0",
|
"eslint-plugin-react-x": "^1.49.0",
|
||||||
"globals": "^16.1.0",
|
"globals": "^16.1.0",
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
"@vitejs/plugin-react": "^4.4.1",
|
"@vitejs/plugin-react": "^4.4.1",
|
||||||
"eslint": "^9.26.0",
|
"eslint": "^9.26.0",
|
||||||
"eslint-plugin-react-dom": "^1.49.0",
|
"eslint-plugin-react-dom": "^1.49.0",
|
||||||
"eslint-plugin-react-hooks": "^5.1.0",
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
"eslint-plugin-react-refresh": "^00.4.20",
|
"eslint-plugin-react-refresh": "^00.4.20",
|
||||||
"eslint-plugin-react-x": "^1.49.0",
|
"eslint-plugin-react-x": "^1.49.0",
|
||||||
"globals": "^16.1.0",
|
"globals": "^16.1.0",
|
||||||
|
@ -121,13 +121,15 @@ function MovementsTable(p: {
|
|||||||
|
|
||||||
const chooseAccount = useSelectAccount();
|
const chooseAccount = useSelectAccount();
|
||||||
|
|
||||||
const [labelFilter, setLabelFilter] = React.useState("");
|
const [filter, setFilter] = React.useState("");
|
||||||
|
|
||||||
const filteredList = React.useMemo(() => {
|
const filteredList = React.useMemo(() => {
|
||||||
return p.movements.filter((m) =>
|
return p.movements.filter(
|
||||||
m.label.toLowerCase().includes(labelFilter.toLowerCase())
|
(m) =>
|
||||||
|
m.label.toLowerCase().includes(filter.toLowerCase()) ||
|
||||||
|
m.amount.toString().includes(filter)
|
||||||
);
|
);
|
||||||
}, [p.movements, labelFilter]);
|
}, [p.movements, filter]);
|
||||||
|
|
||||||
const [rowSelectionModel, setRowSelectionModel] =
|
const [rowSelectionModel, setRowSelectionModel] =
|
||||||
React.useState<GridRowSelectionModel>({ type: "include", ids: new Set() });
|
React.useState<GridRowSelectionModel>({ type: "include", ids: new Set() });
|
||||||
@ -382,12 +384,12 @@ function MovementsTable(p: {
|
|||||||
<>
|
<>
|
||||||
<div style={{ display: "flex" }}>
|
<div style={{ display: "flex" }}>
|
||||||
<TextField
|
<TextField
|
||||||
placeholder="Filter by label"
|
placeholder="Filter by label or amount"
|
||||||
variant="standard"
|
variant="standard"
|
||||||
size="small"
|
size="small"
|
||||||
value={labelFilter}
|
value={filter}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setLabelFilter(e.target.value);
|
setFilter(e.target.value);
|
||||||
}}
|
}}
|
||||||
style={{ padding: "0px", flex: 1 }}
|
style={{ padding: "0px", flex: 1 }}
|
||||||
/>
|
/>
|
||||||
|
@ -158,7 +158,7 @@ function ImportExportModal(p: {
|
|||||||
</CardContent>{" "}
|
</CardContent>{" "}
|
||||||
<CardActions>
|
<CardActions>
|
||||||
<span style={{ flex: 1 }}>
|
<span style={{ flex: 1 }}>
|
||||||
<RouterLink to={p.exportURL}>
|
<RouterLink to={p.exportURL} target="_blank">
|
||||||
<Button
|
<Button
|
||||||
startIcon={<DownloadIcon />}
|
startIcon={<DownloadIcon />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DatePicker } from "@mui/x-date-pickers";
|
import { DateField } from "@mui/x-date-pickers";
|
||||||
import { dateToTime, timeToDate } from "../../utils/DateUtils";
|
import { dateToTime, timeToDate } from "../../utils/DateUtils";
|
||||||
import { TextFieldVariants } from "@mui/material";
|
import { TextFieldVariants } from "@mui/material";
|
||||||
|
|
||||||
@ -13,13 +13,16 @@ export function DateInput(p: {
|
|||||||
variant?: TextFieldVariants;
|
variant?: TextFieldVariants;
|
||||||
}): React.ReactElement {
|
}): React.ReactElement {
|
||||||
return (
|
return (
|
||||||
<DatePicker
|
<DateField
|
||||||
autoFocus={p.autoFocus}
|
autoFocus={p.autoFocus}
|
||||||
readOnly={p.editable === false}
|
readOnly={p.editable === false}
|
||||||
label={p.label}
|
label={p.label}
|
||||||
slotProps={{
|
slotProps={{
|
||||||
field: { ref: p.ref },
|
textField: {
|
||||||
textField: { variant: p.variant ?? "standard", style: p.style },
|
ref: p.ref,
|
||||||
|
variant: p.variant ?? "standard",
|
||||||
|
style: p.style,
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
value={timeToDate(p.value)}
|
value={timeToDate(p.value)}
|
||||||
onChange={(v) => {
|
onChange={(v) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user