@opsnow-mcp/opsnow-mcp-common-ui-server 1.0.27 → 1.0.28
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.
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// CoachMark 컴포넌트 예제 데이터
|
|
2
|
+
export const CoachMarkExamples = [
|
|
3
|
+
{
|
|
4
|
+
title: "storageKey-title-content-placement",
|
|
5
|
+
code: `<OpsnowCommonCoachMark
|
|
6
|
+
storageKey="dashboard-filter-guide"
|
|
7
|
+
title="필터 사용법"
|
|
8
|
+
content="여기서 기간과 계정을 선택해 비용을 필터링할 수 있어요."
|
|
9
|
+
placement="bottom"
|
|
10
|
+
>
|
|
11
|
+
<Button>필터</Button>
|
|
12
|
+
</OpsnowCommonCoachMark>`,
|
|
13
|
+
description: "기본 가이드 말풍선 예제입니다. storageKey는 가이드마다 고유하게 지정하며(localStorage 키로 사용), X로 닫으면 localStorage에 저장되어 새로고침해도 다시 뜨지 않습니다.",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
title: "content-only",
|
|
17
|
+
code: `<OpsnowCommonCoachMark
|
|
18
|
+
storageKey="content-only-guide"
|
|
19
|
+
content="제목 없이 본문만 표시할 수도 있어요."
|
|
20
|
+
placement="right"
|
|
21
|
+
>
|
|
22
|
+
<Button>본문만</Button>
|
|
23
|
+
</OpsnowCommonCoachMark>`,
|
|
24
|
+
description: "title 없이 content만 넘기면 본문만 표시되는 예제입니다.",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
title: "placement-top",
|
|
28
|
+
code: `<OpsnowCommonCoachMark
|
|
29
|
+
storageKey="top-guide"
|
|
30
|
+
title="위쪽 말풍선"
|
|
31
|
+
content="대상 요소 위에 표시됩니다."
|
|
32
|
+
placement="top"
|
|
33
|
+
>
|
|
34
|
+
<Button>placement top</Button>
|
|
35
|
+
</OpsnowCommonCoachMark>`,
|
|
36
|
+
description: "placement로 말풍선 위치를 지정하는 예제입니다 (top/bottom/left/right).",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
title: "placement-left",
|
|
40
|
+
code: `<OpsnowCommonCoachMark
|
|
41
|
+
storageKey="left-guide"
|
|
42
|
+
title="왼쪽 말풍선"
|
|
43
|
+
content="대상 요소 왼쪽에 표시됩니다."
|
|
44
|
+
placement="left"
|
|
45
|
+
>
|
|
46
|
+
<Button>placement left</Button>
|
|
47
|
+
</OpsnowCommonCoachMark>`,
|
|
48
|
+
description: "대상 요소 왼쪽에 표시되는 예제입니다. 공간이 부족하면 MUI가 자동으로 반대쪽으로 flip 됩니다.",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
title: "jsx-content-onClose",
|
|
52
|
+
code: `<OpsnowCommonCoachMark
|
|
53
|
+
storageKey="jsx-guide"
|
|
54
|
+
title="새 기능 안내"
|
|
55
|
+
content={
|
|
56
|
+
<>
|
|
57
|
+
<div>여러 줄로 구성된 안내 문구입니다.</div>
|
|
58
|
+
<div><b>굵은 텍스트</b>나 링크도 넣을 수 있어요.</div>
|
|
59
|
+
</>
|
|
60
|
+
}
|
|
61
|
+
placement="right"
|
|
62
|
+
onClose={() => console.log('closed')}
|
|
63
|
+
>
|
|
64
|
+
<Button>JSX content</Button>
|
|
65
|
+
</OpsnowCommonCoachMark>`,
|
|
66
|
+
description: "content에 JSX를 넘겨 여러 줄/굵은 글씨/링크 등을 표현하고, onClose로 닫힐 때 콜백을 실행하는 예제입니다.",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
title: "actions-button",
|
|
70
|
+
code: `<OpsnowCommonCoachMark
|
|
71
|
+
storageKey="actions-guide"
|
|
72
|
+
title="새 기능 안내"
|
|
73
|
+
content="아래 확인 버튼을 누르면 안내가 닫힙니다."
|
|
74
|
+
placement="bottom"
|
|
75
|
+
actions={(close) => (
|
|
76
|
+
<Button size="small" onClick={close}>확인</Button>
|
|
77
|
+
)}
|
|
78
|
+
>
|
|
79
|
+
<Button>actions 버튼</Button>
|
|
80
|
+
</OpsnowCommonCoachMark>`,
|
|
81
|
+
description: "actions에 함수를 주면 close 인자로 '닫기+영구저장' 핸들러를 받아 하단 우측에 액션 버튼을 표시하는 예제입니다.",
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
title: "reset-dismissed-guides",
|
|
85
|
+
code: `Object.keys(window.localStorage)
|
|
86
|
+
.filter((k) => k.startsWith('opsnow-common-coach-mark:'))
|
|
87
|
+
.forEach((k) => window.localStorage.removeItem(k));
|
|
88
|
+
window.location.reload();`,
|
|
89
|
+
description: "닫힘 기록을 초기화하는 예제입니다. localStorage에서 'opsnow-common-coach-mark:' prefix 키를 제거하면 닫았던 가이드가 다시 표시됩니다.",
|
|
90
|
+
},
|
|
91
|
+
];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// CoachMark 컴포넌트 관련 스키마 정의
|
|
3
|
+
export const CoachMarkSchema = z.object({
|
|
4
|
+
storageKey: z.string().describe("가이드마다 고유하게 지정하는 localStorage 키 (내부적으로 'opsnow-common-coach-mark:' prefix가 붙음) - X로 닫으면 localStorage에 저장되어 새로고침해도 다시 표시되지 않음"),
|
|
5
|
+
title: z.string().optional().describe("가이드 말풍선 제목 - 생략 시 본문만 표시"),
|
|
6
|
+
content: z.string().describe("가이드 말풍선 본문 - 문자열 또는 JSX 사용 가능 (여러 줄/굵은 글씨/링크 등 표현 시 JSX)"),
|
|
7
|
+
isJsxContent: z.boolean().optional().describe("content를 JSX로 렌더링할지 여부 - true면 content를 JSX 표현식으로 출력"),
|
|
8
|
+
placement: z.enum(["top", "bottom", "left", "right"]).optional().describe("말풍선 표시 위치 (top/bottom/left/right) - 공간이 부족하면 MUI가 자동으로 반대쪽으로 flip"),
|
|
9
|
+
onClose: z.string().optional().describe("말풍선이 닫힐 때 실행할 콜백 함수명"),
|
|
10
|
+
actionLabel: z.string().optional().describe("하단 우측 액션 버튼 라벨 - 지정 시 actions={(close) => <Button onClick={close}>라벨</Button>} 형태로 렌더링 (close는 '닫기+영구저장' 핸들러)"),
|
|
11
|
+
});
|
|
12
|
+
// CoachMark 컴포넌트 함수 - 배열 반환
|
|
13
|
+
export function createCoachMarkComponent() {
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
name: "createCoachMark",
|
|
17
|
+
description: `코치마크(가이드 말풍선) 컴포넌트 - 신규 기능/사용법 안내용 말풍선을 대상 요소에 표시
|
|
18
|
+
X로 닫으면 localStorage('opsnow-common-coach-mark:' + storageKey)에 저장되어 새로고침해도 다시 표시되지 않음
|
|
19
|
+
**import 예시:**
|
|
20
|
+
\`\`\`javascript
|
|
21
|
+
import { useCommonComponents } from '@opsnow-common/opsnow-finops-common-ui-loader';
|
|
22
|
+
const { OpsnowCommonCoachMark } = useCommonComponents();
|
|
23
|
+
\`\`\`
|
|
24
|
+
`,
|
|
25
|
+
parameters: CoachMarkSchema,
|
|
26
|
+
handler: async (args) => {
|
|
27
|
+
const props = [];
|
|
28
|
+
props.push(`storageKey="${args.storageKey}"`);
|
|
29
|
+
if (args.title)
|
|
30
|
+
props.push(`title="${args.title}"`);
|
|
31
|
+
if (args.isJsxContent) {
|
|
32
|
+
props.push(`content={${args.content}}`);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
props.push(`content="${args.content}"`);
|
|
36
|
+
}
|
|
37
|
+
if (args.placement)
|
|
38
|
+
props.push(`placement="${args.placement}"`);
|
|
39
|
+
if (args.onClose)
|
|
40
|
+
props.push(`onClose={${args.onClose}}`);
|
|
41
|
+
if (args.actionLabel) {
|
|
42
|
+
props.push(`actions={(close) => (<Button size="small" variant="contained" onClick={close}>${args.actionLabel}</Button>)}`);
|
|
43
|
+
}
|
|
44
|
+
const code = `
|
|
45
|
+
<OpsnowCommonCoachMark
|
|
46
|
+
${props.join("\n ")}
|
|
47
|
+
>
|
|
48
|
+
// 가이드 대상 요소 필요(Mui Button or OpsnowCommonButton 등)
|
|
49
|
+
</OpsnowCommonCoachMark>
|
|
50
|
+
`;
|
|
51
|
+
return {
|
|
52
|
+
content: [
|
|
53
|
+
{
|
|
54
|
+
type: "text",
|
|
55
|
+
text: `\`\`\`jsx\n${code}\n\`\`\``,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
}
|
|
@@ -3,6 +3,7 @@ import { IconExamples, MuiIconExamples } from "./examples/opsnow-common-icons-ex
|
|
|
3
3
|
import { CalendarExamples } from "./examples/opsnow-common-calendar-examples-data.js";
|
|
4
4
|
import { GaugeChartExamples, PieChartExamples, BarChartExamples, LineChartExamples, StackChartExamples, XyMultiChartExamples, HeatmapChartExamples, BubbleChartExamples } from "./examples/opsnow-common-chart-examples-data.js";
|
|
5
5
|
import { TooltipExamples } from "./examples/opsnow-common-tooltip-examples-data.js";
|
|
6
|
+
import { CoachMarkExamples } from "./examples/opsnow-common-coach-mark-examples-data.js";
|
|
6
7
|
import { DataGridExamples } from "./examples/opsnow-common-grid-examples-data.js";
|
|
7
8
|
import { PopupExamples } from "./examples/opsnow-common-popup-examples-data.js";
|
|
8
9
|
import { StepperExamples } from "./examples/opsnow-common-stepper-examples-data.js";
|
|
@@ -47,6 +48,7 @@ const EXAMPLES_MAP = {
|
|
|
47
48
|
HeatmapChart: HeatmapChartExamples,
|
|
48
49
|
BubbleChart: BubbleChartExamples,
|
|
49
50
|
Tooltip: TooltipExamples,
|
|
51
|
+
CoachMark: CoachMarkExamples,
|
|
50
52
|
DataGrid: DataGridExamples,
|
|
51
53
|
Popup: PopupExamples,
|
|
52
54
|
Stepper: StepperExamples,
|
package/build/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { createTabComponent } from "./components/opsnow-common-tab.js";
|
|
|
15
15
|
import { createGridLayoutComponent } from "./components/opsnow-common-layout.js";
|
|
16
16
|
import { createTypographyComponent } from "./components/opsnow-common-typography.js";
|
|
17
17
|
import { createTooltipComponent } from "./components/opsnow-common-tooltip.js";
|
|
18
|
+
import { createCoachMarkComponent } from "./components/opsnow-common-coach-mark.js";
|
|
18
19
|
import { createSelectComponent } from "./components/opsnow-common-select.js";
|
|
19
20
|
import { createPopupComponent } from "./components/opsnow-common-popup.js";
|
|
20
21
|
import { createStepperComponent } from "./components/opsnow-common-stepper.js";
|
|
@@ -103,6 +104,7 @@ const componentFactories = [
|
|
|
103
104
|
createGridLayoutComponent,
|
|
104
105
|
createTypographyComponent,
|
|
105
106
|
createTooltipComponent,
|
|
107
|
+
createCoachMarkComponent,
|
|
106
108
|
createSelectComponent,
|
|
107
109
|
createPopupComponent,
|
|
108
110
|
createStepperComponent,
|