310 lines
7.9 KiB
JavaScript
310 lines
7.9 KiB
JavaScript
|
|
/**
|
||
|
|
* 레이아웃 표준 데이터 초기화 스크립트
|
||
|
|
* 기본 레이아웃들을 layout_standards 테이블에 삽입합니다.
|
||
|
|
*/
|
||
|
|
|
||
|
|
const { PrismaClient } = require("@prisma/client");
|
||
|
|
|
||
|
|
const prisma = new PrismaClient();
|
||
|
|
|
||
|
|
// 기본 레이아웃 데이터
|
||
|
|
const PREDEFINED_LAYOUTS = [
|
||
|
|
{
|
||
|
|
layout_code: "GRID_2X2_001",
|
||
|
|
layout_name: "2x2 그리드",
|
||
|
|
layout_name_eng: "2x2 Grid",
|
||
|
|
description: "2행 2열의 균등한 그리드 레이아웃입니다.",
|
||
|
|
layout_type: "grid",
|
||
|
|
category: "basic",
|
||
|
|
icon_name: "grid",
|
||
|
|
default_size: { width: 800, height: 600 },
|
||
|
|
layout_config: {
|
||
|
|
grid: { rows: 2, columns: 2, gap: 16 },
|
||
|
|
},
|
||
|
|
zones_config: [
|
||
|
|
{
|
||
|
|
id: "zone1",
|
||
|
|
name: "상단 좌측",
|
||
|
|
position: { row: 0, column: 0 },
|
||
|
|
size: { width: "50%", height: "50%" },
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "zone2",
|
||
|
|
name: "상단 우측",
|
||
|
|
position: { row: 0, column: 1 },
|
||
|
|
size: { width: "50%", height: "50%" },
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "zone3",
|
||
|
|
name: "하단 좌측",
|
||
|
|
position: { row: 1, column: 0 },
|
||
|
|
size: { width: "50%", height: "50%" },
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "zone4",
|
||
|
|
name: "하단 우측",
|
||
|
|
position: { row: 1, column: 1 },
|
||
|
|
size: { width: "50%", height: "50%" },
|
||
|
|
},
|
||
|
|
],
|
||
|
|
sort_order: 1,
|
||
|
|
is_active: "Y",
|
||
|
|
is_public: "Y",
|
||
|
|
company_code: "DEFAULT",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
layout_code: "FORM_TWO_COLUMN_001",
|
||
|
|
layout_name: "2단 폼 레이아웃",
|
||
|
|
layout_name_eng: "Two Column Form",
|
||
|
|
description: "좌우 2단으로 구성된 폼 레이아웃입니다.",
|
||
|
|
layout_type: "grid",
|
||
|
|
category: "form",
|
||
|
|
icon_name: "columns",
|
||
|
|
default_size: { width: 800, height: 400 },
|
||
|
|
layout_config: {
|
||
|
|
grid: { rows: 1, columns: 2, gap: 24 },
|
||
|
|
},
|
||
|
|
zones_config: [
|
||
|
|
{
|
||
|
|
id: "left",
|
||
|
|
name: "좌측 입력 영역",
|
||
|
|
position: { row: 0, column: 0 },
|
||
|
|
size: { width: "50%", height: "100%" },
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "right",
|
||
|
|
name: "우측 입력 영역",
|
||
|
|
position: { row: 0, column: 1 },
|
||
|
|
size: { width: "50%", height: "100%" },
|
||
|
|
},
|
||
|
|
],
|
||
|
|
sort_order: 2,
|
||
|
|
is_active: "Y",
|
||
|
|
is_public: "Y",
|
||
|
|
company_code: "DEFAULT",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
layout_code: "FLEXBOX_ROW_001",
|
||
|
|
layout_name: "가로 플렉스박스",
|
||
|
|
layout_name_eng: "Horizontal Flexbox",
|
||
|
|
description: "가로 방향으로 배치되는 플렉스박스 레이아웃입니다.",
|
||
|
|
layout_type: "flexbox",
|
||
|
|
category: "basic",
|
||
|
|
icon_name: "flex",
|
||
|
|
default_size: { width: 800, height: 300 },
|
||
|
|
layout_config: {
|
||
|
|
flexbox: {
|
||
|
|
direction: "row",
|
||
|
|
justify: "flex-start",
|
||
|
|
align: "stretch",
|
||
|
|
wrap: "nowrap",
|
||
|
|
gap: 16,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
zones_config: [
|
||
|
|
{
|
||
|
|
id: "left",
|
||
|
|
name: "좌측 영역",
|
||
|
|
position: {},
|
||
|
|
size: { width: "50%", height: "100%" },
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "right",
|
||
|
|
name: "우측 영역",
|
||
|
|
position: {},
|
||
|
|
size: { width: "50%", height: "100%" },
|
||
|
|
},
|
||
|
|
],
|
||
|
|
sort_order: 3,
|
||
|
|
is_active: "Y",
|
||
|
|
is_public: "Y",
|
||
|
|
company_code: "DEFAULT",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
layout_code: "SPLIT_HORIZONTAL_001",
|
||
|
|
layout_name: "수평 분할",
|
||
|
|
layout_name_eng: "Horizontal Split",
|
||
|
|
description: "크기 조절이 가능한 수평 분할 레이아웃입니다.",
|
||
|
|
layout_type: "split",
|
||
|
|
category: "basic",
|
||
|
|
icon_name: "separator-horizontal",
|
||
|
|
default_size: { width: 800, height: 400 },
|
||
|
|
layout_config: {
|
||
|
|
split: {
|
||
|
|
direction: "horizontal",
|
||
|
|
ratio: [50, 50],
|
||
|
|
minSize: [200, 200],
|
||
|
|
resizable: true,
|
||
|
|
splitterSize: 4,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
zones_config: [
|
||
|
|
{
|
||
|
|
id: "left",
|
||
|
|
name: "좌측 패널",
|
||
|
|
position: {},
|
||
|
|
size: { width: "50%", height: "100%" },
|
||
|
|
isResizable: true,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "right",
|
||
|
|
name: "우측 패널",
|
||
|
|
position: {},
|
||
|
|
size: { width: "50%", height: "100%" },
|
||
|
|
isResizable: true,
|
||
|
|
},
|
||
|
|
],
|
||
|
|
sort_order: 4,
|
||
|
|
is_active: "Y",
|
||
|
|
is_public: "Y",
|
||
|
|
company_code: "DEFAULT",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
layout_code: "TABS_HORIZONTAL_001",
|
||
|
|
layout_name: "수평 탭",
|
||
|
|
layout_name_eng: "Horizontal Tabs",
|
||
|
|
description: "상단에 탭이 있는 탭 레이아웃입니다.",
|
||
|
|
layout_type: "tabs",
|
||
|
|
category: "navigation",
|
||
|
|
icon_name: "tabs",
|
||
|
|
default_size: { width: 800, height: 500 },
|
||
|
|
layout_config: {
|
||
|
|
tabs: {
|
||
|
|
position: "top",
|
||
|
|
variant: "default",
|
||
|
|
size: "md",
|
||
|
|
defaultTab: "tab1",
|
||
|
|
closable: false,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
zones_config: [
|
||
|
|
{
|
||
|
|
id: "tab1",
|
||
|
|
name: "첫 번째 탭",
|
||
|
|
position: {},
|
||
|
|
size: { width: "100%", height: "100%" },
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "tab2",
|
||
|
|
name: "두 번째 탭",
|
||
|
|
position: {},
|
||
|
|
size: { width: "100%", height: "100%" },
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "tab3",
|
||
|
|
name: "세 번째 탭",
|
||
|
|
position: {},
|
||
|
|
size: { width: "100%", height: "100%" },
|
||
|
|
},
|
||
|
|
],
|
||
|
|
sort_order: 5,
|
||
|
|
is_active: "Y",
|
||
|
|
is_public: "Y",
|
||
|
|
company_code: "DEFAULT",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
layout_code: "TABLE_WITH_FILTERS_001",
|
||
|
|
layout_name: "필터가 있는 테이블",
|
||
|
|
layout_name_eng: "Table with Filters",
|
||
|
|
description: "상단에 필터가 있고 하단에 테이블이 있는 레이아웃입니다.",
|
||
|
|
layout_type: "flexbox",
|
||
|
|
category: "table",
|
||
|
|
icon_name: "table",
|
||
|
|
default_size: { width: 1000, height: 600 },
|
||
|
|
layout_config: {
|
||
|
|
flexbox: {
|
||
|
|
direction: "column",
|
||
|
|
justify: "flex-start",
|
||
|
|
align: "stretch",
|
||
|
|
wrap: "nowrap",
|
||
|
|
gap: 16,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
zones_config: [
|
||
|
|
{
|
||
|
|
id: "filters",
|
||
|
|
name: "검색 필터",
|
||
|
|
position: {},
|
||
|
|
size: { width: "100%", height: "auto" },
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: "table",
|
||
|
|
name: "데이터 테이블",
|
||
|
|
position: {},
|
||
|
|
size: { width: "100%", height: "1fr" },
|
||
|
|
},
|
||
|
|
],
|
||
|
|
sort_order: 6,
|
||
|
|
is_active: "Y",
|
||
|
|
is_public: "Y",
|
||
|
|
company_code: "DEFAULT",
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
async function initializeLayoutStandards() {
|
||
|
|
try {
|
||
|
|
console.log("🏗️ 레이아웃 표준 데이터 초기화 시작...");
|
||
|
|
|
||
|
|
// 기존 데이터 확인
|
||
|
|
const existingLayouts = await prisma.layout_standards.count();
|
||
|
|
if (existingLayouts > 0) {
|
||
|
|
console.log(`⚠️ 이미 ${existingLayouts}개의 레이아웃이 존재합니다.`);
|
||
|
|
console.log(
|
||
|
|
"기존 데이터를 삭제하고 새로 생성하시겠습니까? (기본값: 건너뛰기)"
|
||
|
|
);
|
||
|
|
|
||
|
|
// 기존 데이터가 있으면 건너뛰기 (안전을 위해)
|
||
|
|
console.log("💡 기존 데이터를 유지하고 건너뜁니다.");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 데이터 삽입
|
||
|
|
let insertedCount = 0;
|
||
|
|
|
||
|
|
for (const layoutData of PREDEFINED_LAYOUTS) {
|
||
|
|
try {
|
||
|
|
await prisma.layout_standards.create({
|
||
|
|
data: {
|
||
|
|
...layoutData,
|
||
|
|
created_date: new Date(),
|
||
|
|
updated_date: new Date(),
|
||
|
|
created_by: "SYSTEM",
|
||
|
|
updated_by: "SYSTEM",
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
console.log(`✅ ${layoutData.layout_name} 생성 완료`);
|
||
|
|
insertedCount++;
|
||
|
|
} catch (error) {
|
||
|
|
console.error(`❌ ${layoutData.layout_name} 생성 실패:`, error.message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
console.log(
|
||
|
|
`🎉 레이아웃 표준 데이터 초기화 완료! (${insertedCount}/${PREDEFINED_LAYOUTS.length})`
|
||
|
|
);
|
||
|
|
} catch (error) {
|
||
|
|
console.error("❌ 레이아웃 표준 데이터 초기화 실패:", error);
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 스크립트 실행
|
||
|
|
if (require.main === module) {
|
||
|
|
initializeLayoutStandards()
|
||
|
|
.then(() => {
|
||
|
|
console.log("✨ 스크립트 실행 완료");
|
||
|
|
process.exit(0);
|
||
|
|
})
|
||
|
|
.catch((error) => {
|
||
|
|
console.error("💥 스크립트 실행 실패:", error);
|
||
|
|
process.exit(1);
|
||
|
|
})
|
||
|
|
.finally(async () => {
|
||
|
|
await prisma.$disconnect();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
module.exports = { initializeLayoutStandards };
|
||
|
|
|