Merge branch 'mhkim-node' of http://39.117.244.52:3000/kjs/ERP-node into jskim-node
This commit is contained in:
commit
ba39ebf341
|
|
@ -153,6 +153,7 @@ backend-node/uploads/
|
|||
uploads/
|
||||
*.jpg
|
||||
*.jpeg
|
||||
*.png
|
||||
*.gif
|
||||
*.pdf
|
||||
*.doc
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 329 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 342 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
|
|
@ -402,18 +402,9 @@ select {
|
|||
/* 필요시 특정 컴포넌트에 대한 스타일 오버라이드를 여기에 추가 */
|
||||
/* 예: Calendar, Table 등의 미세 조정 */
|
||||
|
||||
/* 모바일에서 테이블 레이아웃 고정 (화면 밖으로 넘어가지 않도록) */
|
||||
@media (max-width: 639px) {
|
||||
.table-mobile-fixed {
|
||||
table-layout: fixed;
|
||||
}
|
||||
}
|
||||
|
||||
/* 데스크톱에서 테이블 레이아웃 자동 (기본값이지만 명시적으로 설정) */
|
||||
@media (min-width: 640px) {
|
||||
.table-mobile-fixed {
|
||||
table-layout: auto;
|
||||
}
|
||||
/* 테이블 레이아웃 고정 (셀 내용이 영역을 벗어나지 않도록) */
|
||||
.table-mobile-fixed {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
/* 그리드선 숨기기 */
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ const RealtimePreviewDynamicComponent: React.FC<RealtimePreviewProps> = ({
|
|||
const needsStripBorder = isV2HorizLabel || isButtonComponent;
|
||||
const safeComponentStyle = needsStripBorder
|
||||
? (() => {
|
||||
const { borderWidth, borderColor, borderStyle, border, borderRadius, ...rest } = componentStyle as any;
|
||||
const { borderWidth, borderColor, borderStyle, border, ...rest } = componentStyle as any;
|
||||
return rest;
|
||||
})()
|
||||
: componentStyle;
|
||||
|
|
|
|||
|
|
@ -2670,7 +2670,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
<td
|
||||
key={colIdx}
|
||||
className="px-3 py-2 text-sm whitespace-nowrap text-foreground"
|
||||
style={{ textAlign: col.align || "left" }}
|
||||
style={{ textAlign: col.align || "left", overflow: "hidden", textOverflow: "ellipsis" }}
|
||||
>
|
||||
{formatCellValue(
|
||||
col.name,
|
||||
|
|
@ -2732,7 +2732,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
<td
|
||||
key={colIdx}
|
||||
className="px-3 py-2 text-sm whitespace-nowrap text-foreground"
|
||||
style={{ textAlign: col.align || "left" }}
|
||||
style={{ textAlign: col.align || "left", overflow: "hidden", textOverflow: "ellipsis" }}
|
||||
>
|
||||
{formatCellValue(
|
||||
col.name,
|
||||
|
|
@ -3415,7 +3415,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
<td
|
||||
key={colIdx}
|
||||
className="px-3 py-2 text-sm whitespace-nowrap text-foreground"
|
||||
style={{ textAlign: col.align || "left" }}
|
||||
style={{ textAlign: col.align || "left", overflow: "hidden", textOverflow: "ellipsis" }}
|
||||
>
|
||||
{formatCellValue(
|
||||
col.name,
|
||||
|
|
|
|||
|
|
@ -379,12 +379,33 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
}
|
||||
}, [tableConfig.selectedTable, currentUserId]);
|
||||
|
||||
// columnVisibility 변경 시 컬럼 순서 및 가시성 적용
|
||||
// columnVisibility 변경 시 컬럼 순서, 가시성, 너비 적용
|
||||
useEffect(() => {
|
||||
if (columnVisibility.length > 0) {
|
||||
const newOrder = columnVisibility.map((cv) => cv.columnName).filter((name) => name !== "__checkbox__"); // 체크박스 제외
|
||||
setColumnOrder(newOrder);
|
||||
|
||||
// 너비 적용
|
||||
const newWidths: Record<string, number> = {};
|
||||
columnVisibility.forEach((cv) => {
|
||||
if (cv.width) {
|
||||
newWidths[cv.columnName] = cv.width;
|
||||
}
|
||||
});
|
||||
if (Object.keys(newWidths).length > 0) {
|
||||
setColumnWidths((prev) => ({ ...prev, ...newWidths }));
|
||||
|
||||
// table_column_widths_* localStorage도 동기화 (초기 너비 로드 시 올바른 값 사용)
|
||||
if (tableConfig.selectedTable && userId) {
|
||||
const widthsKey = `table_column_widths_${tableConfig.selectedTable}_${userId}`;
|
||||
try {
|
||||
const existing = localStorage.getItem(widthsKey);
|
||||
const merged = existing ? { ...JSON.parse(existing), ...newWidths } : newWidths;
|
||||
localStorage.setItem(widthsKey, JSON.stringify(merged));
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
|
||||
// localStorage에 저장 (사용자별)
|
||||
if (tableConfig.selectedTable && currentUserId) {
|
||||
const storageKey = `table_column_visibility_${tableConfig.selectedTable}_${currentUserId}`;
|
||||
|
|
|
|||
|
|
@ -570,6 +570,8 @@ export const ButtonPrimaryComponent: React.FC<ButtonPrimaryComponentProps> = ({
|
|||
...restComponentStyle,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
borderRadius: _br || "0.5rem",
|
||||
overflow: "hidden",
|
||||
};
|
||||
|
||||
// 디자인 모드 스타일
|
||||
|
|
|
|||
|
|
@ -3607,7 +3607,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
<td
|
||||
key={colIdx}
|
||||
className="px-3 py-2 text-sm whitespace-nowrap text-foreground"
|
||||
style={{ textAlign: col.align || "left" }}
|
||||
style={{ textAlign: col.align || "left", overflow: "hidden", textOverflow: "ellipsis" }}
|
||||
>
|
||||
{formatCellValue(
|
||||
col.name,
|
||||
|
|
@ -3704,7 +3704,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
<td
|
||||
key={colIdx}
|
||||
className="px-3 py-2 text-sm whitespace-nowrap text-foreground"
|
||||
style={{ textAlign: col.align || "left" }}
|
||||
style={{ textAlign: col.align || "left", overflow: "hidden", textOverflow: "ellipsis" }}
|
||||
>
|
||||
{formatCellValue(
|
||||
col.name,
|
||||
|
|
@ -4201,7 +4201,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
onClick={() => toggleRightItemExpansion(`tab_${activeTabIndex}_${tabItemId}`)}
|
||||
>
|
||||
{tabSummaryColumns.map((col: any) => (
|
||||
<td key={col.name} className="px-3 py-2 text-xs">
|
||||
<td key={col.name} className="px-3 py-2 text-xs" style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
|
||||
{col.type === "progress"
|
||||
? renderProgressCell(col, item, selectedLeftItem)
|
||||
: formatCellValue(
|
||||
|
|
@ -4317,7 +4317,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
onClick={() => toggleRightItemExpansion(`tab_${activeTabIndex}_${tabItemId}`)}
|
||||
>
|
||||
{listSummaryColumns.map((col: any) => (
|
||||
<td key={col.name} className="px-3 py-2 text-xs">
|
||||
<td key={col.name} className="px-3 py-2 text-xs" style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
|
||||
{col.type === "progress"
|
||||
? renderProgressCell(col, item, selectedLeftItem)
|
||||
: formatCellValue(
|
||||
|
|
@ -4709,8 +4709,8 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
{columnsToShow.map((col, colIdx) => (
|
||||
<td
|
||||
key={colIdx}
|
||||
className="px-3 py-2 text-xs whitespace-nowrap"
|
||||
style={{ textAlign: col.align || "left" }}
|
||||
className="px-3 py-2 text-xs"
|
||||
style={{ textAlign: col.align || "left", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}
|
||||
>
|
||||
{col.type === "progress"
|
||||
? renderProgressCell(col, item, selectedLeftItem)
|
||||
|
|
@ -4856,7 +4856,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
|
|||
onClick={() => toggleRightItemExpansion(itemId)}
|
||||
>
|
||||
{columnsToDisplay.map((col) => (
|
||||
<td key={col.name} className="px-3 py-2 text-xs">
|
||||
<td key={col.name} className="px-3 py-2 text-xs" style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
|
||||
{formatCellValue(
|
||||
col.name,
|
||||
getEntityJoinValue(item, col.name),
|
||||
|
|
|
|||
|
|
@ -521,12 +521,33 @@ export const TableListComponent: React.FC<TableListComponentProps> = ({
|
|||
}
|
||||
}, [tableConfig.selectedTable, currentUserId]);
|
||||
|
||||
// columnVisibility 변경 시 컬럼 순서 및 가시성 적용
|
||||
// columnVisibility 변경 시 컬럼 순서, 가시성, 너비 적용
|
||||
useEffect(() => {
|
||||
if (columnVisibility.length > 0) {
|
||||
const newOrder = columnVisibility.map((cv) => cv.columnName).filter((name) => name !== "__checkbox__"); // 체크박스 제외
|
||||
setColumnOrder(newOrder);
|
||||
|
||||
// 너비 적용
|
||||
const newWidths: Record<string, number> = {};
|
||||
columnVisibility.forEach((cv) => {
|
||||
if (cv.width) {
|
||||
newWidths[cv.columnName] = cv.width;
|
||||
}
|
||||
});
|
||||
if (Object.keys(newWidths).length > 0) {
|
||||
setColumnWidths((prev) => ({ ...prev, ...newWidths }));
|
||||
|
||||
// table_column_widths_* localStorage도 동기화 (초기 너비 로드 시 올바른 값 사용)
|
||||
if (tableConfig.selectedTable && userId) {
|
||||
const widthsKey = `table_column_widths_${tableConfig.selectedTable}_${userId}`;
|
||||
try {
|
||||
const existing = localStorage.getItem(widthsKey);
|
||||
const merged = existing ? { ...JSON.parse(existing), ...newWidths } : newWidths;
|
||||
localStorage.setItem(widthsKey, JSON.stringify(merged));
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
|
||||
// localStorage에 저장 (사용자별)
|
||||
if (tableConfig.selectedTable && currentUserId) {
|
||||
const storageKey = `table_column_visibility_${tableConfig.selectedTable}_${currentUserId}`;
|
||||
|
|
|
|||
Loading…
Reference in New Issue