feat: Добавить кнопку для копирования метаданных и отображение времени последнего изменения в компонентах PageHeaderActions и S3MetaBar
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m52s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m52s
This commit is contained in:
@@ -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({
|
||||
</button>
|
||||
)}
|
||||
{onHistory && (
|
||||
<button className="btn btn-outline-secondary" type="button" onClick={onHistory} title="История версий">История</button>
|
||||
<div className="btn-group">
|
||||
<button className="btn btn-outline-secondary" type="button" onClick={onHistory} title="История версий">История</button>
|
||||
{lastModified && (
|
||||
<button className="btn btn-outline-secondary" type="button" onClick={onHistory} title={`Последние изменения: ${new Date(lastModified).toLocaleString()}`}>
|
||||
<IconClock className="me-1" />
|
||||
<span className="d-none d-sm-inline">{new Date(lastModified).toLocaleTimeString()}</span>
|
||||
<span className="d-inline d-sm-none">{new Date(lastModified).toLocaleTimeString()}</span>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -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 = '' }) {
|
||||
<span className="badge bg-blue-lt text-blue d-inline-flex align-items-center"><IconHash size={14} className="me-1" />{it?.etag || '—'}</span>
|
||||
<span className="badge bg-blue-lt text-blue d-inline-flex align-items-center"><IconClock size={14} className="me-1" />{it?.lastModified ? new Date(it.lastModified).toLocaleString() : '—'}</span>
|
||||
<span className="badge bg-blue-lt text-blue d-inline-flex align-items-center"><IconFileText size={14} className="me-1" />{typeof it?.contentLength === 'number' ? `${it.contentLength} байт` : '—'}</span>
|
||||
<button className="btn btn-outline-secondary btn-sm" type="button" onClick={() => copyMeta(k)} title="Копировать ETag/Last-Modified">
|
||||
<IconFileText size={14} className="me-1" />Копировать
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={`card-footer ${className}`}>
|
||||
<div className={`card-footer ${className}`} style={{ position: 'sticky', bottom: 0, zIndex: 5, background: 'var(--tblr-card-bg)', borderTop: '1px solid rgba(0,0,0,.05)' }}>
|
||||
<div className="d-flex align-items-center justify-content-between">
|
||||
<div className="d-flex flex-column gap-1">
|
||||
{keys.length === 0 ? renderKey('domainsNew') : keys.map(renderKey)}
|
||||
|
||||
Reference in New Issue
Block a user