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:
@@ -86,7 +86,7 @@ const InstrumentEvents: FC<InstrumentEventsProps> = (props) => {
|
||||
|
||||
<Group justify="space-between" mt="md">
|
||||
<Button
|
||||
disabled={!vm.hasPrevious || vm.operationsState.refreshing}
|
||||
disabled={!vm.hasPrevious}
|
||||
onClick={vm.onPrevious}
|
||||
variant="default"
|
||||
>
|
||||
@@ -94,7 +94,7 @@ const InstrumentEvents: FC<InstrumentEventsProps> = (props) => {
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
disabled={!vm.operations.hasNext || vm.operationsState.refreshing}
|
||||
disabled={!vm.operations.hasNext}
|
||||
onClick={vm.onNext}
|
||||
variant="default"
|
||||
>
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
import type { FC, PropsWithChildren, ReactNode } from "react";
|
||||
|
||||
import { Avatar, Button, Group, Paper, Text, Title } from "@mantine/core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Avatar, Group, Paper, Text, Title } from "@mantine/core";
|
||||
|
||||
import classes from "./InstrumentHeader.module.css";
|
||||
|
||||
type InstrumentHeaderProps = PropsWithChildren<{
|
||||
logoSrc: null | string;
|
||||
name: string;
|
||||
onRefresh: () => void;
|
||||
refreshing: boolean;
|
||||
subtitle: ReactNode;
|
||||
}>;
|
||||
|
||||
const InstrumentHeader: FC<InstrumentHeaderProps> = (props) => {
|
||||
const { children, logoSrc, name, onRefresh, refreshing, subtitle } = props;
|
||||
const { t } = useTranslation();
|
||||
const { children, logoSrc, name, subtitle } = props;
|
||||
|
||||
return (
|
||||
<Paper className={classes.header} component="header" withBorder>
|
||||
@@ -31,10 +27,6 @@ const InstrumentHeader: FC<InstrumentHeaderProps> = (props) => {
|
||||
<Text c="dimmed" size="sm">{subtitle}</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button disabled={refreshing} onClick={onRefresh} variant="subtle">
|
||||
{t("investment.refresh")}
|
||||
</Button>
|
||||
</Group>
|
||||
|
||||
{children}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { FC } from "react";
|
||||
|
||||
import { Anchor, Button, Skeleton, Stack, Text, Title } from "@mantine/core";
|
||||
import { Anchor, Skeleton, Stack, Text, Title } from "@mantine/core";
|
||||
import { LoadingSkeleton } from "@wealthledger/ui";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router";
|
||||
@@ -11,11 +11,10 @@ type InstrumentPageStateProps = {
|
||||
code?: string;
|
||||
kind: "bond" | "stock";
|
||||
loading: boolean;
|
||||
retry: () => void;
|
||||
};
|
||||
|
||||
const InstrumentPageState: FC<InstrumentPageStateProps> = (props) => {
|
||||
const { code, kind, loading, retry } = props;
|
||||
const { code, kind, loading } = props;
|
||||
const { t } = useTranslation();
|
||||
if (loading) return (
|
||||
<LoadingSkeleton label={t(`${kind}.loading`)}>
|
||||
@@ -55,10 +54,6 @@ const InstrumentPageState: FC<InstrumentPageStateProps> = (props) => {
|
||||
<Anchor component={Link} to="/settings">
|
||||
{t("accounts.openSettings")}
|
||||
</Anchor>
|
||||
|
||||
<Button onClick={retry} variant="default">
|
||||
{t("accounts.retry")}
|
||||
</Button>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { FC, PropsWithChildren, ReactNode } from "react";
|
||||
|
||||
import {
|
||||
Alert,
|
||||
Button,
|
||||
Group,
|
||||
Paper,
|
||||
Skeleton,
|
||||
@@ -13,8 +12,6 @@ import {
|
||||
import { LoadingSkeleton } from "@wealthledger/ui";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { SourceSyncStatus } from "@/shared/ui";
|
||||
|
||||
import type { SectionState } from "../model/section";
|
||||
|
||||
import classes from "./InstrumentDetails.module.css";
|
||||
@@ -33,10 +30,6 @@ type InstrumentSectionProps = PropsWithChildren<{
|
||||
const InstrumentSection: FC<InstrumentSectionProps> = (props) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const readError = t(
|
||||
props.state.hasData ? "accounts.refreshError" : "stock.sectionError",
|
||||
);
|
||||
|
||||
const sectionClassName = props.embedded
|
||||
? classes.embeddedSection
|
||||
: classes.section;
|
||||
@@ -80,35 +73,11 @@ const InstrumentSection: FC<InstrumentSectionProps> = (props) => {
|
||||
{props.controls}
|
||||
</Group>
|
||||
|
||||
<SourceSyncStatus
|
||||
lastSuccessfulAt={props.state.lastSuccessfulAt}
|
||||
stale={props.state.stale}
|
||||
/>
|
||||
|
||||
{!!props.state.partial && <Text role="status">{t("investment.partial")}</Text>}
|
||||
|
||||
{!!props.state.refreshing && (
|
||||
<Text c="dimmed" role="status" size="xs">
|
||||
{t("accounts.refreshing")}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{!!props.state.error && (
|
||||
{!!(props.state.error && !props.state.hasData) && (
|
||||
<Alert aria-live="polite" color="orange" mb="sm" role="status">
|
||||
<Group justify="space-between">
|
||||
<Text size="sm">
|
||||
{props.state.sourceError ? t("investment.syncFailed") : readError}
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
disabled={props.state.refreshing}
|
||||
onClick={props.state.retry}
|
||||
size="xs"
|
||||
variant="default"
|
||||
>
|
||||
{t("accounts.retry")}
|
||||
</Button>
|
||||
</Group>
|
||||
<Text size="sm">{t("stock.sectionError")}</Text>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user