fix: Improve number and slider input handling in V2Input and SplitPanelLayoutComponent
- Enhanced V2Input to convert string values from the database to numbers for number and slider inputs, ensuring correct display and functionality. - Updated primary key retrieval logic in SplitPanelLayoutComponent to prioritize actual DB id values, improving data integrity. - Simplified primary key handling by removing unnecessary checks and ensuring consistent usage of id fields. - Improved user feedback in the SplitPanelLayoutComponent with clearer console logs for save operations and item selections.
This commit is contained in:
parent
505930b3ec
commit
d0ebb82f90
|
|
@ -771,9 +771,15 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
|
|||
);
|
||||
|
||||
case "number":
|
||||
// DB에서 문자열("325")로 반환되는 경우도 숫자로 변환하여 표시
|
||||
const numValue = typeof displayValue === "number"
|
||||
? displayValue
|
||||
: (displayValue !== undefined && displayValue !== null && displayValue !== "" && !isNaN(Number(displayValue)))
|
||||
? Number(displayValue)
|
||||
: undefined;
|
||||
return (
|
||||
<NumberInput
|
||||
value={typeof displayValue === "number" ? displayValue : undefined}
|
||||
value={numValue}
|
||||
onChange={(v) => {
|
||||
setAutoGeneratedValue(null);
|
||||
onChange?.(v ?? 0);
|
||||
|
|
@ -802,9 +808,15 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
|
|||
);
|
||||
|
||||
case "slider":
|
||||
// DB에서 문자열로 반환되는 경우도 숫자로 변환
|
||||
const sliderValue = typeof displayValue === "number"
|
||||
? displayValue
|
||||
: (displayValue !== undefined && displayValue !== null && displayValue !== "" && !isNaN(Number(displayValue)))
|
||||
? Number(displayValue)
|
||||
: (config.min ?? 0);
|
||||
return (
|
||||
<SliderInput
|
||||
value={typeof displayValue === "number" ? displayValue : (config.min ?? 0)}
|
||||
value={sliderValue}
|
||||
onChange={(v) => {
|
||||
setAutoGeneratedValue(null);
|
||||
onChange?.(v);
|
||||
|
|
|
|||
|
|
@ -2105,22 +2105,16 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
const editButtonConfig = componentConfig.leftPanel?.editButton;
|
||||
if (editButtonConfig?.mode === "modal" && editButtonConfig?.modalScreenId) {
|
||||
const leftTableName = componentConfig.leftPanel?.tableName || "";
|
||||
const sourceColumn = componentConfig.leftPanel?.itemAddConfig?.sourceColumn || "id";
|
||||
|
||||
// Primary Key 찾기
|
||||
let primaryKeyName = sourceColumn;
|
||||
let primaryKeyValue = item[sourceColumn];
|
||||
// Primary Key 찾기 - 실제 DB의 id 컬럼 값을 우선 사용
|
||||
let primaryKeyValue = item.id || item.ID;
|
||||
|
||||
if (primaryKeyValue === undefined || primaryKeyValue === null) {
|
||||
if (item.id !== undefined && item.id !== null) {
|
||||
primaryKeyName = "id";
|
||||
primaryKeyValue = item.id;
|
||||
} else if (item.ID !== undefined && item.ID !== null) {
|
||||
primaryKeyName = "ID";
|
||||
primaryKeyValue = item.ID;
|
||||
} else {
|
||||
// id가 없으면 sourceColumn 시도, 마지막으로 첫 번째 키
|
||||
const sourceColumn = componentConfig.leftPanel?.itemAddConfig?.sourceColumn || "id";
|
||||
primaryKeyValue = item[sourceColumn];
|
||||
if (primaryKeyValue === undefined || primaryKeyValue === null) {
|
||||
const firstKey = Object.keys(item)[0];
|
||||
primaryKeyName = firstKey;
|
||||
primaryKeyValue = item[firstKey];
|
||||
}
|
||||
}
|
||||
|
|
@ -2147,7 +2141,6 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
console.log("✅ [SplitPanel] 좌측 수정 모달 화면 열기:", {
|
||||
screenId: editButtonConfig.modalScreenId,
|
||||
tableName: leftTableName,
|
||||
primaryKeyName,
|
||||
primaryKeyValue,
|
||||
});
|
||||
return;
|
||||
|
|
@ -2282,9 +2275,8 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
return;
|
||||
}
|
||||
|
||||
// Primary Key 찾기
|
||||
const sourceColumn = componentConfig.leftPanel?.itemAddConfig?.sourceColumn || "id";
|
||||
const primaryKey = selectedLeftItem[sourceColumn] || selectedLeftItem.id || selectedLeftItem.ID;
|
||||
// Primary Key 찾기 - 실제 DB의 id 컬럼 값을 사용 (sourceColumn은 관계 연결용이므로 PK로 사용하지 않음)
|
||||
const primaryKey = selectedLeftItem.id || selectedLeftItem.ID;
|
||||
|
||||
if (!primaryKey) {
|
||||
toast({
|
||||
|
|
@ -2307,7 +2299,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
cleanData.company_code = companyCode;
|
||||
}
|
||||
|
||||
console.log("📝 [SplitPanel] 커스텀 우측 패널 저장:", { tableName, sourceColumn, primaryKey, data: cleanData });
|
||||
console.log("📝 [SplitPanel] 커스텀 우측 패널 저장:", { tableName, primaryKey, data: cleanData });
|
||||
|
||||
const response = await dataApi.updateRecord(tableName, primaryKey, cleanData);
|
||||
|
||||
|
|
@ -2529,7 +2521,8 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
if (deleteModalPanel === "left") {
|
||||
loadLeftData();
|
||||
// 삭제된 항목이 선택되어 있었으면 선택 해제
|
||||
if (selectedLeftItem && selectedLeftItem[sourceColumn] === primaryKey) {
|
||||
const deletedId = deleteModalItem?.id || deleteModalItem?.ID;
|
||||
if (selectedLeftItem && (selectedLeftItem.id === deletedId || selectedLeftItem.ID === deletedId)) {
|
||||
setSelectedLeftItem(null);
|
||||
setRightData(null);
|
||||
}
|
||||
|
|
@ -2968,6 +2961,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
const displayHeight = isResizingComp && resizeSize ? resizeSize.height : (comp.size?.height || 100);
|
||||
|
||||
// 컴포넌트 데이터를 DynamicComponentRenderer 형식으로 변환
|
||||
// componentConfig의 주요 속성을 최상위로 펼침 (일반 화면의 overrides 플래트닝과 동일)
|
||||
const componentData = {
|
||||
id: comp.id,
|
||||
type: "component" as const,
|
||||
|
|
@ -2977,6 +2971,11 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
size: { width: displayWidth, height: displayHeight },
|
||||
componentConfig: comp.componentConfig || {},
|
||||
style: comp.style || {},
|
||||
// 파일 업로드/미디어 등이 component.tableName, component.columnName을 직접 참조하므로 펼침
|
||||
tableName: comp.componentConfig?.tableName,
|
||||
columnName: comp.componentConfig?.columnName,
|
||||
webType: comp.componentConfig?.webType,
|
||||
inputType: comp.inputType || comp.componentConfig?.inputType,
|
||||
};
|
||||
|
||||
if (isDesignMode) {
|
||||
|
|
@ -3981,6 +3980,15 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
})()
|
||||
) : componentConfig.rightPanel?.displayMode === "custom" ? (
|
||||
// 🆕 커스텀 모드: 패널 안에 자유롭게 컴포넌트 배치
|
||||
// 실행 모드에서 좌측 미선택 시 안내 메시지 표시
|
||||
!isDesignMode && !selectedLeftItem ? (
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<div className="text-muted-foreground text-center text-sm">
|
||||
<p className="mb-2">좌측에서 항목을 선택하세요</p>
|
||||
<p className="text-xs">선택한 항목의 상세 정보가 여기에 표시됩니다</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className="relative h-full w-full"
|
||||
data-split-panel-container="true"
|
||||
|
|
@ -4002,6 +4010,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
const displayHeight = isResizingComp && resizeSize ? resizeSize.height : (comp.size?.height || 100);
|
||||
|
||||
// 컴포넌트 데이터를 DynamicComponentRenderer 형식으로 변환
|
||||
// componentConfig의 주요 속성을 최상위로 펼침 (일반 화면의 overrides 플래트닝과 동일)
|
||||
const componentData = {
|
||||
id: comp.id,
|
||||
type: "component" as const,
|
||||
|
|
@ -4011,6 +4020,11 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
size: { width: displayWidth, height: displayHeight },
|
||||
componentConfig: comp.componentConfig || {},
|
||||
style: comp.style || {},
|
||||
// 파일 업로드/미디어 등이 component.tableName, component.columnName을 직접 참조하므로 펼침
|
||||
tableName: comp.componentConfig?.tableName,
|
||||
columnName: comp.componentConfig?.columnName,
|
||||
webType: comp.componentConfig?.webType,
|
||||
inputType: comp.inputType || comp.componentConfig?.inputType,
|
||||
};
|
||||
|
||||
if (isDesignMode) {
|
||||
|
|
@ -4201,6 +4215,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
) : isLoadingRight ? (
|
||||
// 로딩 중
|
||||
<div className="flex h-full items-center justify-center">
|
||||
|
|
|
|||
Loading…
Reference in New Issue