feat(editor): + Экспорт button в InfoPanel per redesign dark theme screenshot
User dropped /Users/zimin/Downloads/Ordinis (3) — full project dump.
Dark theme editor screenshot (uploads/draw-4b771386...png) показывает
INFO PANEL c двумя buttons:
- ↓ Экспорт…
- ⟲ Time-travel…
У нас был Time-travel + AOI — добавил Экспорт как third button.
Implementation:
- EditorInfoPanel.actions.onExport + exportPending props
- DownloadSimpleIcon кнопка 'Экспорт…'
- Wired к useBulkExportRecords mutation:
* Selection не empty -> export selected
* Selection empty -> export all filtered records
- disabled когда mutation pending, label 'Экспорт…'
Project dump reviewed:
- design_handoff_dictionary_catalog — старый handoff, всё уже реализовано
(List view MR !62, Hub MR earlier, Graph earlier)
- patches/ — @nstart/ui patches, moot (мы dropped @nstart/ui MR !52)
- redesign/ — уже синхронизированы colors MR !71, layout MR !69
- uploads/ — user-provided screenshots, main delta = Export button
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useMemo } from 'react'
|
||||
import { Link } from '@tanstack/react-router'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { ClockCounterClockwiseIcon, MapTrifoldIcon } from '@phosphor-icons/react'
|
||||
import { ClockCounterClockwiseIcon, MapTrifoldIcon, DownloadSimpleIcon } from '@phosphor-icons/react'
|
||||
import { Badge } from '@/ui'
|
||||
import { useDictionaryDependents } from '@/api/queries'
|
||||
import type { DictionaryDetail } from '@/api/client'
|
||||
@@ -25,13 +25,15 @@ import { cn } from '@/lib/utils'
|
||||
export type EditorInfoPanelProps = {
|
||||
detail: DictionaryDetail
|
||||
recordCount: number
|
||||
/** Optional action buttons (Time-travel / AOI filter) — bottom of panel
|
||||
/** Optional action buttons (Time-travel / AOI / Export) — bottom of panel
|
||||
* per redesign prototype. Toggle handlers come from route's state. */
|
||||
actions?: {
|
||||
onTimeTravel?: () => void
|
||||
timeTravelActive?: boolean
|
||||
onAoi?: () => void
|
||||
aoiActive?: boolean
|
||||
onExport?: () => void
|
||||
exportPending?: boolean
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +111,19 @@ export function EditorInfoPanel({ detail, recordCount, actions }: EditorInfoPane
|
||||
{t('aoi.button', { defaultValue: 'AOI фильтр…' })}
|
||||
</button>
|
||||
)}
|
||||
{actions.onExport && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={actions.onExport}
|
||||
disabled={actions.exportPending}
|
||||
className="w-full h-8 rounded-md border border-line bg-surface text-ink-2 hover:border-line-2 hover:bg-surface-2 disabled:opacity-50 disabled:cursor-not-allowed text-cell flex items-center justify-center gap-1.5 transition-colors"
|
||||
>
|
||||
<DownloadSimpleIcon weight="regular" size={14} />
|
||||
{actions.exportPending
|
||||
? t('export.pending', { defaultValue: 'Экспорт…' })
|
||||
: t('export.button', { defaultValue: '↓ Экспорт…' })}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -570,6 +570,17 @@ function DictionaryDetail() {
|
||||
timeTravelActive: Boolean(timeTravelAt),
|
||||
onAoi: () => setAoiOpen(true),
|
||||
aoiActive: Boolean(aoi),
|
||||
onExport: () => {
|
||||
// Export all visible records (filtered + paginated set OR full
|
||||
// dictionary). Если selection непустой — exports selection,
|
||||
// иначе — все filtered records.
|
||||
const keys =
|
||||
selection.size > 0
|
||||
? Array.from(selection)
|
||||
: filteredRecords.map((r) => r.businessKey)
|
||||
if (keys.length > 0) bulkExportMut.mutate(keys)
|
||||
},
|
||||
exportPending: bulkExportMut.isPending,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user