Merge pull request 'feature/screen-management' (#182) from feature/screen-management into main
Reviewed-on: http://39.117.244.52:3000/kjs/ERP-node/pulls/182
This commit is contained in:
commit
2b3f883909
|
|
@ -610,16 +610,16 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
|||
const columnIndex = Math.round(effectiveX / (columnWidth + (gap || 16)));
|
||||
const snappedX = padding + columnIndex * (columnWidth + (gap || 16));
|
||||
|
||||
// Y 좌표는 20px 단위로 스냅
|
||||
// Y 좌표는 10px 단위로 스냅
|
||||
const effectiveY = newComp.position.y - padding;
|
||||
const rowIndex = Math.round(effectiveY / 20);
|
||||
const snappedY = padding + rowIndex * 20;
|
||||
const rowIndex = Math.round(effectiveY / 10);
|
||||
const snappedY = padding + rowIndex * 10;
|
||||
|
||||
// 크기도 외부 격자와 동일하게 스냅
|
||||
const fullColumnWidth = columnWidth + (gap || 16); // 외부 격자와 동일한 크기
|
||||
const widthInColumns = Math.max(1, Math.round(newComp.size.width / fullColumnWidth));
|
||||
const snappedWidth = widthInColumns * fullColumnWidth - (gap || 16); // gap 제거하여 실제 컴포넌트 크기
|
||||
const snappedHeight = Math.max(40, Math.round(newComp.size.height / 20) * 20);
|
||||
const snappedHeight = Math.max(10, Math.round(newComp.size.height / 10) * 10);
|
||||
|
||||
newComp.position = {
|
||||
x: Math.max(padding, snappedX), // 패딩만큼 최소 여백 확보
|
||||
|
|
|
|||
|
|
@ -961,27 +961,27 @@ const PropertiesPanelComponent: React.FC<PropertiesPanelProps> = ({
|
|||
|
||||
<div className="col-span-2">
|
||||
<Label htmlFor="height" className="text-sm font-medium">
|
||||
최소 높이 (40px 단위)
|
||||
최소 높이 (10px 단위)
|
||||
</Label>
|
||||
<div className="mt-1 flex items-center space-x-2">
|
||||
<Input
|
||||
id="height"
|
||||
type="number"
|
||||
min="1"
|
||||
max="20"
|
||||
value={Math.round((localInputs.height || 40) / 40)}
|
||||
max="100"
|
||||
value={Math.round((localInputs.height || 10) / 10)}
|
||||
onChange={(e) => {
|
||||
const rows = Math.max(1, Math.min(20, Number(e.target.value)));
|
||||
const newHeight = rows * 40;
|
||||
const units = Math.max(1, Math.min(100, Number(e.target.value)));
|
||||
const newHeight = units * 10;
|
||||
setLocalInputs((prev) => ({ ...prev, height: newHeight.toString() }));
|
||||
onUpdateProperty("size.height", newHeight);
|
||||
}}
|
||||
className="flex-1"
|
||||
/>
|
||||
<span className="text-sm text-gray-500">행 = {localInputs.height || 40}px</span>
|
||||
<span className="text-sm text-gray-500">단위 = {localInputs.height || 10}px</span>
|
||||
</div>
|
||||
<p className="mt-1 text-xs text-gray-500">
|
||||
1행 = 40px (현재 {Math.round((localInputs.height || 40) / 40)}행) - 내부 콘텐츠에 맞춰 늘어남
|
||||
1단위 = 10px (현재 {Math.round((localInputs.height || 10) / 10)}단위) - 내부 콘텐츠에 맞춰 늘어남
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -364,11 +364,11 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
|||
value={selectedComponent.size?.height || 0}
|
||||
onChange={(e) => {
|
||||
const value = parseInt(e.target.value) || 0;
|
||||
const roundedValue = Math.max(40, Math.round(value / 40) * 40);
|
||||
const roundedValue = Math.max(10, Math.round(value / 10) * 10);
|
||||
handleUpdate("size.height", roundedValue);
|
||||
}}
|
||||
step={40}
|
||||
placeholder="40"
|
||||
step={10}
|
||||
placeholder="10"
|
||||
className="h-6 w-full px-2 py-0 text-xs"
|
||||
style={{ fontSize: "12px" }}
|
||||
style={{ fontSize: "12px" }}
|
||||
|
|
|
|||
|
|
@ -1169,7 +1169,7 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-10" style={{ flex: 1, overflow: "hidden" }}>
|
||||
<div style={{ marginTop: `${tableConfig.filter?.bottomSpacing ?? 40}px`, flex: 1, overflow: "hidden" }}>
|
||||
<SingleTableWithSticky
|
||||
data={data}
|
||||
columns={visibleColumns}
|
||||
|
|
@ -1263,7 +1263,10 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
)}
|
||||
|
||||
{/* 테이블 컨테이너 */}
|
||||
<div className="flex-1 flex flex-col overflow-hidden w-full max-w-full mt-10">
|
||||
<div
|
||||
className="flex-1 flex flex-col overflow-hidden w-full max-w-full"
|
||||
style={{ marginTop: `${tableConfig.filter?.bottomSpacing ?? 40}px` }}
|
||||
>
|
||||
{/* 스크롤 영역 */}
|
||||
<div
|
||||
className="w-full max-w-full h-[400px] overflow-y-scroll overflow-x-auto bg-background sm:h-[500px]"
|
||||
|
|
|
|||
|
|
@ -1105,6 +1105,41 @@ export const TableListConfigPanel: React.FC<TableListConfigPanelProps> = ({
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 필터 간격 설정 */}
|
||||
{config.filter?.enabled && (
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold">필터 간격</h3>
|
||||
</div>
|
||||
<hr className="border-border" />
|
||||
<div className="space-y-1">
|
||||
<Label htmlFor="filterBottomSpacing" className="text-xs">
|
||||
필터와 리스트 사이 간격 (px)
|
||||
</Label>
|
||||
<Input
|
||||
id="filterBottomSpacing"
|
||||
type="number"
|
||||
value={config.filter?.bottomSpacing ?? 40}
|
||||
onChange={(e) => {
|
||||
const value = Math.max(0, Math.min(200, parseInt(e.target.value) || 40));
|
||||
handleChange("filter", {
|
||||
...config.filter,
|
||||
bottomSpacing: value,
|
||||
});
|
||||
}}
|
||||
min={0}
|
||||
max={200}
|
||||
step={10}
|
||||
placeholder="40"
|
||||
className="h-8 text-xs"
|
||||
/>
|
||||
<p className="text-[10px] text-muted-foreground">
|
||||
기본값: 40px (0-200px 범위, 10px 단위 권장)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ export const TableListDefinition = createComponentDefinition({
|
|||
filter: {
|
||||
enabled: true,
|
||||
filters: [], // 사용자가 설정할 필터 목록
|
||||
bottomSpacing: 40, // 필터와 리스트 사이 간격 (px)
|
||||
},
|
||||
|
||||
// 액션 설정
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ export interface FilterConfig {
|
|||
referenceColumn?: string;
|
||||
displayColumn?: string;
|
||||
}>;
|
||||
// 필터와 리스트 사이 간격 (px 단위, 기본: 40)
|
||||
bottomSpacing?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export function snapToGrid(position: Position, gridInfo: GridInfo, gridSettings:
|
|||
|
||||
// 격자 셀 크기 (컬럼 너비 + 간격을 하나의 격자 단위로 계산)
|
||||
const cellWidth = columnWidth + gap;
|
||||
const cellHeight = Math.max(40, gap * 2); // 행 높이를 더 크게 설정
|
||||
const cellHeight = 10; // 행 높이 10px 단위로 고정
|
||||
|
||||
// 패딩을 제외한 상대 위치
|
||||
const relativeX = position.x - padding;
|
||||
|
|
@ -92,9 +92,9 @@ export function snapSizeToGrid(size: Size, gridInfo: GridInfo, gridSettings: Gri
|
|||
|
||||
const snappedWidth = gridColumns * columnWidth + (gridColumns - 1) * gap;
|
||||
|
||||
// 높이는 동적 행 높이 단위로 스냅
|
||||
const rowHeight = Math.max(20, gap);
|
||||
const snappedHeight = Math.max(40, Math.round(size.height / rowHeight) * rowHeight);
|
||||
// 높이는 10px 단위로 스냅
|
||||
const rowHeight = 10;
|
||||
const snappedHeight = Math.max(10, Math.round(size.height / rowHeight) * rowHeight);
|
||||
|
||||
console.log(
|
||||
`📏 크기 스냅: ${size.width}px → ${snappedWidth}px (${gridColumns}컬럼, 컬럼너비:${columnWidth}px, 간격:${gap}px)`,
|
||||
|
|
@ -175,7 +175,7 @@ export function generateGridLines(
|
|||
|
||||
// 격자 셀 크기 (스냅 로직과 동일하게)
|
||||
const cellWidth = columnWidth + gap;
|
||||
const cellHeight = Math.max(40, gap * 2);
|
||||
const cellHeight = 10; // 행 높이 10px 단위로 고정
|
||||
|
||||
// 세로 격자선
|
||||
const verticalLines: number[] = [];
|
||||
|
|
@ -254,8 +254,8 @@ export function alignGroupChildrenToGrid(
|
|||
const columnIndex = Math.round(effectiveX / (columnWidth + gap));
|
||||
const snappedX = padding + columnIndex * (columnWidth + gap);
|
||||
|
||||
// Y 좌표는 동적 행 높이 단위로 스냅
|
||||
const rowHeight = Math.max(20, gap);
|
||||
// Y 좌표는 10px 단위로 스냅
|
||||
const rowHeight = 10;
|
||||
const effectiveY = child.position.y - padding;
|
||||
const rowIndex = Math.round(effectiveY / rowHeight);
|
||||
const snappedY = padding + rowIndex * rowHeight;
|
||||
|
|
@ -264,7 +264,7 @@ export function alignGroupChildrenToGrid(
|
|||
const fullColumnWidth = columnWidth + gap; // 외부 격자와 동일한 크기
|
||||
const widthInColumns = Math.max(1, Math.round(child.size.width / fullColumnWidth));
|
||||
const snappedWidth = widthInColumns * fullColumnWidth - gap; // gap 제거하여 실제 컴포넌트 크기
|
||||
const snappedHeight = Math.max(40, Math.round(child.size.height / rowHeight) * rowHeight);
|
||||
const snappedHeight = Math.max(10, Math.round(child.size.height / rowHeight) * rowHeight);
|
||||
|
||||
const snappedChild = {
|
||||
...child,
|
||||
|
|
@ -310,7 +310,7 @@ export function calculateOptimalGroupSize(
|
|||
gridSettings: GridSettings,
|
||||
): Size {
|
||||
if (children.length === 0) {
|
||||
return { width: gridInfo.columnWidth * 2, height: 40 * 2 };
|
||||
return { width: gridInfo.columnWidth * 2, height: 10 * 4 };
|
||||
}
|
||||
|
||||
console.log("📏 calculateOptimalGroupSize 시작:", {
|
||||
|
|
|
|||
Loading…
Reference in New Issue