feat: Enhance CategoryValueManagerTree with input focus management and modal improvements
- Added refs for input fields in the CategoryValueManagerTree component to manage focus transitions between the name and description inputs. - Updated the modal behavior to reset form data without closing the modal, allowing for continuous input. - Changed the button label from "취소" to "닫기" for better clarity in the modal interface. - Included debug logging for cascading roles in the SelectBasicComponent to assist with troubleshooting. These enhancements improve user experience and maintainability of the component.
This commit is contained in:
parent
db31b02180
commit
27558787b0
|
|
@ -6,7 +6,7 @@
|
||||||
* - 체크박스를 통한 다중 선택 및 일괄 삭제 지원
|
* - 체크박스를 통한 다중 선택 및 일괄 삭제 지원
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState, useEffect, useCallback, useMemo } from "react";
|
import React, { useState, useEffect, useCallback, useMemo, useRef } from "react";
|
||||||
import {
|
import {
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
|
|
@ -291,6 +291,10 @@ export const CategoryValueManagerTree: React.FC<CategoryValueManagerTreeProps> =
|
||||||
const [editingValue, setEditingValue] = useState<CategoryValue | null>(null);
|
const [editingValue, setEditingValue] = useState<CategoryValue | null>(null);
|
||||||
const [deletingValue, setDeletingValue] = useState<CategoryValue | null>(null);
|
const [deletingValue, setDeletingValue] = useState<CategoryValue | null>(null);
|
||||||
|
|
||||||
|
// 추가 모달 input ref
|
||||||
|
const addNameRef = useRef<HTMLInputElement>(null);
|
||||||
|
const addDescRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
// 폼 상태
|
// 폼 상태
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
valueCode: "",
|
valueCode: "",
|
||||||
|
|
@ -508,7 +512,15 @@ export const CategoryValueManagerTree: React.FC<CategoryValueManagerTreeProps> =
|
||||||
const response = await createCategoryValue(input);
|
const response = await createCategoryValue(input);
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
toast.success("카테고리가 추가되었습니다");
|
toast.success("카테고리가 추가되었습니다");
|
||||||
setIsAddModalOpen(false);
|
// 폼 초기화 (모달은 닫지 않고 연속 입력)
|
||||||
|
setFormData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
valueCode: "",
|
||||||
|
valueLabel: "",
|
||||||
|
description: "",
|
||||||
|
color: "",
|
||||||
|
}));
|
||||||
|
setTimeout(() => addNameRef.current?.focus(), 50);
|
||||||
// 기존 펼침 상태 유지하면서 데이터 새로고침
|
// 기존 펼침 상태 유지하면서 데이터 새로고침
|
||||||
await loadTree(true);
|
await loadTree(true);
|
||||||
// 부모 노드만 펼치기 (하위 추가 시)
|
// 부모 노드만 펼치기 (하위 추가 시)
|
||||||
|
|
@ -746,9 +758,17 @@ export const CategoryValueManagerTree: React.FC<CategoryValueManagerTreeProps> =
|
||||||
이름 <span className="text-destructive">*</span>
|
이름 <span className="text-destructive">*</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
ref={addNameRef}
|
||||||
id="valueLabel"
|
id="valueLabel"
|
||||||
value={formData.valueLabel}
|
value={formData.valueLabel}
|
||||||
onChange={(e) => setFormData({ ...formData, valueLabel: e.target.value })}
|
onChange={(e) => setFormData({ ...formData, valueLabel: e.target.value })}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
addDescRef.current?.focus();
|
||||||
|
}
|
||||||
|
}}
|
||||||
placeholder="카테고리 이름을 입력하세요"
|
placeholder="카테고리 이름을 입력하세요"
|
||||||
className="h-9 text-sm"
|
className="h-9 text-sm"
|
||||||
/>
|
/>
|
||||||
|
|
@ -759,9 +779,17 @@ export const CategoryValueManagerTree: React.FC<CategoryValueManagerTreeProps> =
|
||||||
설명
|
설명
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
ref={addDescRef}
|
||||||
id="description"
|
id="description"
|
||||||
value={formData.description}
|
value={formData.description}
|
||||||
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
|
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
handleAdd();
|
||||||
|
}
|
||||||
|
}}
|
||||||
placeholder="선택 사항"
|
placeholder="선택 사항"
|
||||||
className="h-9 text-sm"
|
className="h-9 text-sm"
|
||||||
/>
|
/>
|
||||||
|
|
@ -784,7 +812,7 @@ export const CategoryValueManagerTree: React.FC<CategoryValueManagerTreeProps> =
|
||||||
onClick={() => setIsAddModalOpen(false)}
|
onClick={() => setIsAddModalOpen(false)}
|
||||||
className="h-9 flex-1 text-sm sm:flex-none"
|
className="h-9 flex-1 text-sm sm:flex-none"
|
||||||
>
|
>
|
||||||
취소
|
닫기
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={handleAdd} className="h-9 flex-1 text-sm sm:flex-none">
|
<Button onClick={handleAdd} className="h-9 flex-1 text-sm sm:flex-none">
|
||||||
추가
|
추가
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,22 @@ const SelectBasicComponent: React.FC<SelectBasicComponentProps> = ({
|
||||||
const cascadingRole = config?.cascadingRole || componentConfig?.cascadingRole || "child";
|
const cascadingRole = config?.cascadingRole || componentConfig?.cascadingRole || "child";
|
||||||
const cascadingParentField = config?.cascadingParentField || componentConfig?.cascadingParentField;
|
const cascadingParentField = config?.cascadingParentField || componentConfig?.cascadingParentField;
|
||||||
|
|
||||||
|
if (component.columnName === "data_type" || component.columnName === "unit") {
|
||||||
|
console.log("🔥🔥🔥 [PLC 캐스케이딩 디버그]", {
|
||||||
|
columnName: component.columnName,
|
||||||
|
categoryRelationCode,
|
||||||
|
cascadingRole,
|
||||||
|
cascadingParentField,
|
||||||
|
configKeys: config ? Object.keys(config) : "null",
|
||||||
|
componentConfigKeys: componentConfig ? Object.keys(componentConfig) : "null",
|
||||||
|
configCategoryRelationCode: config?.categoryRelationCode,
|
||||||
|
componentConfigCategoryRelationCode: componentConfig?.categoryRelationCode,
|
||||||
|
webType,
|
||||||
|
formDataKeys: formData ? Object.keys(formData) : "null",
|
||||||
|
parentValue: cascadingParentField && formData ? formData[cascadingParentField] : "N/A",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 🆕 계층구조 역할 설정 (대분류/중분류/소분류)
|
// 🆕 계층구조 역할 설정 (대분류/중분류/소분류)
|
||||||
// 1순위: 동적으로 조회된 값 (테이블 타입관리에서 설정)
|
// 1순위: 동적으로 조회된 값 (테이블 타입관리에서 설정)
|
||||||
// 2순위: config에서 전달된 값
|
// 2순위: config에서 전달된 값
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue