Merge branch 'mhkim-node' of http://39.117.244.52:3000/kjs/ERP-node into jskim-node
This commit is contained in:
commit
2cf5c8de32
|
|
@ -563,8 +563,20 @@ export const EditModal: React.FC<EditModalProps> = ({ className }) => {
|
|||
if (screenInfo && layoutData) {
|
||||
const components = layoutData.components || [];
|
||||
|
||||
// 화면의 실제 크기 계산
|
||||
const dimensions = calculateScreenDimensions(components);
|
||||
// 화면 관리에서 설정한 해상도 우선 사용 (ScreenModal과 동일)
|
||||
const screenResolution = (layoutData as any).screenResolution || (screenInfo as any).screenResolution;
|
||||
|
||||
let dimensions;
|
||||
if (screenResolution && screenResolution.width && screenResolution.height) {
|
||||
dimensions = {
|
||||
width: screenResolution.width,
|
||||
height: screenResolution.height,
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
};
|
||||
} else {
|
||||
dimensions = calculateScreenDimensions(components);
|
||||
}
|
||||
setScreenDimensions(dimensions);
|
||||
|
||||
setScreenData({
|
||||
|
|
@ -1547,31 +1559,25 @@ export const EditModal: React.FC<EditModalProps> = ({ className }) => {
|
|||
}
|
||||
};
|
||||
|
||||
// 모달 크기 설정 - 화면관리 설정 크기 + 헤더
|
||||
// 모달 크기 설정 - ScreenModal과 동일한 방식 (maxHeight로 유연 처리)
|
||||
const getModalStyle = () => {
|
||||
if (!screenDimensions) {
|
||||
return {
|
||||
className: "w-fit min-w-[400px] max-w-4xl max-h-[90vh] overflow-hidden p-0",
|
||||
style: undefined, // undefined로 변경 - defaultWidth/defaultHeight 사용
|
||||
className: "w-fit min-w-[400px] max-w-4xl overflow-hidden",
|
||||
style: { padding: 0, gap: 0, maxHeight: "calc(100dvh - 8px)" },
|
||||
};
|
||||
}
|
||||
|
||||
// 화면관리에서 설정한 크기 = 컨텐츠 영역 크기
|
||||
// 실제 모달 크기 = 컨텐츠 + 헤더 + gap + padding + 라벨 공간
|
||||
const headerHeight = 52; // DialogHeader (타이틀 + border-b + py-3)
|
||||
const dialogGap = 16; // DialogContent gap-4
|
||||
const extraPadding = 24; // 추가 여백 (안전 마진)
|
||||
const labelSpace = 30; // 입력 필드 위 라벨 공간 (-top-6 = 24px + 여유)
|
||||
|
||||
const totalHeight = screenDimensions.height + headerHeight + dialogGap + extraPadding + labelSpace;
|
||||
const finalWidth = Math.min(screenDimensions.width, window.innerWidth * 0.98);
|
||||
|
||||
return {
|
||||
className: "overflow-hidden p-0",
|
||||
style: {
|
||||
width: `${Math.min(screenDimensions.width + 48, window.innerWidth * 0.98)}px`, // 좌우 패딩 추가
|
||||
height: `${Math.min(totalHeight, window.innerHeight * 0.95)}px`,
|
||||
width: `${finalWidth}px`,
|
||||
maxHeight: "calc(100dvh - 8px)",
|
||||
maxWidth: "98vw",
|
||||
maxHeight: "95vh",
|
||||
padding: 0,
|
||||
gap: 0,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
@ -1593,7 +1599,7 @@ export const EditModal: React.FC<EditModalProps> = ({ className }) => {
|
|||
</div>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="[&::-webkit-scrollbar-thumb]:bg-muted/60 flex flex-1 justify-center overflow-y-auto [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-track]:bg-transparent">
|
||||
<div className="flex-1 min-h-0 flex items-start justify-center overflow-auto">
|
||||
{loading ? (
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<div className="text-center">
|
||||
|
|
@ -1608,42 +1614,41 @@ export const EditModal: React.FC<EditModalProps> = ({ className }) => {
|
|||
>
|
||||
<div
|
||||
data-screen-runtime="true"
|
||||
className="bg-card relative m-auto"
|
||||
className="relative bg-white"
|
||||
style={{
|
||||
width: screenDimensions?.width || 800,
|
||||
// 조건부 레이어가 활성화되면 높이 자동 확장
|
||||
width: `${screenDimensions?.width || 800}px`,
|
||||
minHeight: `${screenDimensions?.height || 600}px`,
|
||||
height: (() => {
|
||||
const baseHeight = (screenDimensions?.height || 600) + 30;
|
||||
const baseHeight = screenDimensions?.height || 600;
|
||||
if (activeConditionalComponents.length > 0) {
|
||||
// 조건부 레이어 컴포넌트 중 가장 아래 위치 계산
|
||||
const offsetY = screenDimensions?.offsetY || 0;
|
||||
let maxBottom = 0;
|
||||
activeConditionalComponents.forEach((comp) => {
|
||||
const y = parseFloat(comp.position?.y?.toString() || "0") - offsetY + 30;
|
||||
const y = parseFloat(comp.position?.y?.toString() || "0") - offsetY;
|
||||
const h = parseFloat(comp.size?.height?.toString() || "40");
|
||||
maxBottom = Math.max(maxBottom, y + h);
|
||||
});
|
||||
return Math.max(baseHeight, maxBottom + 20); // 20px 여백
|
||||
return `${Math.max(baseHeight, maxBottom + 20)}px`;
|
||||
}
|
||||
return baseHeight;
|
||||
return `${baseHeight}px`;
|
||||
})(),
|
||||
transformOrigin: "center center",
|
||||
maxWidth: "100%",
|
||||
overflow: "visible",
|
||||
}}
|
||||
>
|
||||
{/* 기본 레이어 컴포넌트 렌더링 */}
|
||||
{screenData.components.map((component) => {
|
||||
// 컴포넌트 위치를 offset만큼 조정
|
||||
const offsetX = screenDimensions?.offsetX || 0;
|
||||
const offsetY = screenDimensions?.offsetY || 0;
|
||||
const labelSpace = 30; // 라벨 공간 (입력 필드 위 -top-6 라벨용)
|
||||
// screenResolution이 있으면 offsetY=0이므로 디자이너 좌표 그대로 사용
|
||||
// offsetY > 0 (자동 계산)일 때만 라벨 공간 보정
|
||||
const labelSpace = offsetY > 0 ? 30 : 0;
|
||||
|
||||
const adjustedComponent = {
|
||||
...component,
|
||||
position: {
|
||||
...component.position,
|
||||
x: parseFloat(component.position?.x?.toString() || "0") - offsetX,
|
||||
y: parseFloat(component.position?.y?.toString() || "0") - offsetY + labelSpace, // 라벨 공간 추가
|
||||
y: parseFloat(component.position?.y?.toString() || "0") - offsetY + labelSpace,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -1709,11 +1714,11 @@ export const EditModal: React.FC<EditModalProps> = ({ className }) => {
|
|||
);
|
||||
})}
|
||||
|
||||
{/* 🆕 조건부 레이어 컴포넌트 렌더링 */}
|
||||
{/* 조건부 레이어 컴포넌트 렌더링 */}
|
||||
{activeConditionalComponents.map((component) => {
|
||||
const offsetX = screenDimensions?.offsetX || 0;
|
||||
const offsetY = screenDimensions?.offsetY || 0;
|
||||
const labelSpace = 30;
|
||||
const labelSpace = offsetY > 0 ? 30 : 0;
|
||||
|
||||
const adjustedComponent = {
|
||||
...component,
|
||||
|
|
|
|||
|
|
@ -89,12 +89,12 @@ function formatTel(value: string): string {
|
|||
return `${digits.slice(0, 4)}-${digits.slice(4, 8)}`;
|
||||
}
|
||||
|
||||
// 서울: 02 → 2-4-4
|
||||
// 서울: 02 → 9자리 2-3-4, 10자리 2-4-4
|
||||
if (digits.startsWith("02")) {
|
||||
if (digits.length <= 2) return digits;
|
||||
if (digits.length <= 6) return `${digits.slice(0, 2)}-${digits.slice(2)}`;
|
||||
if (digits.length <= 10) return `${digits.slice(0, 2)}-${digits.slice(2, 6)}-${digits.slice(6)}`;
|
||||
return `${digits.slice(0, 2)}-${digits.slice(2, 6)}-${digits.slice(6, 10)}`;
|
||||
if (digits.length <= 5) return `${digits.slice(0, 2)}-${digits.slice(2)}`;
|
||||
const mid = digits.length >= 10 ? 4 : 3;
|
||||
return `${digits.slice(0, 2)}-${digits.slice(2, 2 + mid)}-${digits.slice(2 + mid, 2 + mid + 4)}`;
|
||||
}
|
||||
|
||||
// 안심번호: 050x → 4-4-4
|
||||
|
|
@ -1228,7 +1228,7 @@ export const V2Input = forwardRef<HTMLDivElement, V2InputProps>((props, ref) =>
|
|||
ref={ref}
|
||||
id={id}
|
||||
className={cn(
|
||||
"flex gap-1",
|
||||
"flex",
|
||||
labelPos === "left" ? "flex-row items-center" : "flex-row-reverse items-center",
|
||||
)}
|
||||
style={{
|
||||
|
|
|
|||
|
|
@ -1291,7 +1291,7 @@ export const V2Select = forwardRef<HTMLDivElement, V2SelectProps>((props, ref) =
|
|||
ref={ref}
|
||||
id={id}
|
||||
className={cn(
|
||||
"flex gap-1",
|
||||
"flex",
|
||||
labelPos === "left" ? "flex-row items-center" : "flex-row-reverse items-center",
|
||||
isDesignMode && "pointer-events-none",
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -808,12 +808,10 @@ export const DynamicComponentRenderer: React.FC<DynamicComponentRendererProps> =
|
|||
? component.style?.labelText || (component as any).label || component.componentConfig?.label
|
||||
: undefined;
|
||||
|
||||
// 🔧 수평 라벨(left/right) 감지 → 런타임에서만 외부 flex 컨테이너로 라벨 처리
|
||||
// 디자인 모드에서는 V2 컴포넌트가 자체적으로 라벨을 렌더링 (height 체인 문제 방지)
|
||||
// 🔧 수평 라벨(left/right) 감지 → 외부 absolute 래퍼로 라벨 처리 (카테고리 셀렉트와 동일 방식)
|
||||
const labelPosition = component.style?.labelPosition;
|
||||
const isV2Component = componentType?.startsWith("v2-");
|
||||
const needsExternalHorizLabel = !!(
|
||||
!props.isDesignMode &&
|
||||
isV2Component &&
|
||||
effectiveLabel &&
|
||||
(labelPosition === "left" || labelPosition === "right")
|
||||
|
|
|
|||
Loading…
Reference in New Issue