feat: implement real-time numbering preview with manual input handling
- Enhanced the `previewCode` endpoint to accept a new `manualInputValue` parameter, allowing for dynamic sequence generation based on user input. - Updated the `NumberingRuleService` to skip legacy sequence lookups when manual input is not provided, ensuring accurate initial sequence display. - Integrated debounce functionality in the `V2Input` component to optimize API calls for real-time suffix updates as users type. - Refactored category resolution logic into a helper function to reduce code duplication and improve maintainability. These changes significantly improve the user experience by providing immediate feedback on numbering sequences based on manual inputs.
This commit is contained in:
@@ -676,7 +676,7 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
|
||||
|
||||
// 채번 코드 생성 (formDataRef.current 사용하여 최신 formData 전달)
|
||||
const currentFormData = formDataRef.current;
|
||||
const previewResponse = await previewNumberingCode(numberingRuleId, currentFormData);
|
||||
const previewResponse = await previewNumberingCode(numberingRuleId, currentFormData, manualInputValue || undefined);
|
||||
|
||||
if (previewResponse.success && previewResponse.data?.generatedCode) {
|
||||
const generatedCode = previewResponse.data.generatedCode;
|
||||
@@ -764,6 +764,49 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
|
||||
};
|
||||
}, [columnName, manualInputValue, propsInputType, config.inputType, config.type]);
|
||||
|
||||
// 수동 입력값 변경 시 디바운스로 순번 미리보기 갱신
|
||||
useEffect(() => {
|
||||
const inputType = propsInputType || config.inputType || config.type || "text";
|
||||
if (inputType !== "numbering") return;
|
||||
if (!numberingTemplateRef.current?.includes("____")) return;
|
||||
|
||||
const ruleId = numberingRuleIdRef.current;
|
||||
if (!ruleId) return;
|
||||
|
||||
// 사용자가 한 번도 입력하지 않은 초기 상태면 스킵
|
||||
if (!userEditedNumberingRef.current) return;
|
||||
|
||||
const debounceTimer = setTimeout(async () => {
|
||||
try {
|
||||
const currentFormData = formDataRef.current;
|
||||
const resp = await previewNumberingCode(ruleId, currentFormData, manualInputValue || undefined);
|
||||
|
||||
if (resp.success && resp.data?.generatedCode) {
|
||||
const newTemplate = resp.data.generatedCode;
|
||||
if (newTemplate.includes("____")) {
|
||||
numberingTemplateRef.current = newTemplate;
|
||||
|
||||
const parts = newTemplate.split("____");
|
||||
const prefix = parts[0] || "";
|
||||
const suffix = parts.length > 1 ? parts.slice(1).join("") : "";
|
||||
const combined = prefix + manualInputValue + suffix;
|
||||
|
||||
setAutoGeneratedValue(combined);
|
||||
onChange?.(combined);
|
||||
if (onFormDataChange && columnName) {
|
||||
onFormDataChange(columnName, combined);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
/* 미리보기 실패 시 기존 suffix 유지 */
|
||||
}
|
||||
}, 300);
|
||||
|
||||
return () => clearTimeout(debounceTimer);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [manualInputValue]);
|
||||
|
||||
// 실제 표시할 값 (자동생성 값 또는 props value)
|
||||
const displayValue = autoGeneratedValue ?? value;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user