feat: add loading overlay and spinner to BrokerOperationsTable

This commit is contained in:
Sergey Krylov 2026-06-18 06:59:43 +03:00 committed by ksv741
parent 90e9c468de
commit 26371381e0

View File

@ -95,6 +95,7 @@ const pagButtonDisabledStyle = {
export function BrokerOperationsTable({
isLoading,
isFetching,
page,
pageNumber,
canGoBack,
@ -103,6 +104,7 @@ export function BrokerOperationsTable({
onNext,
}: {
isLoading: boolean;
isFetching: boolean;
page: BrokerOperationsPage | undefined;
pageNumber: number;
canGoBack: boolean;
@ -128,10 +130,17 @@ export function BrokerOperationsTable({
<button
type="button"
onClick={onPrevious}
disabled={!canGoBack}
style={canGoBack ? pagButtonStyle : pagButtonDisabledStyle}
disabled={!canGoBack || isFetching}
style={canGoBack && !isFetching ? pagButtonStyle : pagButtonDisabledStyle}
>
{isFetching ? (
<span
className="loading-spinner"
style={{ width: 14, height: 14, display: 'block' }}
/>
) : (
'←'
)}
</button>
<span
style={{
@ -147,10 +156,17 @@ export function BrokerOperationsTable({
<button
type="button"
onClick={onNext}
disabled={!canGoForward}
style={canGoForward ? pagButtonStyle : pagButtonDisabledStyle}
disabled={!canGoForward || isFetching}
style={canGoForward && !isFetching ? pagButtonStyle : pagButtonDisabledStyle}
>
{isFetching ? (
<span
className="loading-spinner"
style={{ width: 14, height: 14, display: 'block' }}
/>
) : (
'→'
)}
</button>
</div>
</div>
@ -180,51 +196,60 @@ export function BrokerOperationsTable({
/>
</table>
</div>
) : operations.length === 0 ? (
) : operations.length === 0 && !isFetching ? (
<p style={{ color: 'var(--color-text-secondary)' }}>Операций за выбранный период нет</p>
) : (
<div style={{ overflowX: 'auto', background: 'var(--color-surface)' }}>
<table style={tableStyle}>
<thead>
<tr>
<th align="left" style={thStyle}>
Дата
</th>
<th align="left" style={thStyle}>
Тип
</th>
<th align="left" style={thStyle}>
Инструмент
</th>
<th align="right" style={thStyle}>
Сумма
</th>
</tr>
</thead>
<tbody>
{operations.map((operation) => {
const impact = getBrokerOperationImpact(operation);
return (
<tr key={operation.cursor || operation.id}>
<td style={tdStyle}>{formatDate(operation.date)}</td>
<td style={tdStyle}>
<span>{getBrokerOperationTypeLabel(operation)}</span>
</td>
<td style={tdStyle}>
<OperationInstrument operation={operation} />
</td>
<td
align="right"
style={{ ...tdStyle, color: moneyColor(impact), fontWeight: 700 }}
>
{formatMoney(operation.payment)}
</td>
</tr>
);
})}
</tbody>
</table>
<div className="table-container">
<div style={{ overflowX: 'auto', background: 'var(--color-surface)' }}>
<table style={tableStyle}>
<thead>
<tr>
<th align="left" style={thStyle}>
Дата
</th>
<th align="left" style={thStyle}>
Тип
</th>
<th align="left" style={thStyle}>
Инструмент
</th>
<th align="right" style={thStyle}>
Сумма
</th>
</tr>
</thead>
<tbody>
{operations.map((operation) => {
const impact = getBrokerOperationImpact(operation);
return (
<tr key={operation.cursor || operation.id}>
<td style={tdStyle}>{formatDate(operation.date)}</td>
<td style={tdStyle}>
<span>{getBrokerOperationTypeLabel(operation)}</span>
</td>
<td style={tdStyle}>
<OperationInstrument operation={operation} />
</td>
<td
align="right"
style={{ ...tdStyle, color: moneyColor(impact), fontWeight: 700 }}
>
{formatMoney(operation.payment)}
</td>
</tr>
);
})}
</tbody>
</table>
</div>
{isFetching && (
<div className="table-loading-overlay">
<div className="loading-spinner" />
<span style={{ fontSize: 13, color: 'var(--color-text-secondary)' }}>
Загрузка страницы {pageNumber}
</span>
</div>
)}
</div>
)}
</section>