fix: 화면 편집기 높이 입력 필드 1px 단위 조절 가능하도록 수정
- 문제: 높이 입력 시 10 단위로만 입력 가능 (예: 1080 입력 불가) - 원인: 격자 스냅 로직이 onChange마다 높이를 10/20 단위로 강제 반올림 - 해결: 1. 모든 number input 필드에 step="1" 추가 2. ScreenDesigner.tsx의 격자 스냅 로직 수정 (높이 스냅 제거) 3. UnifiedPropertiesPanel.tsx에 로컬 상태 추가하여 입력 중 스냅 방지 4. onBlur/Enter 시에만 실제 값 업데이트 수정 파일: - frontend/components/screen/ScreenDesigner.tsx - frontend/components/screen/panels/UnifiedPropertiesPanel.tsx - frontend/components/screen/panels/PropertiesPanel.tsx - frontend/components/screen/panels/ResolutionPanel.tsx - frontend/components/screen/panels/RowSettingsPanel.tsx - frontend/components/screen/panels/webtype-configs/NumberTypeConfigPanel.tsx - frontend/components/screen/panels/webtype-configs/TextTypeConfigPanel.tsx
This commit is contained in:
@@ -181,7 +181,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
// 🆕 전역 테이블 새로고침 이벤트 리스너
|
||||
useEffect(() => {
|
||||
const handleRefreshTable = () => {
|
||||
console.log("🔄 InteractiveDataTable: 전역 새로고침 이벤트 수신");
|
||||
if (component.tableName) {
|
||||
loadData(currentPage, searchValues);
|
||||
}
|
||||
@@ -206,15 +205,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
return webType === "category";
|
||||
});
|
||||
|
||||
console.log(`🔍 InteractiveDataTable 카테고리 컬럼 확인:`, {
|
||||
tableName: component.tableName,
|
||||
totalColumns: component.columns?.length,
|
||||
categoryColumns: categoryColumns?.map(c => ({
|
||||
name: c.columnName,
|
||||
webType: getColumnWebType(c.columnName)
|
||||
}))
|
||||
});
|
||||
|
||||
if (!categoryColumns || categoryColumns.length === 0) return;
|
||||
|
||||
// 각 카테고리 컬럼의 값 목록 조회
|
||||
@@ -239,12 +229,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`✅ InteractiveDataTable 카테고리 매핑 완료:`, {
|
||||
tableName: component.tableName,
|
||||
mappedColumns: Object.keys(mappings),
|
||||
mappings
|
||||
});
|
||||
|
||||
setCategoryMappings(mappings);
|
||||
} catch (error) {
|
||||
console.error("카테고리 매핑 로드 실패:", error);
|
||||
@@ -403,7 +387,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
// 대체 URL 생성 (직접 파일 경로 사용)
|
||||
if (previewImage.path) {
|
||||
const altUrl = getDirectFileUrl(previewImage.path);
|
||||
// console.log("대체 URL 시도:", altUrl);
|
||||
setAlternativeImageUrl(altUrl);
|
||||
} else {
|
||||
toast.error("이미지를 불러올 수 없습니다.");
|
||||
@@ -469,7 +452,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
try {
|
||||
return tableColumn?.detailSettings ? JSON.parse(tableColumn.detailSettings) : {};
|
||||
} catch {
|
||||
// console.warn("상세 설정 파싱 실패:", tableColumn?.detailSettings);
|
||||
return {};
|
||||
}
|
||||
},
|
||||
@@ -672,15 +654,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
const handleRefreshFileStatus = async (event: CustomEvent) => {
|
||||
const { tableName, recordId, columnName, targetObjid, fileCount } = event.detail;
|
||||
|
||||
// console.log("🔄 InteractiveDataTable 파일 상태 새로고침 이벤트 수신:", {
|
||||
// tableName,
|
||||
// recordId,
|
||||
// columnName,
|
||||
// targetObjid,
|
||||
// fileCount,
|
||||
// currentTableName: component.tableName
|
||||
// });
|
||||
|
||||
// 현재 테이블과 일치하는지 확인
|
||||
if (tableName === component.tableName) {
|
||||
// 해당 행의 파일 상태 업데이트
|
||||
@@ -690,13 +663,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
[recordId]: { hasFiles: fileCount > 0, fileCount },
|
||||
[columnKey]: { hasFiles: fileCount > 0, fileCount },
|
||||
}));
|
||||
|
||||
// console.log("✅ 파일 상태 업데이트 완료:", {
|
||||
// recordId,
|
||||
// columnKey,
|
||||
// hasFiles: fileCount > 0,
|
||||
// fileCount
|
||||
// });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1104,7 +1070,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
setIsAdding(true);
|
||||
|
||||
// 실제 API 호출로 데이터 추가
|
||||
// console.log("🔥 추가할 데이터:", addFormData);
|
||||
await tableTypeApi.addTableData(component.tableName, addFormData);
|
||||
|
||||
// 모달 닫기 및 폼 초기화
|
||||
@@ -1127,9 +1092,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
setIsEditing(true);
|
||||
|
||||
// 실제 API 호출로 데이터 수정
|
||||
// console.log("🔥 수정할 데이터:", editFormData);
|
||||
// console.log("🔥 원본 데이터:", editingRowData);
|
||||
|
||||
if (editingRowData) {
|
||||
await tableTypeApi.editTableData(component.tableName, editingRowData, editFormData);
|
||||
|
||||
@@ -1200,7 +1162,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
const selectedData = Array.from(selectedRows).map((index) => data[index]);
|
||||
|
||||
// 실제 삭제 API 호출
|
||||
// console.log("🗑️ 삭제할 데이터:", selectedData);
|
||||
await tableTypeApi.deleteTableData(component.tableName, selectedData);
|
||||
|
||||
// 선택 해제 및 다이얼로그 닫기
|
||||
@@ -1488,12 +1449,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
case "category": {
|
||||
// 카테고리 셀렉트 (동적 import)
|
||||
const { CategorySelectComponent } = require("@/lib/registry/components/category-select/CategorySelectComponent");
|
||||
console.log("🎯 카테고리 렌더링 (편집 폼):", {
|
||||
tableName: component.tableName,
|
||||
columnName: column.columnName,
|
||||
columnLabel: column.label,
|
||||
value,
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<CategorySelectComponent
|
||||
@@ -1775,12 +1730,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
case "category": {
|
||||
// 카테고리 셀렉트 (동적 import)
|
||||
const { CategorySelectComponent } = require("@/lib/registry/components/category-select/CategorySelectComponent");
|
||||
console.log("🎯 카테고리 렌더링 (추가 폼):", {
|
||||
tableName: component.tableName,
|
||||
columnName: column.columnName,
|
||||
columnLabel: column.label,
|
||||
value,
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<CategorySelectComponent
|
||||
@@ -1868,8 +1817,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
const handleDeleteLinkedFile = useCallback(
|
||||
async (fileId: string, fileName: string) => {
|
||||
try {
|
||||
// console.log("🗑️ 파일 삭제 시작:", { fileId, fileName });
|
||||
|
||||
// 삭제 확인 다이얼로그
|
||||
if (!confirm(`"${fileName}" 파일을 삭제하시겠습니까?`)) {
|
||||
return;
|
||||
@@ -1884,7 +1831,6 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
});
|
||||
|
||||
const result = response.data;
|
||||
// console.log("📡 파일 삭제 API 응답:", result);
|
||||
|
||||
if (!result.success) {
|
||||
throw new Error(result.message || "파일 삭제 실패");
|
||||
@@ -1901,15 +1847,11 @@ export const InteractiveDataTable: React.FC<InteractiveDataTableProps> = ({
|
||||
try {
|
||||
const response = await getLinkedFiles(component.tableName, recordId);
|
||||
setLinkedFiles(response.files || []);
|
||||
// console.log("📁 파일 목록 새로고침 완료:", response.files?.length || 0);
|
||||
} catch (error) {
|
||||
// console.error("파일 목록 새로고침 실패:", error);
|
||||
// 파일 목록 새로고침 실패 시 무시
|
||||
}
|
||||
}
|
||||
|
||||
// console.log("✅ 파일 삭제 완료:", fileName);
|
||||
} catch (error) {
|
||||
// console.error("❌ 파일 삭제 실패:", error);
|
||||
toast.error(`"${fileName}" 파일 삭제에 실패했습니다.`);
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user