fix(pop): 연결 역방향 라우팅 + 확정 후속 액션 + API URL 수정

- useConnectionResolver: _auto 모드에서 역방향(타겟→소스) 라우팅 추가
- pop-button: 입고 확정 성공 후 followUpActions 실행 (navigate/refresh/event)
- pop-button: execute-action API URL 경로 수정 (/api/pop/ → /pop/)
This commit is contained in:
SeongHyun Kim 2026-03-03 16:19:22 +09:00
parent e3ae8d273c
commit f12fca46be
2 changed files with 40 additions and 6 deletions

View File

@ -11,7 +11,8 @@
*
* _auto :
* sourceOutput="_auto" / connectionMeta를
* key가 category="event" .
* key가 category="event" .
* (정방향: 소스->, 역방향: 타겟->)
*/
import { useEffect, useRef } from "react";
@ -85,9 +86,9 @@ export function useConnectionResolver({
if (!sourceType || !targetType) continue;
const pairs = getAutoMatchPairs(sourceType, targetType);
for (const pair of pairs) {
// 정방향: 소스 sendable -> 타겟 receivable
const forwardPairs = getAutoMatchPairs(sourceType, targetType);
for (const pair of forwardPairs) {
const sourceEvent = `__comp_output__${conn.sourceComponent}__${pair.sourceKey}`;
const targetEvent = `__comp_input__${conn.targetComponent}__${pair.targetKey}`;
@ -99,6 +100,21 @@ export function useConnectionResolver({
});
unsubscribers.push(unsub);
}
// 역방향: 타겟 sendable -> 소스 receivable
const reversePairs = getAutoMatchPairs(targetType, sourceType);
for (const pair of reversePairs) {
const sourceEvent = `__comp_output__${conn.targetComponent}__${pair.sourceKey}`;
const targetEvent = `__comp_input__${conn.sourceComponent}__${pair.targetKey}`;
const unsub = subscribe(sourceEvent, (payload: unknown) => {
publish(targetEvent, {
value: payload,
_connectionId: conn.id,
});
});
unsubscribers.push(unsub);
}
} else {
const sourceEvent = `__comp_output__${conn.sourceComponent}__${conn.sourceOutput || conn.sourceField}`;

View File

@ -547,7 +547,7 @@ export function PopButtonComponent({
const cardListMapping = cardListData?.mapping ?? null;
const fieldMapping = fieldData?.mapping ?? null;
const result = await apiClient.post("/api/pop/execute-action", {
const result = await apiClient.post("/pop/execute-action", {
action: "inbound-confirm",
data: {
items: selectedItems,
@ -567,6 +567,24 @@ export function PopButtonComponent({
success: true,
count: selectedItems.length,
});
// 후속 액션 실행 (navigate, refresh 등)
const followUps = config?.followUpActions ?? [];
for (const fa of followUps) {
switch (fa.type) {
case "navigate":
if (fa.targetScreenId) {
publish("__pop_navigate__", { screenId: fa.targetScreenId, params: fa.params });
}
break;
case "refresh":
publish("__pop_refresh__");
break;
case "event":
if (fa.eventName) publish(fa.eventName, fa.eventPayload);
break;
}
}
} else {
toast.error(result.data?.message || "입고 확정에 실패했습니다.");
}
@ -577,7 +595,7 @@ export function PopButtonComponent({
setConfirmProcessing(false);
setShowInboundConfirm(false);
}
}, [componentId, subscribe, publish, config?.statusChangeRules, config?.inboundConfirm?.statusChangeRules]);
}, [componentId, subscribe, publish, config?.statusChangeRules, config?.inboundConfirm?.statusChangeRules, config?.followUpActions]);
// 클릭 핸들러
const handleClick = useCallback(async () => {