Commit 7783dd60 authored by Nicolas Frandeboeuf's avatar Nicolas Frandeboeuf
Browse files

Remote stash (breaks everything)

parent e473f4b9
Pipeline #546231 failed with stage
in 1 minute and 6 seconds
import React, { useCallback, useState } from 'react';
import { useDispatch } from 'react-redux';
import { useHistory, useParams } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';
import { get, actions } from '../../store';
import {
......@@ -209,7 +209,7 @@ const CustomLabelForm = (props: { access: Access }) => {
const DangerZone = (props: { access: Access }) => {
const dispatch = useDispatch();
const history = useHistory();
const navigate = useNavigate();
const accessId = props.access.id;
const isDemoEnabled = useKresusState(state => get.isDemoMode(state));
......@@ -228,11 +228,11 @@ const DangerZone = (props: { access: Access }) => {
try {
await actions.deleteAccess(dispatch, props.access.id);
notify.success($t('client.accesses.deletion_success'));
history.push(URL.accessList);
navigate(URL.accessList);
} catch (error) {
notify.error($t('client.accesses.deletion_error', { error: error.message }));
}
}, [history, dispatch, props.access.id])
}, [navigate, dispatch, props.access.id])
);
return (
......
import React, { useCallback } from 'react';
import { useHistory, useParams } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';
import URL from './urls';
import {
......@@ -85,7 +85,7 @@ const SyncAccount = (props: { accountId: number }) => {
export default () => {
const dispatch = useDispatch();
const history = useHistory();
const navigate = useNavigate();
const { accountId: accountIdStr } = useParams<{ accountId: string }>();
const accountId = Number.parseInt(accountIdStr, 10);
......@@ -109,11 +109,11 @@ export default () => {
try {
await actions.deleteAccount(dispatch, account.id);
notify.success($t('client.accesses.account_deletion_success'));
history.push(URL.accessList);
navigate(URL.accessList);
} catch (error) {
notify.error($t('client.category.account_deletion_error', { error: error.message }));
}
}, [history, dispatch, account]);
}, [navigate, dispatch, account]);
const updateAccount = useCallback(
(update: any, previousAttributes: any) => {
......
import React from 'react';
import { Switch, Route, Redirect } from 'react-router-dom';
import { Route, Routes, Navigate } from 'react-router-dom';
import AccessesList from './accesses-list';
import NewAccess from './new-access';
......@@ -9,24 +9,16 @@ import EditAccount from './edit-account';
import URL from './urls';
import './accesses.css';
const redirectToAccessList = () => <Redirect to={URL.accessList} />;
const redirectToAccessList = () => <Navigate to={URL.accessList} />;
export default () => {
return (
<Switch>
<Route path={URL.newAccess}>
<NewAccess />
</Route>
<Route path={URL.EDIT_ACCESS_PATTERN}>
<EditAccess />
</Route>
<Route path={URL.EDIT_ACCOUNT_PATTERN}>
<EditAccount />
</Route>
<Route path={URL.accessList}>
<AccessesList />
</Route>
<Routes>
<Route path={URL.newAccess} element={<NewAccess />} />
<Route path={URL.EDIT_ACCESS_PATTERN} element={<EditAccess />} />
<Route path={URL.EDIT_ACCOUNT_PATTERN} element={<EditAccount />} />
<Route path={URL.accessList} element={<AccessesList />} />
<Route path={URL.accessList} render={redirectToAccessList} />
</Switch>
</Routes>
);
};
import React, { useCallback } from 'react';
import { useHistory } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import { notify, translate as $t } from '../../helpers';
import URL from './urls';
......@@ -7,12 +7,12 @@ import URL from './urls';
import NewAccessForm from './new-access-form';
export default () => {
const history = useHistory();
const navigate = useNavigate();
const onSubmit = useCallback(() => {
notify.success($t('client.accesses.creation_success'));
history.push(URL.accessList);
}, [history]);
navigate(URL.accessList);
}, [navigate]);
return (
<NewAccessForm
......
import React, { useCallback, useRef } from 'react';
import { useDispatch } from 'react-redux';
import { useParams, useHistory } from 'react-router-dom';
import { useParams, useNavigate } from 'react-router-dom';
import { translate as $t, notify, NONE_CATEGORY_ID, useKresusState } from '../../helpers';
import { get, actions } from '../../store';
......@@ -18,7 +18,7 @@ const DeleteForm = () => {
state => get.operationIdsByCategoryId(state, categoryId).length
);
const history = useHistory();
const navigate = useNavigate();
const dispatch = useDispatch();
const refReplace = useRef<HTMLSelectElement>(null);
......@@ -33,15 +33,15 @@ const DeleteForm = () => {
// the category may not exist anymore!
// So, we have to first push the history entry, then delete, and get
// back to the current form if the deletion failed somehow.
history.push(URL.list);
navigate(URL.list);
try {
await actions.deleteCategory(dispatch, categoryId, replaceBy);
notify.success($t('client.category.deletion_success'));
} catch (error) {
notify.error($t('client.category.deletion_error', { error: error.message }));
history.push(URL.delete(categoryId));
navigate(URL.delete(categoryId));
}
}, [dispatch, history, refReplace, categoryId]);
}, [dispatch, navigate, refReplace, categoryId]);
let explainer;
let replaceForm;
......
import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useHistory, useParams } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { get, actions } from '../../store';
......@@ -17,7 +17,7 @@ import { ValidatedTextInputRef } from '../ui/validated-text-input';
const CategoryForm = (props: { id?: number }) => {
const dispatch = useDispatch();
const history = useHistory();
const navigate = useNavigate();
const labelRef = useRef<ValidatedTextInputRef>(null);
......@@ -49,7 +49,7 @@ const CategoryForm = (props: { id?: number }) => {
try {
await actions.createCategory(dispatch, newFields);
notify.success($t('client.category.creation_success'));
history.push(URL.list);
navigate(URL.list);
} catch (error) {
notify.error($t('client.category.creation_error', { error: error.message }));
}
......@@ -59,11 +59,11 @@ const CategoryForm = (props: { id?: number }) => {
try {
await actions.updateCategory(dispatch, category, newFields);
notify.success($t('client.category.edition_success'));
history.push(URL.list);
navigate(URL.list);
} catch (error) {
notify.error($t('client.category.edition_error', { error: error.message }));
}
}, [history, dispatch, label, color, category]);
}, [navigate, dispatch, label, color, category]);
// On mount, focus on (resp. select in edit mode) the label field.
useEffect(() => {
......
import React from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import { Route, Routes, Navigate } from 'react-router-dom';
import List from './list';
import DeleteForm from './delete-form';
import { EditForm, NewForm } from './form';
import URL from './urls';
const redirectToList = () => <Redirect to={URL.list} push={false} />;
export default () => {
return (
<Switch>
<Route path={URL.new}>
{' '}
<NewForm />
</Route>
<Route path={URL.EDIT_PATTERN}>
<EditForm />
</Route>
<Route path={URL.DELETE_PATTERN}>
<DeleteForm />
</Route>
<Route path={URL.list}>
<List />
</Route>
<Route path={URL.list} render={redirectToList} />
</Switch>
<Routes>
<Route
path={URL.new}
element={
<>
{' '}
<NewForm />
</>
}
/>
<Route path={URL.EDIT_PATTERN} element={<EditForm />} />
<Route path={URL.DELETE_PATTERN} element={<DeleteForm />} />
<Route path={URL.list} element={<List />} />
</Routes>
);
};
......@@ -6,13 +6,13 @@ import { translate as $t, useKresusState } from '../../helpers';
import { Popconfirm } from '../ui';
import { useGenericError } from '../../hooks';
import { useHistory } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import URL from '../../urls';
export default () => {
const isDemoMode = useKresusState(state => get.isDemoMode(state));
const dispatch = useDispatch();
const history = useHistory();
const navigate = useNavigate();
const handleDisable = useGenericError(
useCallback(async () => {
// Bad Hack: Go to the about/ page before disabling demo mode. The
......@@ -32,15 +32,15 @@ export default () => {
// assertions.
//
// In case of failure, revert back to the previous page.
history.push(URL.about.url());
navigate(URL.about.url());
try {
await actions.disableDemoMode(dispatch);
} catch (err) {
history.goBack();
navigate(-1);
throw err;
}
}, [history, dispatch])
}, [navigate, dispatch])
);
if (!isDemoMode) {
......
import React from 'react';
import { Switch, Redirect, Route, Link } from 'react-router-dom';
import { Navigate, Route, Routes, Link } from 'react-router-dom';
import { translate as $t } from '../../helpers';
import URL from '../../urls';
......@@ -121,34 +121,23 @@ const Menu = () => (
</div>
);
const RedirectToBasePath = () => <Redirect to={BASE_PATH} />;
const Onboarding = () => {
return (
<div className="onboarding">
<div className="onboarding-content">
<div>
<Switch>
<Route path={NEW_BANK_PATH}>
<NewAccessPane />
</Route>
<Route path={IMPORT_PATH}>
<ImportPane />
</Route>
<Route path={DEMO_PATH}>
<Demo />
</Route>
<Route path={ADMIN_PATH}>
<AdminPane />
</Route>
<Route path={BASE_PATH}>
<Menu />
</Route>
<Route path={URL.woobReadme.url()}>
<WoobInstallIndex />
</Route>
<Route path={BASE_PATH} render={RedirectToBasePath} />
</Switch>
<Routes>
<Route path={NEW_BANK_PATH} element={<NewAccessPane />} />
<Route path={IMPORT_PATH} element={<ImportPane />} />
<Route path={DEMO_PATH} element={<Demo />} />
<Route path={ADMIN_PATH} element={<AdminPane />} />
<Route path={BASE_PATH} element={<Menu />} />
<Route path={URL.woobReadme.url()} element={<WoobInstallIndex />} />
<Route
path={BASE_PATH}
element={<Navigate to={BASE_PATH} replace={true} />}
/>
</Routes>
</div>
</div>
</div>
......
import React, { useCallback, useContext } from 'react';
import { Link, useHistory } from 'react-router-dom';
import { Link, useNavigate } from 'react-router-dom';
import { formatDate, NONE_CATEGORY_ID, translate as $t, useKresusState } from '../../helpers';
import { get } from '../../store';
......@@ -126,13 +126,13 @@ export const OperationItem = React.forwardRef<HTMLTableRowElement, OperationItem
export const PressableOperationItem = (props: OperationItemProps) => {
const { operationId } = props;
const history = useHistory();
const navigate = useNavigate();
const { driver } = useContext(ViewContext);
const onLongPress = useCallback(
() => history.push(TransactionUrls.details.url(driver, operationId)),
[history, operationId, driver]
() => navigate(TransactionUrls.details.url(driver, operationId)),
[navigate, operationId, driver]
);
const ref = useLongPress<HTMLTableRowElement>(onLongPress);
......
......@@ -21,7 +21,7 @@ import MultipleSelect from '../ui/multiple-select';
import MinMaxInput, { MinMaxInputRef } from '../ui/min-max-input';
import './search.css';
import { matchPath, useHistory } from 'react-router-dom';
import { matchPath, useNavigate } from 'react-router-dom';
// Debouncing for input events (ms).
const INPUT_DEBOUNCING = 150;
......@@ -175,7 +175,7 @@ const MaxDatePicker = (props: { id: string }) => {
};
const SearchComponent = (props: { minAmount: number; maxAmount: number }) => {
const history = useHistory();
const navigate = useNavigate();
const displaySearchDetails = useKresusState(state => get.displaySearchDetails(state));
const searchFields = useKresusState(state => get.searchFields(state));
......@@ -276,12 +276,12 @@ const SearchComponent = (props: { minAmount: number; maxAmount: number }) => {
// transaction's detail page. We already know what the next path
// will be, because this effect is triggered asynchronously, after
// we've requested to leave the current route/component.
const nextPath = history.location.pathname;
const nextPath = window.location.pathname;
if (matchPath(nextPath, URL.transactions.pattern) === null) {
resetAll(false);
}
};
}, [resetAll, history]);
}, [resetAll, navigate]);
return (
<form className="search" hidden={!displaySearchDetails}>
......
import React, { useCallback, useEffect, useState } from 'react';
import { Route, Switch, Redirect, useHistory, useParams } from 'react-router-dom';
import { Route, Routes, Navigate, useNavigate, useParams } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { BackLink, ButtonLink, Form, Popconfirm, ValidatedTextInput } from '../ui';
......@@ -55,7 +55,7 @@ const SharedForm = (props: {
};
const NewForm = (props: { categoryToName?: Map<number, string> }) => {
const history = useHistory();
const navigate = useNavigate();
const dispatch = useDispatch();
const { label: predefinedLabel, categoryId: categoryIdStr } = useParams<{
......@@ -79,12 +79,12 @@ const NewForm = (props: { categoryToName?: Map<number, string> }) => {
assert(label !== null, 'label must be set at this point');
await actions.createRule(dispatch, { label, categoryId });
notify.success($t('client.rules.creation_success'));
history.push(URL.list);
navigate(URL.list);
} catch (err) {
notify.error($t('client.rules.creation_error', { err: err.message }));
}
},
[history, dispatch]
[navigate, dispatch]
);
return (
......@@ -99,7 +99,7 @@ const NewForm = (props: { categoryToName?: Map<number, string> }) => {
};
const EditForm = () => {
const history = useHistory();
const navigate = useNavigate();
const { ruleId: ruleIdStr } = useParams<{ ruleId: string }>();
const ruleId = Number.parseInt(ruleIdStr, 10);
......@@ -122,17 +122,17 @@ const EditForm = () => {
assert(label !== null, 'label must be set at this point');
await actions.updateRule(dispatch, rule, { label, categoryId });
notify.success($t('client.rules.edit_success'));
history.push(URL.list);
navigate(URL.list);
} catch (err) {
notify.error($t('client.rules.edit_error', { err: err.message }));
}
},
[rule, history, dispatch]
[rule, navigate, dispatch]
);
if (Number.isNaN(ruleId)) {
notify.error($t('client.rules.rule_not_found'));
history.push(URL.list);
navigate(URL.list);
return null;
}
......@@ -336,8 +336,6 @@ const List = (props: { categoryToName: Map<number, string> }) => {
return <ul className="rules">{content}</ul>;
};
const redirectToList = () => <Redirect to={URL.list} push={false} />;
export default () => {
// Load the rules the first time we navigate within the family of
// components from the outside. This is not done in the List component
......@@ -370,27 +368,29 @@ export default () => {
}
return (
<Switch>
<Route path={URL.predefinedNew.pattern} exact={true}>
<NewForm categoryToName={categoryToName} />
</Route>
<Route path={URL.new}>
<NewForm />
</Route>
<Route path={URL.edit.pattern}>
<EditForm />
</Route>
<Route path={URL.list}>
<ButtonLink
to={URL.new}
aria={$t('client.rules.new_rule')}
label={$t('client.rules.new_rule')}
icon="plus"
/>
<hr />
<List categoryToName={categoryToName} />
</Route>
<Route path={URL.list} render={redirectToList} />
</Switch>
<Routes>
<Route
path={URL.predefinedNew.pattern}
element={<NewForm categoryToName={categoryToName} />}
/>
<Route path={URL.new} element={<NewForm />} />
<Route path={URL.edit.pattern} element={<EditForm />} />
<Route
path={URL.list}
element={
<>
<ButtonLink
to={URL.new}
aria={$t('client.rules.new_rule')}
label={$t('client.rules.new_rule')}
icon="plus"
/>
<hr />
<List categoryToName={categoryToName} />
</>
}
/>
<Route path={URL.list} element={<Navigate to={URL.list} replace={true} />} />
</Routes>
);
};
......@@ -6,7 +6,7 @@ import { actions } from '../../../store';
import AccountSelector from '../../ui/account-select';
import AmountInput from '../../ui/amount-input';
import { useHistory, useParams } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';
import { BackLink, Form } from '../../ui';
import URL from './urls';
import { useGenericError } from '../../../hooks';
......@@ -22,7 +22,7 @@ const AlertForm = () => {
const refSelectOrder = useRef<HTMLSelectElement | null>(null);
const refSelectAccount = useRef<{ value: number } | null>(null);
const history = useHistory();
const navigate = useNavigate();
const onSubmit = useGenericError(
useCallback(async () => {
assert(type !== null, 'type must be set');
......@@ -41,8 +41,8 @@ const AlertForm = () => {
order,
});
history.push(URL.all);
}, [dispatch, history, type, limit, refSelectOrder, refSelectAccount])
navigate(URL.all);
}, [dispatch, navigate, type, limit, refSelectOrder, refSelectAccount])
);
const isBalanceAlert = type === 'balance';
......
......@@ -15,7 +15,7 @@ import DisplayIf from '../../ui/display-if';
import './alerts.css';
import { Route, Switch } from 'react-router-dom';
import { Route, Routes } from 'react-router-dom';
import URL from './urls';
const AlertsAndReports = () => {
......@@ -74,16 +74,10 @@ AlertsAndReports.displayName = 'AlertsAndReports';
export default () => {
return (
<Switch>
<Route path={URL.newAlert.pattern}>
<AlertForm />
</Route>
<Route path={URL.newReport.pattern}>
<ReportForm />
</Route>
<Route path={URL.all}>
<AlertsAndReports />
</Route>
</Switch>
<Routes>
<Route path={URL.newAlert.pattern} element={<AlertForm />} />
<Route path={URL.newReport.pattern} element={<ReportForm />} />
<Route path={URL.all} element={<AlertsAndReports />} />
</Routes>
);
};
import React, { useCallback, useRef } from 'react';
import { useDispatch } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
import { assert, translate as $t } from '../../../helpers';
import { actions } from '../../../store';
......@@ -10,7 +10,7 @@ import { BackLink, Form } from '../../ui';
import URL from './urls';
const CreateReportForm = () => {
const history = useHistory();
const navigate = useNavigate();
const dispatch = useDispatch();
const refSelectFrequency = useRef<HTMLSelectElement>(null);
......@@ -30,8 +30,8 @@ const CreateReportForm = () => {
accountId: refSelectAccount.current.value,