feat(WEB): DynamicItemForm 필드 타입 확장 및 컴포넌트 레지스트리 추가
- DynamicFieldRenderer에 신규 필드 타입 추가 (Currency, File, MultiSelect, Radio, Reference, Toggle, UnitValue, Computed) - DynamicTableSection 및 TableCellRenderer 추가 - 필드 프리셋 및 설정 구조 분리 - 컴포넌트 레지스트리 개발 도구 페이지 추가 - UniversalListPage 개선 - 근태관리 코드 정리 - 즐겨찾기 기능 및 동적 필드 타입 백엔드 스펙 문서 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -671,30 +671,12 @@ export function UniversalListPage<T>({
|
||||
toast.success(`${selectedData.length}건 다운로드 완료`);
|
||||
}, [config.excelDownload, effectiveSelectedItems, rawData, getItemId]);
|
||||
|
||||
// 엑셀 다운로드 버튼 렌더링
|
||||
// 엑셀 전체 다운로드 버튼 (헤더 영역)
|
||||
const renderExcelDownloadButton = useMemo(() => {
|
||||
if (!config.excelDownload || config.excelDownload.enabled === false || !canExport) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { enableSelectedDownload = true } = config.excelDownload;
|
||||
|
||||
// 선택 항목이 있고 선택 다운로드가 활성화된 경우
|
||||
if (enableSelectedDownload && effectiveSelectedItems.size > 0) {
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleSelectedExcelDownload}
|
||||
className="gap-2"
|
||||
>
|
||||
<Download className="h-4 w-4" />
|
||||
선택 다운로드 ({effectiveSelectedItems.size})
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
// 전체 다운로드
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
@@ -711,7 +693,30 @@ export function UniversalListPage<T>({
|
||||
{isExcelDownloading ? '다운로드 중...' : '엑셀 다운로드'}
|
||||
</Button>
|
||||
);
|
||||
}, [config.excelDownload, effectiveSelectedItems.size, isExcelDownloading, handleExcelDownload, handleSelectedExcelDownload]);
|
||||
}, [config.excelDownload, canExport, isExcelDownloading, handleExcelDownload]);
|
||||
|
||||
// 엑셀 선택 다운로드 버튼 (selectionActions 영역 - "전체 N건 / N개 항목 선택됨" 뒤)
|
||||
const renderExcelSelectedDownloadButton = useMemo(() => {
|
||||
if (!config.excelDownload || config.excelDownload.enabled === false || !canExport) {
|
||||
return null;
|
||||
}
|
||||
const { enableSelectedDownload = true } = config.excelDownload;
|
||||
if (!enableSelectedDownload || effectiveSelectedItems.size === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={handleSelectedExcelDownload}
|
||||
className="gap-2"
|
||||
>
|
||||
<Download className="h-4 w-4" />
|
||||
선택 다운로드 ({effectiveSelectedItems.size})
|
||||
</Button>
|
||||
);
|
||||
}, [config.excelDownload, canExport, effectiveSelectedItems.size, handleSelectedExcelDownload]);
|
||||
|
||||
// ===== 정렬 핸들러 =====
|
||||
const handleSort = useCallback((key: string) => {
|
||||
@@ -952,11 +957,16 @@ export function UniversalListPage<T>({
|
||||
onToggleSelectAll={toggleSelectAll}
|
||||
getItemId={effectiveGetItemId}
|
||||
onBulkDelete={config.actions?.deleteItem ? handleBulkDeleteClick : undefined}
|
||||
selectionActions={config.selectionActions?.({
|
||||
selectedItems: effectiveSelectedItems,
|
||||
onClearSelection: () => externalSelection ? undefined : setSelectedItems(new Set()),
|
||||
onRefresh: fetchData,
|
||||
})}
|
||||
selectionActions={
|
||||
<>
|
||||
{renderExcelSelectedDownloadButton}
|
||||
{config.selectionActions?.({
|
||||
selectedItems: effectiveSelectedItems,
|
||||
onClearSelection: () => externalSelection ? undefined : setSelectedItems(new Set()),
|
||||
onRefresh: fetchData,
|
||||
})}
|
||||
</>
|
||||
}
|
||||
// 표시 옵션
|
||||
showCheckbox={config.showCheckbox}
|
||||
showRowNumber={config.showRowNumber}
|
||||
|
||||
Reference in New Issue
Block a user