diff --git a/frontend/src/components/PageHeaderActions.jsx b/frontend/src/components/PageHeaderActions.jsx index 3dc1406..590d94d 100644 --- a/frontend/src/components/PageHeaderActions.jsx +++ b/frontend/src/components/PageHeaderActions.jsx @@ -8,6 +8,7 @@ import { IconEraser } from '@tabler/icons-react'; import PortalDropdown from './PortalDropdown.jsx'; +import { IconClock } from '@tabler/icons-react'; function PageHeaderActions({ loading = false, @@ -25,6 +26,7 @@ function PageHeaderActions({ onSave, disableSave = false, onHistory, + lastModified, onOnlineUpdate, onBackgroundUpdate, }) { @@ -144,7 +146,16 @@ function PageHeaderActions({ )} {onHistory && ( - +
+ + {lastModified && ( + + )} +
)} diff --git a/frontend/src/components/S3MetaBar.jsx b/frontend/src/components/S3MetaBar.jsx index 5a81f75..7276b4a 100644 --- a/frontend/src/components/S3MetaBar.jsx +++ b/frontend/src/components/S3MetaBar.jsx @@ -20,6 +20,17 @@ function S3MetaBar({ keys = [], className = '' }) { useEffect(() => { fetchMeta(); }, []); + const copyMeta = async (k) => { + try { + const it = meta[k] || {}; + const text = `etag: ${it?.etag || ''}\nlastModified: ${it?.lastModified || ''}`; + await navigator.clipboard?.writeText(text); + window.notify?.success?.('Скопировано в буфер'); + } catch (e) { + window.notify?.error?.('Не удалось скопировать', String(e)); + } + }; + const renderKey = (k) => { const it = meta[k]; return ( @@ -27,12 +38,15 @@ function S3MetaBar({ keys = [], className = '' }) { {it?.etag || '—'} {it?.lastModified ? new Date(it.lastModified).toLocaleString() : '—'} {typeof it?.contentLength === 'number' ? `${it.contentLength} байт` : '—'} + ); }; return ( -
+
{keys.length === 0 ? renderKey('domainsNew') : keys.map(renderKey)}