feat(builder): implement reusable media library

Media dashboard (real total/images/SVG/logos/unused/storage/alt-coverage, computed from actual assets + a bootstrap usage scan, no fabricated stats); gallery gets grid/list toggle, type filter, sort, drag-and-drop + multi-file upload with cancel/retry and friendly error mapping, lazy thumbnails, multi-select with bulk delete/download/export-metadata; asset details drawer shows real dimensions/size/format/date/usage locations (walks bootstrap config for exact URL matches, reports not-used rather than guessing) plus editable alt text/caption/description/decorative flag with missing-alt warning; shared MediaPickerComponent (already the one reusable picker used by content management) gains type filter, a recent shortcut, and keyboard grid navigation.
This commit is contained in:
sdarbinyan
2026-07-18 16:09:47 +04:00
parent b31c75214d
commit 5d52d81c7d
21 changed files with 1255 additions and 136 deletions

View File

@@ -1147,6 +1147,71 @@ export const ru: Translations = {
confirm: 'Удалить',
emptyTitle: 'Пока нет файлов',
emptyDescription: 'Загрузите изображение или документ, чтобы начать.',
allFolders: 'Все папки',
newFolder: 'Новая папка',
editTags: 'Изменить теги',
totalAssets: 'Всего файлов',
logos: 'Логотипы',
unused: 'Неиспользуемые',
storageUsed: 'Использовано места',
altCoverage: 'Покрытие alt-текстом',
allTypes: 'Все типы',
typeImage: 'Изображения',
typeSvg: 'SVG',
typePdf: 'PDF',
sortRecent: 'Недавние',
sortName: 'Имя',
sortSize: 'Размер',
viewMode: 'Вид',
viewGrid: 'Сетка',
viewList: 'Список',
dropHint: 'Перетащите изображения сюда или используйте кнопку «Загрузить» выше.',
cancelUpload: 'Отменить',
retry: 'Повторить',
errorTooLarge: 'Файл слишком большой. Попробуйте файл меньшего размера.',
errorUnsupportedType: 'Этот тип файла не поддерживается. Используйте JPG, PNG, WebP, GIF, SVG или PDF.',
errorGeneric: 'Не удалось загрузить файл. Попробуйте ещё раз.',
selectedCount: 'выбрано',
download: 'Скачать',
exportMetadata: 'Экспортировать метаданные',
bulkDelete: 'Удалить выбранные',
bulkDeleteConfirm: 'Удалить выбранные файлы? Это действие нельзя отменить.',
clearSelection: 'Снять выделение',
guideCopy: 'Повторное использование существующего файла избавляет от дублей и экономит место. Для баннеров и главных изображений рекомендуем размер около 1200×1200px и сжатие крупных фото перед загрузкой.',
missingAlt: 'Нет alt-текста',
usageCount: 'исп.',
detailsTitle: 'Информация о файле',
filename: 'Имя файла',
format: 'Формат',
fileSize: 'Размер файла',
dimensions: 'Размеры',
uploadDate: 'Загружен',
lastUsed: 'Последнее использование',
usageCountLabel: 'Количество использований',
usedIn: 'Используется в',
notUsed: 'Пока нигде не используется.',
unknownValue: 'Неизвестно',
altText: 'Alt-текст',
altTextHelp: 'Описывает изображение для программ чтения с экрана и поисковых систем.',
decorative: 'Декоративное (alt-текст не нужен)',
missingAltWarning: 'У этого изображения нет alt-текста, и оно не отмечено как декоративное — пользователи с программами чтения с экрана не узнают, что на нём изображено.',
caption: 'Подпись',
description: 'Описание',
usage: {
brand: 'Логотип',
theme: 'Тема',
header: 'Шапка',
footer: 'Подвал',
staticPage: 'Статическая страница',
homepage: 'Главная страница',
catalog: 'Каталог',
productPage: 'Страница товара',
widget: 'Виджет',
company: 'Информация о компании',
seo: 'SEO',
navigation: 'Навигация',
other: 'Другое',
},
},
adminCategories: {
chooseImage: 'Выбрать изображение',