@opsnow-mcp/opsnow-mcp-common-ui-server 1.0.0
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/README.md +135 -0
- 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 +5983 -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 +1454 -0
- package/build/components/examples/opsnow-common-grid-examples-data.js +1888 -0
- package/build/components/examples/opsnow-common-icons-examples-data.js +72 -0
- package/build/components/examples/opsnow-common-layout-examples-data.js +60 -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 +173 -0
- package/build/components/examples/opsnow-common-progress-examples-data.js +86 -0
- package/build/components/examples/opsnow-common-select-examples-data.js +106 -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 +82 -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 +334 -0
- package/build/components/opsnow-common-calendar.js +228 -0
- package/build/components/opsnow-common-chart.js +1507 -0
- package/build/components/opsnow-common-data-status.js +116 -0
- package/build/components/opsnow-common-examples.js +108 -0
- package/build/components/opsnow-common-file-upload.js +57 -0
- package/build/components/opsnow-common-forms.js +812 -0
- package/build/components/opsnow-common-grid.js +213 -0
- package/build/components/opsnow-common-icons.js +139 -0
- package/build/components/opsnow-common-layout.js +70 -0
- package/build/components/opsnow-common-notification.js +109 -0
- package/build/components/opsnow-common-pagination.js +163 -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 +132 -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 +213 -0
- package/build/components/opsnow-common-typography.js +93 -0
- package/build/index.js +75 -0
- package/package.json +41 -0
|
@@ -0,0 +1,163 @@
|
|
|
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
|
+
**import**:
|
|
54
|
+
\`\`\`jsx
|
|
55
|
+
import { useCommonComponents } from 'opsnow-finops-common-ui-loader'
|
|
56
|
+
import i18n from 'opsnow-finops-common-i18n'
|
|
57
|
+
const { OpsnowCommonPagination } = useCommonComponents();
|
|
58
|
+
\`\`\`
|
|
59
|
+
`,
|
|
60
|
+
parameters: PaginationSchema,
|
|
61
|
+
handler: async (args) => {
|
|
62
|
+
// 기본값 설정
|
|
63
|
+
const props = [];
|
|
64
|
+
let code = "";
|
|
65
|
+
if (args.rowsPerPageOptions) {
|
|
66
|
+
code += `
|
|
67
|
+
const [rowsPerPage, setRowsPerPage] = useState(${args.rowsPerPage});
|
|
68
|
+
`;
|
|
69
|
+
}
|
|
70
|
+
if (args.onRowsPerPageChange) {
|
|
71
|
+
code += `
|
|
72
|
+
const ${args.onRowsPerPageChange} = (event) => {
|
|
73
|
+
// 함수 내부 코드 작성
|
|
74
|
+
// 예시 : setRowsPerPage(event.target.value);
|
|
75
|
+
};
|
|
76
|
+
`;
|
|
77
|
+
}
|
|
78
|
+
// 데이터 리스트 처리
|
|
79
|
+
if (args.list && Array.isArray(args.list)) {
|
|
80
|
+
const listItems = args.list
|
|
81
|
+
.map((item) => {
|
|
82
|
+
const displayValue = typeof item === "string" ? item : JSON.stringify(item);
|
|
83
|
+
return `<li>${displayValue}</li>`;
|
|
84
|
+
})
|
|
85
|
+
.join("\n ");
|
|
86
|
+
code += `
|
|
87
|
+
// 데이터 나열 예시
|
|
88
|
+
<ul>
|
|
89
|
+
${listItems}
|
|
90
|
+
</ul>
|
|
91
|
+
`;
|
|
92
|
+
props.push(`list={${JSON.stringify(args.list)}}`);
|
|
93
|
+
props.push(`count={${args.list.length}}`);
|
|
94
|
+
}
|
|
95
|
+
// 기본 props 추가
|
|
96
|
+
if (args.isLocale) {
|
|
97
|
+
props.push("locale={i18n.getLocale()}");
|
|
98
|
+
}
|
|
99
|
+
if (args.page) {
|
|
100
|
+
props.push(`page={${args.page}}`);
|
|
101
|
+
}
|
|
102
|
+
if (args.size) {
|
|
103
|
+
props.push(`size="${args.size}"`);
|
|
104
|
+
}
|
|
105
|
+
if (args.pagingFromServer) {
|
|
106
|
+
props.push(`pagingFromServer={${args.pagingFromServer}}`);
|
|
107
|
+
}
|
|
108
|
+
// rowsPerPage 관련 props
|
|
109
|
+
if (args.rowsPerPageOptions) {
|
|
110
|
+
const optionsString = args.rowsPerPageOptions
|
|
111
|
+
.map((opt) => `{ label: "${opt.label}", value: ${opt.value} }`)
|
|
112
|
+
.join(", ");
|
|
113
|
+
props.push(`rowsPerPageOptions={[${optionsString}]}`);
|
|
114
|
+
props.push("rowsPerPage={rowsPerPage}");
|
|
115
|
+
}
|
|
116
|
+
else if (args.rowsPerPage) {
|
|
117
|
+
props.push(`rowsPerPage={${args.rowsPerPage}}`);
|
|
118
|
+
}
|
|
119
|
+
// 이벤트 핸들러 props
|
|
120
|
+
if (args.onRowsPerPageChange) {
|
|
121
|
+
props.push(`onRowsPerPageChange={${args.onRowsPerPageChange}}`);
|
|
122
|
+
}
|
|
123
|
+
if (args.onChangePageNum) {
|
|
124
|
+
props.push(`onChangePageNum={(pageNum) => {
|
|
125
|
+
${args.onChangePageNum}
|
|
126
|
+
}}`);
|
|
127
|
+
}
|
|
128
|
+
if (args.onChangePageSize) {
|
|
129
|
+
props.push(`onChangePageSize={(pageSize, pageNum) => {
|
|
130
|
+
${args.onChangePageSize}
|
|
131
|
+
}}`);
|
|
132
|
+
}
|
|
133
|
+
if (args.onNext) {
|
|
134
|
+
props.push(`onNext={(pageNum) => {
|
|
135
|
+
${args.onNext}
|
|
136
|
+
}}`);
|
|
137
|
+
}
|
|
138
|
+
if (args.onPrevious) {
|
|
139
|
+
props.push(`onPrevious={(pageNum) => {
|
|
140
|
+
${args.onPrevious}
|
|
141
|
+
}}`);
|
|
142
|
+
}
|
|
143
|
+
if (args.onPageChange) {
|
|
144
|
+
props.push(`onPageChange={(pageData) => {
|
|
145
|
+
${args.onPageChange}
|
|
146
|
+
}}`);
|
|
147
|
+
}
|
|
148
|
+
// 컴포넌트 렌더링
|
|
149
|
+
code += `
|
|
150
|
+
<OpsnowCommonPagination ${props.join(" ")} />
|
|
151
|
+
`;
|
|
152
|
+
return {
|
|
153
|
+
content: [
|
|
154
|
+
{
|
|
155
|
+
type: "text",
|
|
156
|
+
text: `\`\`\`jsx\n${code}\n\`\`\``,
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
];
|
|
163
|
+
}
|
|
@@ -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-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-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-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,132 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// Select 컴포넌트 관련 스키마 정의
|
|
3
|
+
export const SelectSchema = z.object({
|
|
4
|
+
options: 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
|
+
disabled: z.boolean().optional().default(false).describe("전체 비활성화 여부")
|
|
35
|
+
});
|
|
36
|
+
// Select 컴포넌트 함수 - 배열 반환
|
|
37
|
+
export function createSelectComponent() {
|
|
38
|
+
return [
|
|
39
|
+
{
|
|
40
|
+
name: "createSelect",
|
|
41
|
+
description: `기본 셀렉트 컴포넌트 예제입니다.
|
|
42
|
+
|
|
43
|
+
- options: 옵션 배열 (value, label, disabled 등 지원)
|
|
44
|
+
- multiple, placeholder, variant, size, error, disabled, searchable 등 다양한 props 지원
|
|
45
|
+
- value/onChange는 단일/다중 선택에 따라 배열 또는 단일 값
|
|
46
|
+
|
|
47
|
+
**import:**
|
|
48
|
+
\`\`\`javascript
|
|
49
|
+
import { useCommonComponents } from 'opsnow-finops-common-ui-loader';
|
|
50
|
+
const { OpsnowCommonSelect } = useCommonComponents();
|
|
51
|
+
\`\`\``,
|
|
52
|
+
parameters: SelectSchema,
|
|
53
|
+
handler: async (args) => {
|
|
54
|
+
const props = [];
|
|
55
|
+
if (args.options)
|
|
56
|
+
props.push(`items={${JSON.stringify(args.options)}}`);
|
|
57
|
+
if (args.value !== undefined)
|
|
58
|
+
props.push(`value={value}`);
|
|
59
|
+
if (args.multiple)
|
|
60
|
+
props.push(`multiple`);
|
|
61
|
+
if (args.placeholder)
|
|
62
|
+
props.push(`placeholder=\"${args.placeholder}\"`);
|
|
63
|
+
if (args.variant)
|
|
64
|
+
props.push(`variant=\"${args.variant}\"`);
|
|
65
|
+
if (args.size)
|
|
66
|
+
props.push(`size=\"${args.size}\"`);
|
|
67
|
+
if (args.error)
|
|
68
|
+
props.push(`error`);
|
|
69
|
+
if (args.disabled)
|
|
70
|
+
props.push(`disabled`);
|
|
71
|
+
if (args.searchable)
|
|
72
|
+
props.push(`searchable`);
|
|
73
|
+
props.push(`onChange={setValue}`);
|
|
74
|
+
const code = `<OpsnowCommonSelect ${props.join(' ')} />`;
|
|
75
|
+
return {
|
|
76
|
+
content: [
|
|
77
|
+
{
|
|
78
|
+
type: "text",
|
|
79
|
+
text: `\u0060\u0060\u0060jsx\n${code}\n\u0060\u0060\u0060`
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: "createAutocompleteSelect",
|
|
87
|
+
description: `오토컴플리트 셀렉트 컴포넌트 예제입니다.
|
|
88
|
+
- 그룹 옵션 및 전체 선택 옵션 지원
|
|
89
|
+
- items: 옵션 배열 (value, label, group, iconName, disabled 등 지원)
|
|
90
|
+
- multiple, useCheckboxOption, useSelectAll, disableCloseOnSelect, loading 등 다양한 props 지원
|
|
91
|
+
- value/onChange는 단일/다중 선택에 따라 배열 또는 단일 값
|
|
92
|
+
|
|
93
|
+
**import:**
|
|
94
|
+
\`\`\`javascript
|
|
95
|
+
import { useCommonComponents } from 'opsnow-finops-common-ui-loader';
|
|
96
|
+
const { OpsnowCommonAutocomplete } = useCommonComponents();
|
|
97
|
+
\`\`\``,
|
|
98
|
+
parameters: AutocompleteSelectSchema,
|
|
99
|
+
handler: async (args) => {
|
|
100
|
+
const props = [];
|
|
101
|
+
if (args.items)
|
|
102
|
+
props.push(`items={${JSON.stringify(args.items)}}`);
|
|
103
|
+
if (args.value !== undefined)
|
|
104
|
+
props.push(`value={value}`);
|
|
105
|
+
if (args.multiple)
|
|
106
|
+
props.push(`multiple`);
|
|
107
|
+
if (args.useCheckboxOption)
|
|
108
|
+
props.push(`useCheckboxOption`);
|
|
109
|
+
if (args.useSelectAll)
|
|
110
|
+
props.push(`useSelectAll`);
|
|
111
|
+
if (args.disableCloseOnSelect)
|
|
112
|
+
props.push(`disableCloseOnSelect`);
|
|
113
|
+
if (args.loading)
|
|
114
|
+
props.push(`loading`);
|
|
115
|
+
if (args.label)
|
|
116
|
+
props.push(`label=\"${args.label}\"`);
|
|
117
|
+
if (args.disabled)
|
|
118
|
+
props.push(`disabled`);
|
|
119
|
+
props.push(`onChange={setValue}`);
|
|
120
|
+
const code = `<OpsnowCommonAutocomplete ${props.join(' ')} />`;
|
|
121
|
+
return {
|
|
122
|
+
content: [
|
|
123
|
+
{
|
|
124
|
+
type: "text",
|
|
125
|
+
text: `\`\`\`jsx\n${code}\n\`\`\``
|
|
126
|
+
}
|
|
127
|
+
]
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
];
|
|
132
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// Stepper 컴포넌트 관련 스키마 정의 (예제 코드에 맞게 확장)
|
|
3
|
+
export const StepperSchema = z.object({
|
|
4
|
+
steps: z.array(z.object({
|
|
5
|
+
label: z.string().describe("스텝 라벨"),
|
|
6
|
+
status: z.string().optional().describe("스텝 상태 (NotStarted, Completed, Error 등)"),
|
|
7
|
+
optionalText: z.string().optional().describe("옵셔널 텍스트"),
|
|
8
|
+
description: z.string().optional(),
|
|
9
|
+
icon: z.string().optional(),
|
|
10
|
+
// slot은 StepContent에서만 사용
|
|
11
|
+
})).describe("스텝 목록"),
|
|
12
|
+
activeStep: z.number().optional().default(0).describe("현재 스텝 인덱스"),
|
|
13
|
+
orientation: z.enum(["horizontal", "vertical"]).optional().default("horizontal").describe("스텝 방향"),
|
|
14
|
+
align: z.enum(["left", "center", "right"]).optional().describe("스텝 정렬"),
|
|
15
|
+
isSimpleView: z.boolean().optional().describe("심플 뷰 여부"),
|
|
16
|
+
connector: z.string().optional().describe("커스텀 커넥터 컴포넌트(JSX 문자열)"),
|
|
17
|
+
onStepClick: z.string().optional().describe("스텝 클릭 핸들러 함수명"),
|
|
18
|
+
contentPadding: z.string().optional().describe("컨텐츠 패딩 스타일"),
|
|
19
|
+
contentHeight: z.string().optional().describe("컨텐츠 높이 스타일"),
|
|
20
|
+
nonLinear: z.boolean().optional().describe("논리니어 여부"),
|
|
21
|
+
contentDependency: z.boolean().optional().describe("컨텐츠 의존성 여부"),
|
|
22
|
+
size: z.enum(["default", "small"]).optional().default("default").describe("스텝 크기"),
|
|
23
|
+
onChange: z.string().optional().describe("스텝 변경 이벤트 핸들러 함수명"),
|
|
24
|
+
clickable: z.boolean().optional().default(false).describe("스텝 클릭 가능 여부")
|
|
25
|
+
});
|
|
26
|
+
// Stepper 컴포넌트 함수 - 배열 반환
|
|
27
|
+
export function createStepperComponent() {
|
|
28
|
+
return [
|
|
29
|
+
{
|
|
30
|
+
name: "createStepper",
|
|
31
|
+
description: `스텝퍼 컴포넌트 - 단계별 진행 상황 표시
|
|
32
|
+
|
|
33
|
+
**import 예시(React의 모든 훅(useState, useEffect, useCommonComponents 등)은 반드시 함수 컴포넌트 내부에서 호출):**
|
|
34
|
+
\`\`\`javascript
|
|
35
|
+
import { useCommonComponents } from 'opsnow-finops-common-ui-loader';
|
|
36
|
+
const { OpsnowCommonStepper, OpsnowCommonStepContent } = useCommonComponents();
|
|
37
|
+
\`\`\``,
|
|
38
|
+
parameters: StepperSchema,
|
|
39
|
+
handler: async (args) => {
|
|
40
|
+
const { steps, activeStep = 0, orientation = "horizontal", align, isSimpleView, connector, onStepClick, contentPadding, contentHeight, nonLinear, contentDependency, size = "default", onChange, clickable } = args;
|
|
41
|
+
// 태그 props만 생성
|
|
42
|
+
const propList = [
|
|
43
|
+
`steps={steps}`,
|
|
44
|
+
`activeStep={activeStep}`,
|
|
45
|
+
`orientation=\"${orientation}\"`,
|
|
46
|
+
align ? `align=\"${align}\"` : '',
|
|
47
|
+
isSimpleView ? 'isSimpleView' : '',
|
|
48
|
+
connector ? `connector={${connector}}` : '',
|
|
49
|
+
onStepClick ? `onStepClick={${onStepClick}}` : '',
|
|
50
|
+
contentPadding ? `contentPadding=\"${contentPadding}\"` : '',
|
|
51
|
+
contentHeight ? `contentHeight=\"${contentHeight}\"` : '',
|
|
52
|
+
nonLinear ? 'nonLinear' : '',
|
|
53
|
+
typeof contentDependency === 'boolean' ? `contentDependency={${contentDependency}}` : '',
|
|
54
|
+
`size=\"${size}\"`,
|
|
55
|
+
onChange ? `onChange={${onChange}}` : '',
|
|
56
|
+
clickable ? 'clickable' : ''
|
|
57
|
+
].filter(Boolean);
|
|
58
|
+
// StepContent 샘플
|
|
59
|
+
const stepContent = steps.map((_, idx) => ` <OpsnowCommonStepContent stepIndex={${idx}} />`).join('\n');
|
|
60
|
+
const code = `<OpsnowCommonStepper\n ${propList.join('\n ')}\n>\n${stepContent}\n</OpsnowCommonStepper>`;
|
|
61
|
+
return {
|
|
62
|
+
content: [
|
|
63
|
+
{
|
|
64
|
+
type: "text",
|
|
65
|
+
text: `\`\`\`jsx\n${code}\n\`\`\``
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
];
|
|
72
|
+
}
|