feat: add quiet reading with rare confirmations
Part of the quiet-user-feedback change; docs and specs land in their own repositories.
This commit is contained in:
@@ -5,7 +5,7 @@ import { useParams, useSearchParams } from "react-router";
|
||||
|
||||
import { type IncomeAnalytics, useIncomeAnalytics } from "@/entities/income";
|
||||
import { useScreenSync } from "@/features/tbank-connection";
|
||||
import { isValidPeriod, moscowDate } from "@/shared/lib";
|
||||
import { isValidPeriod, moscowDate, useInitialAvailability } from "@/shared/lib";
|
||||
|
||||
import {
|
||||
type IncomeDisplayModel,
|
||||
@@ -27,19 +27,13 @@ type AccountIncomePageViewModel
|
||||
display: IncomeDisplayModel;
|
||||
form: ReturnType<typeof useForm<IncomeForm>>;
|
||||
formRevision: string;
|
||||
lastSuccessfulAt?: null | string;
|
||||
onReset: () => void;
|
||||
onSubmit: (values: IncomeForm) => void;
|
||||
partial?: boolean;
|
||||
refreshError: boolean;
|
||||
refreshing: boolean;
|
||||
retry: () => Promise<unknown> | undefined;
|
||||
sourceError?: boolean;
|
||||
state: "loaded";
|
||||
}
|
||||
| {
|
||||
period: IncomePeriod;
|
||||
retry: () => Promise<unknown> | undefined;
|
||||
state: "error";
|
||||
}
|
||||
| { state: "loading" };
|
||||
@@ -69,7 +63,7 @@ const useAccountIncomePageViewModel = (): AccountIncomePageViewModel => {
|
||||
const [resetRevision, setResetRevision] = useState(0);
|
||||
const analytics = useIncomeAnalytics(accountId, period);
|
||||
|
||||
const sync = useScreenSync(
|
||||
useScreenSync(
|
||||
{ accountId, from: period.from, screen: "income", to: period.to },
|
||||
[analytics],
|
||||
);
|
||||
@@ -82,11 +76,20 @@ const useAccountIncomePageViewModel = (): AccountIncomePageViewModel => {
|
||||
form.reset(draftPeriod(period));
|
||||
}, [accountId, form, period]);
|
||||
|
||||
if (analytics.isLoading || !analytics.data) {
|
||||
return analytics.isError || analytics.meta?.sync.state === "failed"
|
||||
? { period, retry: sync.retry, state: "error" }
|
||||
const availability = useInitialAvailability({
|
||||
hasContent: !!analytics.data,
|
||||
identity: `${accountId}:${period.from}:${period.to}`,
|
||||
isError: analytics.isError || analytics.meta?.sync.state === "failed",
|
||||
isFetching: analytics.isFetching,
|
||||
});
|
||||
|
||||
if (availability === "loading" && analytics.isLoading)
|
||||
return { state: "loading" };
|
||||
|
||||
if (!analytics.data)
|
||||
return availability === "unavailable"
|
||||
? { period, state: "error" }
|
||||
: { state: "loading" };
|
||||
}
|
||||
|
||||
const display = toIncomeDisplayModel(analytics.data, analytics.meta);
|
||||
|
||||
@@ -109,14 +112,9 @@ const useAccountIncomePageViewModel = (): AccountIncomePageViewModel => {
|
||||
display,
|
||||
form,
|
||||
formRevision: `${accountId}:${period.from}:${period.to}:${resetRevision}`,
|
||||
lastSuccessfulAt: analytics.meta?.lastSuccessfulAt,
|
||||
onReset,
|
||||
onSubmit,
|
||||
partial: analytics.meta?.availability !== "complete",
|
||||
refreshError: analytics.isError || sync.sourceError || sync.transportError,
|
||||
refreshing: analytics.isFetching || sync.refreshing,
|
||||
retry: sync.retry,
|
||||
sourceError: sync.sourceError,
|
||||
state: "loaded",
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user