refactor: enforce frontend view model boundaries
Frontend verify / commits (pull_request) Successful in 28s
Frontend verify / security (pull_request) Successful in 10s
Frontend verify / verify (pull_request) Successful in 8m19s

This commit is contained in:
2026-09-28 18:48:23 +03:00
parent 5b69003516
commit ca0ad4f824
287 changed files with 8558 additions and 4538 deletions
@@ -29,12 +29,46 @@ type InstrumentSectionProps = PropsWithChildren<{
state: SectionState;
title: string;
}>;
const InstrumentSection: FC<InstrumentSectionProps> = (props) => {
const { t } = useTranslation();
const readError = t(props.state.hasData ? "accounts.refreshError" : "stock.sectionError");
const readError = t(
props.state.hasData ? "accounts.refreshError" : "stock.sectionError",
);
const sectionClassName = props.embedded
? classes.embeddedSection
: classes.section;
const skeletonHeight = props.large
? CHART_SKELETON_HEIGHT_PX
: SECTION_SKELETON_HEIGHT_PX;
let sectionContent;
if (props.state.loading) {
sectionContent = (
<LoadingSkeleton
label={t("stock.loadingSection", { section: props.title })}
>
<Stack>
<Skeleton h={skeletonHeight} />
<Skeleton h={14} w="60%" />
</Stack>
</LoadingSkeleton>
);
}
else {
sectionContent = (
props.children
);
}
return (
<Paper
className={props.embedded ? classes.embeddedSection : classes.section}
className={sectionClassName}
component="section"
withBorder={!props.embedded}
>
@@ -42,34 +76,37 @@ const InstrumentSection: FC<InstrumentSectionProps> = (props) => {
<Title order={2} size="h3">
{props.title}
</Title>
{props.controls}
</Group>
{!!(props.state.stale) && ((
<Text size="xs">{t("investment.stale")}</Text>
))}
{!!(props.state.partial) && ((
{!!props.state.stale && <Text size="xs">{t("investment.stale")}</Text>}
{!!props.state.partial && (
<Text role="status">{t("investment.partial")}</Text>
))}
{!!(props.state.lastSuccessfulAt) && ((
)}
{!!props.state.lastSuccessfulAt && (
<Text c="dimmed" size="xs">
{t("investment.sourceTime", {
date: formatSnapshotTime(props.state.lastSuccessfulAt),
})}
</Text>
))}
{!!(props.state.refreshing) && ((
)}
{!!props.state.refreshing && (
<Text c="dimmed" role="status" size="xs">
{t("accounts.refreshing")}
</Text>
))}
{!!(props.state.error) && ((
)}
{!!props.state.error && (
<Alert aria-live="polite" color="orange" mb="sm" role="status">
<Group justify="space-between">
<Text size="sm">
{props.state.sourceError
? t("investment.syncFailed")
: readError}
{props.state.sourceError ? t("investment.syncFailed") : readError}
</Text>
<Button
disabled={props.state.refreshing}
onClick={props.state.retry}
@@ -80,27 +117,9 @@ const InstrumentSection: FC<InstrumentSectionProps> = (props) => {
</Button>
</Group>
</Alert>
))}
{props.state.loading
? (
<LoadingSkeleton
label={t("stock.loadingSection", { section: props.title })}
>
<Stack>
<Skeleton
h={
props.large
? CHART_SKELETON_HEIGHT_PX
: SECTION_SKELETON_HEIGHT_PX
}
/>
<Skeleton h={14} w="60%" />
</Stack>
</LoadingSkeleton>
)
: (
props.children
)}
)}
{sectionContent}
</Paper>
);
};