@opsnow-mcp/opsnow-mcp-common-ui-server 1.0.21 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/components/data/icon-names.js +129 -0
- package/build/components/examples/opsnow-common-calendar-examples-data.js +48 -0
- package/build/components/examples/opsnow-common-chart-examples-data.js +6590 -0
- package/build/components/examples/opsnow-common-data-status-examples-data.js +65 -0
- package/build/components/examples/opsnow-common-file-upload-examples-data.js +95 -0
- package/build/components/examples/opsnow-common-forms-examples-data.js +1715 -0
- package/build/components/examples/opsnow-common-grid-examples-data.js +2389 -0
- package/build/components/examples/opsnow-common-icons-examples-data.js +72 -0
- package/build/components/examples/opsnow-common-layout-examples-data.js +97 -0
- package/build/components/examples/opsnow-common-notification-examples-data.js +78 -0
- package/build/components/examples/opsnow-common-pagination-examples-data.js +82 -0
- package/build/components/examples/opsnow-common-popup-examples-data.js +205 -0
- package/build/components/examples/opsnow-common-progress-examples-data.js +86 -0
- package/build/components/examples/opsnow-common-select-examples-data.js +121 -0
- package/build/components/examples/opsnow-common-stepper-examples-data.js +180 -0
- package/build/components/examples/opsnow-common-storage-examples-data.js +8 -0
- package/build/components/examples/opsnow-common-tab-examples-data.js +87 -0
- package/build/components/examples/opsnow-common-toast-popup-examples-data.js +129 -0
- package/build/components/examples/opsnow-common-tooltip-examples-data.js +80 -0
- package/build/components/examples/opsnow-common-typography-examples-data.js +366 -0
- package/build/components/opsnow-common-calendar.js +228 -0
- package/build/components/opsnow-common-chart.js +1643 -0
- package/build/components/opsnow-common-data-status.js +116 -0
- package/build/components/opsnow-common-examples.js +109 -0
- package/build/components/opsnow-common-file-upload.js +57 -0
- package/build/components/opsnow-common-forms.js +1009 -0
- package/build/components/opsnow-common-grid.js +352 -0
- package/build/components/opsnow-common-icons.js +139 -0
- package/build/components/opsnow-common-layout.js +141 -0
- package/build/components/opsnow-common-notification.js +110 -0
- package/build/components/opsnow-common-pagination.js +164 -0
- package/build/components/opsnow-common-popup.js +71 -0
- package/build/components/opsnow-common-progress.js +177 -0
- package/build/components/opsnow-common-select.js +135 -0
- package/build/components/opsnow-common-stepper.js +72 -0
- package/build/components/opsnow-common-tab.js +111 -0
- package/build/components/opsnow-common-toast-popup.js +135 -0
- package/build/components/opsnow-common-tooltip.js +204 -0
- package/build/components/opsnow-common-typography.js +93 -0
- package/build/index.js +135 -0
- package/package.json +1 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// Notification 컴포넌트 관련 스키마 정의
|
|
3
|
+
export const NotificationSchema = z.object({
|
|
4
|
+
severity: z
|
|
5
|
+
.enum([
|
|
6
|
+
"infoSuccess",
|
|
7
|
+
"infoError",
|
|
8
|
+
"infoWarning",
|
|
9
|
+
"success",
|
|
10
|
+
"error",
|
|
11
|
+
"warning",
|
|
12
|
+
"info",
|
|
13
|
+
])
|
|
14
|
+
.describe(`알림 타입(색상/스타일):
|
|
15
|
+
- "info": 회색/ 흰색 배경 + 배경과 동일한 색상의 아이콘 + 컬러 라인 없음
|
|
16
|
+
- "infoSuccess": 흰/회색 배경 + 왼쪽 초록 컬러 라인 + 초록 아이콘(placement: page 전용)
|
|
17
|
+
- "infoWarning": 흰/회색 배경 + 왼쪽 주황 컬러 라인 + 주황 아이콘(placement: page 전용)
|
|
18
|
+
- "infoError": 흰/회색 배경 + 왼쪽 빨강 컬러 라인 + 빨강 아이콘(placement: page 전용)
|
|
19
|
+
- "success": 박스 내 초록 배경
|
|
20
|
+
- "error": 박스 내 빨강 배경
|
|
21
|
+
- "warning": 박스 내 주황 배경
|
|
22
|
+
※ infoSuccess/infoWarning/infoError는 배경이 항상 흰색/회색이고, 컬러 라인 색상만 다릅니다.
|
|
23
|
+
※ card 타입에서는 infoSuccess/infoWarning/infoError를 사용하지 않습니다.`),
|
|
24
|
+
useTitle: z.boolean().optional().describe("제목 사용 여부 - title 옵션 사용 시 true(true시 사용 예시 : useTitle (useTitle={true}처럼 쓰지 않음.)"),
|
|
25
|
+
title: z.string().optional().describe("볼드 처리 된 알림 제목 - 해당 옵션 사용하는 경우 useTitle true 필수"),
|
|
26
|
+
message: z.string().optional().describe("제목 아래 알림 메시지 내용"),
|
|
27
|
+
placement: z
|
|
28
|
+
.enum(["card", "page"])
|
|
29
|
+
.optional()
|
|
30
|
+
.describe(`알림 표시 위치/스타일:
|
|
31
|
+
- "page": 배경은 항상 회색/흰색, 왼쪽 컬러 라인 색상만 타입에 따라 변함. 모서리가 둥근 경우 사용.
|
|
32
|
+
- "card": 배경색 자체가 타입(success/ error/ warning/ info)에 따라 컬러풀하게 채워짐.
|
|
33
|
+
※ infoSuccess/infoWarning/infoError는 "page"에서만 사용 가능(배경 흰색, 컬러 라인 색상만 변함).
|
|
34
|
+
※ "card"는 배경색이 타입에 따라 바뀌며, infoSuccess/infoWarning/infoError는 지원하지 않음.`),
|
|
35
|
+
closable: z.boolean().optional().describe("수동 닫기 가능 여부"),
|
|
36
|
+
bgWhite: z
|
|
37
|
+
.boolean()
|
|
38
|
+
.default(false)
|
|
39
|
+
.describe("배경 흰색 여부 - severity : info 일때만 사용(true시 사용 예시 : bgWhite (bgWhite={true}처럼 쓰지 않음.)"),
|
|
40
|
+
action: z.string().optional().describe("액션 버튼 코드 - 예시: <OpsnowCommonButton label='확인' />"),
|
|
41
|
+
isCustom: z
|
|
42
|
+
.boolean()
|
|
43
|
+
.default(false)
|
|
44
|
+
.describe("커스텀 action 버튼 사용 여부 - action랑 같이 사용, default 버튼이 아닌 custom시 사용"),
|
|
45
|
+
}).describe("알림 컴포넌트 - 박스 형태로 알림을 제공하는 컴포넌트. 알림 컴포넌트 내에 버튼 사용 시 (action, isCustom 옵션 사용 시) 반드시 버튼 컴포넌트 동시 호출 하여 action에 OpsnowCommonButton 컴포넌트를 string으로 전달");
|
|
46
|
+
// Notification 컴포넌트 함수 - 배열 반환
|
|
47
|
+
export function createNotificationComponent() {
|
|
48
|
+
return [
|
|
49
|
+
{
|
|
50
|
+
name: "createNotification",
|
|
51
|
+
description: `알림 컴포넌트 - 박스 형태로 알림을 제공하는 컴포넌트.
|
|
52
|
+
알림 컴포넌트 내에 버튼 생성 시 action, isCustom 옵션 사용(버튼 컴포넌트 동시 호출 하여 action에 OpsnowCommonButton 컴포넌트를 string으로 전달)
|
|
53
|
+
**주의사항**:
|
|
54
|
+
message 옵션 사용 시 반드시 알림 컴포넌트 내부(children)에 메시지 작성(props로 사용 금지)
|
|
55
|
+
- '>' 버튼이 있는 경우 이동하는 버튼이며 placement가 card인 경우 버튼은 자동으로 생성됨(따로 버튼 추가 필요 없음)
|
|
56
|
+
- 좌측 외부 컬러 라인, 아이콘 색상 존재하고 모서리가 둥근 경우 알림 컴포넌트(severity:infoXXX, placement: page)사용
|
|
57
|
+
**import**:
|
|
58
|
+
import { useCommonComponents } from '@opsnow-common/opsnow-finops-common-ui-loader'
|
|
59
|
+
const { OpsnowCommonButton, OpsnowCommonNotification } = useCommonComponents()
|
|
60
|
+
`,
|
|
61
|
+
parameters: NotificationSchema,
|
|
62
|
+
handler: async (args) => {
|
|
63
|
+
// 알림 컴포넌트 로직 구현
|
|
64
|
+
const props = [];
|
|
65
|
+
if (args.severity) {
|
|
66
|
+
props.push(`severity="${args.severity}"`);
|
|
67
|
+
}
|
|
68
|
+
if (args.title && args.useTitle) {
|
|
69
|
+
props.push("useTitle");
|
|
70
|
+
props.push(`title="${args.title}"`);
|
|
71
|
+
}
|
|
72
|
+
if (args.placement) {
|
|
73
|
+
props.push(`placement="${args.placement}"`);
|
|
74
|
+
}
|
|
75
|
+
if (args.bgWhite) {
|
|
76
|
+
props.push("bgWhite");
|
|
77
|
+
}
|
|
78
|
+
if (args.action) {
|
|
79
|
+
if (args.isCustom && args.closable && args.placement === `card`) {
|
|
80
|
+
props.push(`customActionBtn={${args.action}}`);
|
|
81
|
+
}
|
|
82
|
+
else if (args.isCustom && !args.placement) {
|
|
83
|
+
props.push(`customActionBtn={${args.action}}`);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
props.push(`action={${args.action}}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (args.closable) {
|
|
90
|
+
props.push(`onClose={() => {\n // 닫힐때 실행할 함수\n // 예시: setOpen(${!args.closable}})\n}}`);
|
|
91
|
+
}
|
|
92
|
+
let code = `<OpsnowCommonNotification\n ${props.join("\n ")}>
|
|
93
|
+
// 내부 메시지가 있는경우 children으로 작성
|
|
94
|
+
// title은 props로 사용
|
|
95
|
+
${args.message ? args.message : ""}</OpsnowCommonNotification>`;
|
|
96
|
+
if (args.closable) {
|
|
97
|
+
code = `const [open, setOpen] = useState(${args.closable});\n{open && (${code})}`;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
content: [
|
|
101
|
+
{
|
|
102
|
+
type: "text",
|
|
103
|
+
text: `\`\`\`jsx\n${code}\n\`\`\``,
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// Pagination 컴포넌트 관련 스키마 정의
|
|
3
|
+
export const PaginationSchema = z.object({
|
|
4
|
+
page: z.number().describe("현재 페이지 번호"),
|
|
5
|
+
rowsPerPage: z.number().optional().default(10).describe("페이지당 항목 수"),
|
|
6
|
+
size: z
|
|
7
|
+
.enum(["medium", "small", "large"])
|
|
8
|
+
.describe("페이지네이션 컴포넌트 크기 (medium, small, large)"),
|
|
9
|
+
rowsPerPageOptions: z
|
|
10
|
+
.array(z.object({
|
|
11
|
+
label: z.string().describe("페이지 크기 옵션 라벨"),
|
|
12
|
+
value: z.number().describe("페이지 크기 옵션 값"),
|
|
13
|
+
}))
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("페이지 크기 옵션들 - 한 페이지에 몇 개 씩 보여줄지"),
|
|
16
|
+
list: z.array(z.string()).optional().describe("페이지네이션에 표시할 데이터"),
|
|
17
|
+
onRowsPerPageChange: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("rowsPerPage가 변경될 때 호출되는 핸들러 함수명 - 함수명만 필요함"),
|
|
21
|
+
isLocale: z.boolean().default(true).describe("locale(언어) 설정 여부"),
|
|
22
|
+
onChangePageNum: z
|
|
23
|
+
.string()
|
|
24
|
+
.optional()
|
|
25
|
+
.describe("페이지 번호(pageNum) 변경되었을때 핸들러 함수. 함수 내부 코드(문자열)로 전달하세요. 예시: console.log('페이지 번호가', pageNum, '으로 변경되었습니다.')"),
|
|
26
|
+
onChangePageSize: z
|
|
27
|
+
.string()
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("페이지당 항목수 변경(pageSize) 및 현재 페이지(pageNum) 변경되었을때 핸들러 함수. 함수 내부 코드(문자열)로 전달하세요. 예시: console.log('페이지당 항목 수가',pageSize,'로 변경되고, 현재 페이지는',pageNum,'입니다.')"),
|
|
30
|
+
onNext: z
|
|
31
|
+
.string()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("pageNum이 다음페이지로 이동할때 핸들러 함수 코드. 함수 내부 코드(문자열)로 전달하세요. 예시: console.log('다음 페이지로 이동, 현재 페이지:', pageNum)"),
|
|
34
|
+
onPrevious: z
|
|
35
|
+
.string()
|
|
36
|
+
.optional()
|
|
37
|
+
.describe("pageNum이 이전페이지로 이동할때 핸들러 함수 코드. 함수 내부 코드(문자열)로 전달하세요. 예시: console.log('이전 페이지로 이동, 현재 페이지:', pageNum)"),
|
|
38
|
+
pagingFromServer: z
|
|
39
|
+
.boolean()
|
|
40
|
+
.default(false)
|
|
41
|
+
.describe("서버에서 페이지네이션 정보를 받아오는 여부"),
|
|
42
|
+
onPageChange: z
|
|
43
|
+
.string()
|
|
44
|
+
.optional()
|
|
45
|
+
.describe("pageData가 변경 되었을때 사용하는 핸들러 함수 코드. 함수 내부 코드(문자열)로 전달하세요. 예시: setCurrentPageData(pageData); console.log('Current Page Data:', pageData)"),
|
|
46
|
+
});
|
|
47
|
+
// Pagination 컴포넌트 함수 - 배열 반환
|
|
48
|
+
export function createPaginationComponent() {
|
|
49
|
+
return [
|
|
50
|
+
{
|
|
51
|
+
name: "createPagination",
|
|
52
|
+
description: `페이지네이션 컴포넌트 - 페이지 이동 및 크기 조절
|
|
53
|
+
|
|
54
|
+
**import**:
|
|
55
|
+
\`\`\`jsx
|
|
56
|
+
import { useCommonComponents } from '@opsnow-common/opsnow-finops-common-ui-loader'
|
|
57
|
+
import i18n from '@opsnow-common/opsnow-finops-common-i18n'
|
|
58
|
+
const { OpsnowCommonPagination } = useCommonComponents();
|
|
59
|
+
\`\`\`
|
|
60
|
+
`,
|
|
61
|
+
parameters: PaginationSchema,
|
|
62
|
+
handler: async (args) => {
|
|
63
|
+
// 기본값 설정
|
|
64
|
+
const props = [];
|
|
65
|
+
let code = "";
|
|
66
|
+
if (args.rowsPerPageOptions) {
|
|
67
|
+
code += `
|
|
68
|
+
const [rowsPerPage, setRowsPerPage] = useState(${args.rowsPerPage});
|
|
69
|
+
`;
|
|
70
|
+
}
|
|
71
|
+
if (args.onRowsPerPageChange) {
|
|
72
|
+
code += `
|
|
73
|
+
const ${args.onRowsPerPageChange} = (event) => {
|
|
74
|
+
// 함수 내부 코드 작성
|
|
75
|
+
// 예시 : setRowsPerPage(event.target.value);
|
|
76
|
+
};
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
// 데이터 리스트 처리
|
|
80
|
+
if (args.list && Array.isArray(args.list)) {
|
|
81
|
+
const listItems = args.list
|
|
82
|
+
.map((item) => {
|
|
83
|
+
const displayValue = typeof item === "string" ? item : JSON.stringify(item);
|
|
84
|
+
return `<li>${displayValue}</li>`;
|
|
85
|
+
})
|
|
86
|
+
.join("\n ");
|
|
87
|
+
code += `
|
|
88
|
+
// 데이터 나열 예시
|
|
89
|
+
<ul>
|
|
90
|
+
${listItems}
|
|
91
|
+
</ul>
|
|
92
|
+
`;
|
|
93
|
+
props.push(`list={${JSON.stringify(args.list)}}`);
|
|
94
|
+
props.push(`count={${args.list.length}}`);
|
|
95
|
+
}
|
|
96
|
+
// 기본 props 추가
|
|
97
|
+
if (args.isLocale) {
|
|
98
|
+
props.push("locale={i18n.getLocale()}");
|
|
99
|
+
}
|
|
100
|
+
if (args.page) {
|
|
101
|
+
props.push(`page={${args.page}}`);
|
|
102
|
+
}
|
|
103
|
+
if (args.size) {
|
|
104
|
+
props.push(`size="${args.size}"`);
|
|
105
|
+
}
|
|
106
|
+
if (args.pagingFromServer) {
|
|
107
|
+
props.push(`pagingFromServer={${args.pagingFromServer}}`);
|
|
108
|
+
}
|
|
109
|
+
// rowsPerPage 관련 props
|
|
110
|
+
if (args.rowsPerPageOptions) {
|
|
111
|
+
const optionsString = args.rowsPerPageOptions
|
|
112
|
+
.map((opt) => `{ label: "${opt.label}", value: ${opt.value} }`)
|
|
113
|
+
.join(", ");
|
|
114
|
+
props.push(`rowsPerPageOptions={[${optionsString}]}`);
|
|
115
|
+
props.push("rowsPerPage={rowsPerPage}");
|
|
116
|
+
}
|
|
117
|
+
else if (args.rowsPerPage) {
|
|
118
|
+
props.push(`rowsPerPage={${args.rowsPerPage}}`);
|
|
119
|
+
}
|
|
120
|
+
// 이벤트 핸들러 props
|
|
121
|
+
if (args.onRowsPerPageChange) {
|
|
122
|
+
props.push(`onRowsPerPageChange={${args.onRowsPerPageChange}}`);
|
|
123
|
+
}
|
|
124
|
+
if (args.onChangePageNum) {
|
|
125
|
+
props.push(`onChangePageNum={(pageNum) => {
|
|
126
|
+
${args.onChangePageNum}
|
|
127
|
+
}}`);
|
|
128
|
+
}
|
|
129
|
+
if (args.onChangePageSize) {
|
|
130
|
+
props.push(`onChangePageSize={(pageSize, pageNum) => {
|
|
131
|
+
${args.onChangePageSize}
|
|
132
|
+
}}`);
|
|
133
|
+
}
|
|
134
|
+
if (args.onNext) {
|
|
135
|
+
props.push(`onNext={(pageNum) => {
|
|
136
|
+
${args.onNext}
|
|
137
|
+
}}`);
|
|
138
|
+
}
|
|
139
|
+
if (args.onPrevious) {
|
|
140
|
+
props.push(`onPrevious={(pageNum) => {
|
|
141
|
+
${args.onPrevious}
|
|
142
|
+
}}`);
|
|
143
|
+
}
|
|
144
|
+
if (args.onPageChange) {
|
|
145
|
+
props.push(`onPageChange={(pageData) => {
|
|
146
|
+
${args.onPageChange}
|
|
147
|
+
}}`);
|
|
148
|
+
}
|
|
149
|
+
// 컴포넌트 렌더링
|
|
150
|
+
code += `
|
|
151
|
+
<OpsnowCommonPagination ${props.join(" ")} />
|
|
152
|
+
`;
|
|
153
|
+
return {
|
|
154
|
+
content: [
|
|
155
|
+
{
|
|
156
|
+
type: "text",
|
|
157
|
+
text: `\`\`\`jsx\n${code}\n\`\`\``,
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
];
|
|
164
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// Popup 컴포넌트 관련 스키마 정의
|
|
3
|
+
export const PopupSchema = z.object({
|
|
4
|
+
title: z.string().describe("팝업 제목"),
|
|
5
|
+
visible: z.boolean().optional().default(false).describe("팝업 표시 여부"),
|
|
6
|
+
width: z.number().optional().describe("팝업 너비 (px)"),
|
|
7
|
+
height: z.number().optional().describe("팝업 높이 (px)"),
|
|
8
|
+
closable: z.boolean().optional().default(true).describe("닫기 버튼 표시 여부"),
|
|
9
|
+
maskClosable: z.boolean().optional().default(true).describe("마스크 클릭으로 닫기 가능 여부"),
|
|
10
|
+
disableEscapeKeyDown: z.boolean().optional().default(false).describe('ESC 키 입력으로 닫기 방지 여부'),
|
|
11
|
+
type: z.enum(['wing', 'standard', 'bottom']).optional().default('standard').describe("팝업 타입"),
|
|
12
|
+
size: z.enum(['sm', 'md', 'lg']).optional().describe('팝업 크기 (sm, md, lg)'),
|
|
13
|
+
confirmButton: z.object({
|
|
14
|
+
color: z.string().describe('확인 버튼 색상'),
|
|
15
|
+
variant: z.string().describe('확인 버튼 변형'),
|
|
16
|
+
}).optional().describe('확인 버튼 설정'),
|
|
17
|
+
useCustomHeader: z.boolean().optional().default(false).describe('커스텀 헤더 사용 여부'),
|
|
18
|
+
useCustomFooter: z.boolean().optional().default(false).describe('커스텀 푸터 사용 여부'),
|
|
19
|
+
headerContent: z.any().optional().describe('커스텀 헤더 내용 (JSX)'),
|
|
20
|
+
footerContent: z.any().optional().describe('커스텀 푸터 내용 (JSX)'),
|
|
21
|
+
});
|
|
22
|
+
// Popup 컴포넌트 함수 - 배열 반환
|
|
23
|
+
export function createPopupComponent() {
|
|
24
|
+
return [
|
|
25
|
+
{
|
|
26
|
+
name: "createPopup",
|
|
27
|
+
description: `팝업 컴포넌트 - 모달/다이얼로그 UI를 표시합니다.
|
|
28
|
+
|
|
29
|
+
사용 예시(React 함수 컴포넌트 내부에서 아래와 같이 import 후 사용하세요):
|
|
30
|
+
\`\`\`javascript
|
|
31
|
+
import { useCommonComponents } from '@opsnow-common/opsnow-finops-common-ui-loader';
|
|
32
|
+
const { OpsnowCommonPopup } = useCommonComponents();
|
|
33
|
+
\`\`\``,
|
|
34
|
+
parameters: PopupSchema,
|
|
35
|
+
handler: async (args) => {
|
|
36
|
+
// <OpsnowCommonPopup ...> 코드만 동적으로 생성
|
|
37
|
+
const { title = 'Example Popup', visible = false, width, height, closable = true, maskClosable = true, disableEscapeKeyDown = false, size, confirmButton, useCustomHeader = false, useCustomFooter = false, headerContent, footerContent, type = 'standard', } = args;
|
|
38
|
+
// prop 문자열 생성
|
|
39
|
+
const propStr = [
|
|
40
|
+
`title=\"${title}\"`,
|
|
41
|
+
`open={${visible}}`,
|
|
42
|
+
`onClose={handleClose}`,
|
|
43
|
+
width ? `width={${width}}` : '',
|
|
44
|
+
height ? `height={${height}}` : '',
|
|
45
|
+
closable === false ? 'closable={false}' : '',
|
|
46
|
+
maskClosable === false ? 'maskClosable={false}' : '',
|
|
47
|
+
disableEscapeKeyDown ? 'disableEscapeKeyDown' : '',
|
|
48
|
+
`type=\"${type}\"`,
|
|
49
|
+
`size=\"${size}\"`,
|
|
50
|
+
confirmButton ? `confirmButton={${JSON.stringify(confirmButton)}}` : '',
|
|
51
|
+
useCustomHeader ? 'useCustomHeader' : '',
|
|
52
|
+
useCustomFooter ? 'useCustomFooter' : '',
|
|
53
|
+
headerContent ? `headerContent={${headerContent}}` : '',
|
|
54
|
+
footerContent ? `footerContent={${footerContent}}` : '',
|
|
55
|
+
].filter(Boolean).join('\n ');
|
|
56
|
+
const code = `<OpsnowCommonPopup
|
|
57
|
+
${propStr}
|
|
58
|
+
>
|
|
59
|
+
</OpsnowCommonPopup>`;
|
|
60
|
+
return {
|
|
61
|
+
content: [
|
|
62
|
+
{
|
|
63
|
+
type: "text",
|
|
64
|
+
text: `\`\`\`jsx\n${code}\n\`\`\``
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
];
|
|
71
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const COMMON_VARIANTS = ["indeterminate", "determinate"];
|
|
3
|
+
const LINE_VARIANTS = ["buffer"];
|
|
4
|
+
const COMMON_COLORS = ["primary", "secondary", "inherit"];
|
|
5
|
+
const CIRCLE_COLORS = ["error", "info", "warning", "success"];
|
|
6
|
+
// 공통 Progress 스키마
|
|
7
|
+
export const BaseProgressSchema = z.object({
|
|
8
|
+
percent: z
|
|
9
|
+
.number()
|
|
10
|
+
.min(0)
|
|
11
|
+
.max(100)
|
|
12
|
+
.optional()
|
|
13
|
+
.describe("진행률 (0-100)(dot 형태, indeterminate일때는 필요 없음, variant가 buffer인 경우 초기값으로 사용)"),
|
|
14
|
+
size: z
|
|
15
|
+
.number()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe("progress 크기 (dot 형태일 때는 필요 없음)"),
|
|
18
|
+
showInfo: z
|
|
19
|
+
.boolean()
|
|
20
|
+
.default(false)
|
|
21
|
+
.describe("퍼센트 정보 표시 여부 - percent value가 존재하는 경우만 true"),
|
|
22
|
+
}).describe("진행률 컴포넌트 - 로딩 관련 버튼이 필요하면 createButtonComponent 호출");
|
|
23
|
+
// Line Type(Progress) 스키마
|
|
24
|
+
export const LineProgressSchema = BaseProgressSchema.extend({
|
|
25
|
+
variant: z
|
|
26
|
+
.enum([...COMMON_VARIANTS, ...LINE_VARIANTS])
|
|
27
|
+
.describe("Progress 형태 타입"),
|
|
28
|
+
strokeColor: z
|
|
29
|
+
.enum([...COMMON_COLORS])
|
|
30
|
+
.optional()
|
|
31
|
+
.describe("Progress 바 색상"),
|
|
32
|
+
valueBuffer: z
|
|
33
|
+
.number()
|
|
34
|
+
.optional()
|
|
35
|
+
.describe("Progress 바 버퍼 값 - variant가 buffer일때 필요"),
|
|
36
|
+
});
|
|
37
|
+
// Circle Type(Loading) 스키마
|
|
38
|
+
export const CircleProgressSchema = BaseProgressSchema.extend({
|
|
39
|
+
variant: z
|
|
40
|
+
.enum([...COMMON_VARIANTS])
|
|
41
|
+
.optional()
|
|
42
|
+
.describe("Loading Progress 타입 - dot 형태일때는 필요 없음"),
|
|
43
|
+
strokeColor: z
|
|
44
|
+
.enum([...COMMON_COLORS, ...CIRCLE_COLORS])
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("Loading 원형 색상"),
|
|
47
|
+
loadingDots: z
|
|
48
|
+
.object({
|
|
49
|
+
dotSize: z.number().describe("도트 크기"),
|
|
50
|
+
dotIndex: z.number().describe("도트 인덱스"),
|
|
51
|
+
})
|
|
52
|
+
.partial()
|
|
53
|
+
.optional()
|
|
54
|
+
.describe("도트 형태 일때 도트 속성(dotSize, dotIndex)"),
|
|
55
|
+
open: z.boolean().default(false).describe("open, setOpen useState 사용 여부"),
|
|
56
|
+
isFullScreen: z.boolean().default(false).describe("전체 화면 표시 여부"),
|
|
57
|
+
}).describe("단일 진행률인 경우 사용");
|
|
58
|
+
// Progress 컴포넌트 함수 - 여러 tool을 반환
|
|
59
|
+
export function createProgressComponent() {
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
name: "createProgressCircle",
|
|
63
|
+
description: `진행률 컴포넌트 생성 - 단일 진행률(%)을 표시하기 위한 원 형태의 컴포넌트 생성(원형, 도트 형태)
|
|
64
|
+
- 도트형태: 점(●)이 여러 개, 진행률 숫자/원형 바 없음(하나의 컴포넌트에 점 세개)
|
|
65
|
+
- 원형: 하나의 원, 진행률 숫자/텍스트/원형 바가 있음(앙에 숫자/텍스트/원형 바가 있으면 무조건 원형)
|
|
66
|
+
**주의사항:**
|
|
67
|
+
- 도트 형태를 사용하는 경우, <OpsnowCommonLoading loadingDots dotSize={8}/> 와 같이 loadingDots, dotSize, dotIndex와 한꺼번에 묶어서 사용하지 않음
|
|
68
|
+
- 금지 : isLoadingDots = { dotSize: 8, dotIndex: 0 } - 해당 예시처럼 사용 금지
|
|
69
|
+
**import:**
|
|
70
|
+
\`\`\`javascript
|
|
71
|
+
import { useCommonComponents } from '@opsnow-common/opsnow-finops-common-ui-loader';
|
|
72
|
+
const { OpsnowCommonLoading, OpsnowCommonButton } = useCommonComponents();
|
|
73
|
+
`,
|
|
74
|
+
parameters: CircleProgressSchema,
|
|
75
|
+
handler: async (args) => {
|
|
76
|
+
// 진행률 컴포넌트 생성 로직 구현
|
|
77
|
+
let functionDefinitions = ``;
|
|
78
|
+
if (args.open) {
|
|
79
|
+
functionDefinitions += `
|
|
80
|
+
const [open, setOpen] = useState(false);
|
|
81
|
+
`;
|
|
82
|
+
}
|
|
83
|
+
// Props 생성
|
|
84
|
+
const props = [];
|
|
85
|
+
if (args.percent)
|
|
86
|
+
props.push(`value={${args.percent}}`);
|
|
87
|
+
if (args.variant)
|
|
88
|
+
props.push(`variant="${args.variant}"`);
|
|
89
|
+
if (args.size)
|
|
90
|
+
props.push(`size={${args.size}}`);
|
|
91
|
+
if (args.showInfo)
|
|
92
|
+
props.push(`label`);
|
|
93
|
+
if (args.strokeColor)
|
|
94
|
+
props.push(`color="${args.strokeColor}"`);
|
|
95
|
+
if (args.open)
|
|
96
|
+
props.push(`open={open}`);
|
|
97
|
+
if (args.isFullScreen)
|
|
98
|
+
props.push(`isFullScreen`);
|
|
99
|
+
if (args.loadingDots) {
|
|
100
|
+
if (args.loadingDots.dotSize || args.loadingDots.dotIndex) {
|
|
101
|
+
props.push("loadingDots");
|
|
102
|
+
}
|
|
103
|
+
if (args.loadingDots?.dotSize)
|
|
104
|
+
props.push(`dotSize={${args.loadingDots.dotSize}}`);
|
|
105
|
+
if (args.loadingDots?.dotIndex)
|
|
106
|
+
props.push(`index={${args.loadingDots.dotIndex}}`);
|
|
107
|
+
}
|
|
108
|
+
// 컴포넌트 코드 생성
|
|
109
|
+
let componentCode = `
|
|
110
|
+
<OpsnowCommonLoading
|
|
111
|
+
${props.join("\n ")}
|
|
112
|
+
/>`;
|
|
113
|
+
const fullCode = `${componentCode}`;
|
|
114
|
+
return {
|
|
115
|
+
content: [
|
|
116
|
+
{
|
|
117
|
+
type: "text",
|
|
118
|
+
text: `\`\`\`jsx\n${fullCode}\n\`\`\``,
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: "createProgressLine",
|
|
126
|
+
description: `진행률 컴포넌트 생성 - 단일 진행률(%)을 라인 형태로 표시를 위한 컴포넌트 생성(라인, 바 형태)
|
|
127
|
+
**import:**
|
|
128
|
+
\`\`\`javascript클라
|
|
129
|
+
import { useCommonComponents } from '@opsnow-common/opsnow-finops-common-ui-loader';
|
|
130
|
+
const { OpsnowCommonProgress } = useCommonComponents();
|
|
131
|
+
`,
|
|
132
|
+
parameters: LineProgressSchema,
|
|
133
|
+
handler: async (args) => {
|
|
134
|
+
let functionDefinitions = ``;
|
|
135
|
+
if (args.valueBuffer) {
|
|
136
|
+
functionDefinitions += `
|
|
137
|
+
const [progress, setProgress] = useState(${args.percent});
|
|
138
|
+
const [buffer, setBuffer] = useState(${args.valueBuffer});
|
|
139
|
+
// 아래에 버퍼 값 업데이트 로직 추가
|
|
140
|
+
// 그 외 필요한 함수 추가
|
|
141
|
+
`;
|
|
142
|
+
}
|
|
143
|
+
let componentCode = "";
|
|
144
|
+
const props = [];
|
|
145
|
+
props.push(`value={${args.percent}}`);
|
|
146
|
+
if (args.variant)
|
|
147
|
+
props.push(`variant="${args.variant}"`);
|
|
148
|
+
if (args.percent && args.valueBuffer) {
|
|
149
|
+
props.push(`value = {progress}`);
|
|
150
|
+
props.push(`valueBuffer={buffer}`);
|
|
151
|
+
}
|
|
152
|
+
else if (args.percent) {
|
|
153
|
+
props.push(`value=${args.percent}`);
|
|
154
|
+
}
|
|
155
|
+
if (args.size)
|
|
156
|
+
props.push(`size="${args.size}"`);
|
|
157
|
+
if (args.showInfo)
|
|
158
|
+
props.push(`label`);
|
|
159
|
+
if (args.strokeColor)
|
|
160
|
+
props.push(`color="${args.strokeColor}"`);
|
|
161
|
+
componentCode += `
|
|
162
|
+
<OpsnowCommonProgress ${props.join("\n ")} />
|
|
163
|
+
`;
|
|
164
|
+
const code = `${functionDefinitions}\n${componentCode}`;
|
|
165
|
+
// 진행률 업데이트 로직 구현
|
|
166
|
+
return {
|
|
167
|
+
content: [
|
|
168
|
+
{
|
|
169
|
+
type: "text",
|
|
170
|
+
text: `\`\`\`jsx\n${code}\n\`\`\``,
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
};
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// Select 컴포넌트 관련 스키마 정의
|
|
3
|
+
export const SelectSchema = z.object({
|
|
4
|
+
items: z.array(z.object({
|
|
5
|
+
value: z.string(),
|
|
6
|
+
label: z.any(), // string | JSX 가능
|
|
7
|
+
disabled: z.boolean().optional().default(false)
|
|
8
|
+
})).describe("셀렉트 옵션 목록"),
|
|
9
|
+
value: z.any().optional().describe("선택된 값(단일/다중)"),
|
|
10
|
+
multiple: z.boolean().optional().default(false).describe("다중 선택 가능 여부"),
|
|
11
|
+
placeholder: z.string().optional().describe("플레이스홀더 텍스트"),
|
|
12
|
+
variant: z.enum(["standard", "outlined", "filled", "noLine"]).optional().describe("셀렉트 variant"),
|
|
13
|
+
size: z.enum(["small", "medium"]).optional().describe("셀렉트 크기"),
|
|
14
|
+
error: z.boolean().optional().default(false).describe("에러 상태"),
|
|
15
|
+
disabled: z.boolean().optional().default(false).describe("비활성화 여부"),
|
|
16
|
+
searchable: z.boolean().optional().default(false).describe("검색 가능 여부")
|
|
17
|
+
});
|
|
18
|
+
// Autocomplete Select 컴포넌트 관련 스키마 정의
|
|
19
|
+
export const AutocompleteSelectSchema = z.object({
|
|
20
|
+
items: z.array(z.object({
|
|
21
|
+
value: z.string(),
|
|
22
|
+
label: z.string(),
|
|
23
|
+
group: z.string().optional(),
|
|
24
|
+
iconName: z.string().optional(),
|
|
25
|
+
disabled: z.boolean().optional().default(false)
|
|
26
|
+
})).describe("오토컴플리트 옵션 목록"),
|
|
27
|
+
value: z.any().optional().describe("선택된 값/값들 (단일/다중)"),
|
|
28
|
+
multiple: z.boolean().optional().default(false).describe("다중 선택 가능 여부"),
|
|
29
|
+
useCheckboxOption: z.boolean().optional().default(false).describe("체크박스 옵션 사용 여부"),
|
|
30
|
+
useSelectAll: z.boolean().optional().default(false).describe("전체 선택 옵션 사용 여부"),
|
|
31
|
+
disableCloseOnSelect: z.boolean().optional().default(false).describe("선택 시 닫힘 방지 여부"),
|
|
32
|
+
loading: z.boolean().optional().default(false).describe("로딩 상태 표시 여부"),
|
|
33
|
+
label: z.string().optional().describe("라벨 텍스트"),
|
|
34
|
+
placeholder: z.string().optional().describe("플레이스홀더 텍스트"),
|
|
35
|
+
disabled: z.boolean().optional().default(false).describe("전체 비활성화 여부")
|
|
36
|
+
});
|
|
37
|
+
// Select 컴포넌트 함수 - 배열 반환
|
|
38
|
+
export function createSelectComponent() {
|
|
39
|
+
return [
|
|
40
|
+
{
|
|
41
|
+
name: "createSelect",
|
|
42
|
+
description: `기본 셀렉트 컴포넌트 예제입니다.
|
|
43
|
+
|
|
44
|
+
- items: 옵션 배열 (value, label, disabled 등 지원)
|
|
45
|
+
- multiple, placeholder, variant, size, error, disabled, searchable 등 다양한 props 지원
|
|
46
|
+
- value/onChange는 단일/다중 선택에 따라 배열 또는 단일 값
|
|
47
|
+
|
|
48
|
+
**import:**
|
|
49
|
+
\`\`\`javascript
|
|
50
|
+
import { useCommonComponents } from '@opsnow-common/opsnow-finops-common-ui-loader';
|
|
51
|
+
const { OpsnowCommonSelect } = useCommonComponents();
|
|
52
|
+
\`\`\``,
|
|
53
|
+
parameters: SelectSchema,
|
|
54
|
+
handler: async (args) => {
|
|
55
|
+
const props = [];
|
|
56
|
+
if (args.items)
|
|
57
|
+
props.push(`items={${JSON.stringify(args.items)}}`);
|
|
58
|
+
if (args.value !== undefined)
|
|
59
|
+
props.push(`value={value}`);
|
|
60
|
+
if (args.multiple)
|
|
61
|
+
props.push(`multiple`);
|
|
62
|
+
if (args.placeholder)
|
|
63
|
+
props.push(`placeholder=\"${args.placeholder}\"`);
|
|
64
|
+
if (args.variant)
|
|
65
|
+
props.push(`variant=\"${args.variant}\"`);
|
|
66
|
+
if (args.size)
|
|
67
|
+
props.push(`size=\"${args.size}\"`);
|
|
68
|
+
if (args.error)
|
|
69
|
+
props.push(`error`);
|
|
70
|
+
if (args.disabled)
|
|
71
|
+
props.push(`disabled`);
|
|
72
|
+
if (args.searchable)
|
|
73
|
+
props.push(`searchable`);
|
|
74
|
+
props.push(`onChange={e => setValue(e.target.value)}`);
|
|
75
|
+
const code = `<OpsnowCommonSelect ${props.join(' ')} />`;
|
|
76
|
+
return {
|
|
77
|
+
content: [
|
|
78
|
+
{
|
|
79
|
+
type: "text",
|
|
80
|
+
text: `\`\`\`jsx\n${code}\n\`\`\``
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "createAutocompleteSelect",
|
|
88
|
+
description: `오토컴플리트 셀렉트 컴포넌트 예제입니다.
|
|
89
|
+
- 그룹 옵션 및 전체 선택 옵션 지원
|
|
90
|
+
- items: 옵션 배열 (value, label, group, iconName, disabled 등 지원)
|
|
91
|
+
- multiple, useCheckboxOption, useSelectAll, disableCloseOnSelect, loading 등 다양한 props 지원
|
|
92
|
+
- value/onChange는 단일/다중 선택에 따라 배열 또는 단일 값
|
|
93
|
+
|
|
94
|
+
**import:**
|
|
95
|
+
\`\`\`javascript
|
|
96
|
+
import { useCommonComponents } from '@opsnow-common/opsnow-finops-common-ui-loader';
|
|
97
|
+
const { OpsnowCommonAutocomplete } = useCommonComponents();
|
|
98
|
+
\`\`\``,
|
|
99
|
+
parameters: AutocompleteSelectSchema,
|
|
100
|
+
handler: async (args) => {
|
|
101
|
+
const props = [];
|
|
102
|
+
if (args.items)
|
|
103
|
+
props.push(`items={${JSON.stringify(args.items)}}`);
|
|
104
|
+
if (args.value !== undefined)
|
|
105
|
+
props.push(`value={value}`);
|
|
106
|
+
if (args.multiple)
|
|
107
|
+
props.push(`multiple`);
|
|
108
|
+
if (args.useCheckboxOption)
|
|
109
|
+
props.push(`useCheckboxOption`);
|
|
110
|
+
if (args.useSelectAll)
|
|
111
|
+
props.push(`useSelectAll`);
|
|
112
|
+
if (args.disableCloseOnSelect)
|
|
113
|
+
props.push(`disableCloseOnSelect`);
|
|
114
|
+
if (args.loading)
|
|
115
|
+
props.push(`loading`);
|
|
116
|
+
if (args.label)
|
|
117
|
+
props.push(`label=\"${args.label}\"`);
|
|
118
|
+
if (args.placeholder)
|
|
119
|
+
props.push(`placeholder=\"${args.placeholder}\"`);
|
|
120
|
+
if (args.disabled)
|
|
121
|
+
props.push(`disabled`);
|
|
122
|
+
props.push(`onChange={setValue}`);
|
|
123
|
+
const code = `<OpsnowCommonAutocomplete ${props.join(' ')} />`;
|
|
124
|
+
return {
|
|
125
|
+
content: [
|
|
126
|
+
{
|
|
127
|
+
type: "text",
|
|
128
|
+
text: `\`\`\`jsx\n${code}\n\`\`\``
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
];
|
|
135
|
+
}
|