@opsnow-mcp/opsnow-mcp-common-ui-server 1.0.19 → 1.0.21

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.
Files changed (41) hide show
  1. package/package.json +1 -1
  2. package/build/components/data/icon-names.js +0 -129
  3. package/build/components/examples/opsnow-common-calendar-examples-data.js +0 -48
  4. package/build/components/examples/opsnow-common-chart-examples-data.js +0 -6590
  5. package/build/components/examples/opsnow-common-data-status-examples-data.js +0 -65
  6. package/build/components/examples/opsnow-common-file-upload-examples-data.js +0 -95
  7. package/build/components/examples/opsnow-common-forms-examples-data.js +0 -1699
  8. package/build/components/examples/opsnow-common-grid-examples-data.js +0 -2328
  9. package/build/components/examples/opsnow-common-icons-examples-data.js +0 -72
  10. package/build/components/examples/opsnow-common-layout-examples-data.js +0 -72
  11. package/build/components/examples/opsnow-common-notification-examples-data.js +0 -78
  12. package/build/components/examples/opsnow-common-pagination-examples-data.js +0 -82
  13. package/build/components/examples/opsnow-common-popup-examples-data.js +0 -205
  14. package/build/components/examples/opsnow-common-progress-examples-data.js +0 -86
  15. package/build/components/examples/opsnow-common-select-examples-data.js +0 -106
  16. package/build/components/examples/opsnow-common-stepper-examples-data.js +0 -180
  17. package/build/components/examples/opsnow-common-storage-examples-data.js +0 -8
  18. package/build/components/examples/opsnow-common-tab-examples-data.js +0 -87
  19. package/build/components/examples/opsnow-common-toast-popup-examples-data.js +0 -129
  20. package/build/components/examples/opsnow-common-tooltip-examples-data.js +0 -80
  21. package/build/components/examples/opsnow-common-typography-examples-data.js +0 -366
  22. package/build/components/opsnow-common-calendar.js +0 -228
  23. package/build/components/opsnow-common-chart.js +0 -1643
  24. package/build/components/opsnow-common-data-status.js +0 -116
  25. package/build/components/opsnow-common-examples.js +0 -109
  26. package/build/components/opsnow-common-file-upload.js +0 -57
  27. package/build/components/opsnow-common-forms.js +0 -1006
  28. package/build/components/opsnow-common-grid.js +0 -352
  29. package/build/components/opsnow-common-icons.js +0 -139
  30. package/build/components/opsnow-common-layout.js +0 -138
  31. package/build/components/opsnow-common-notification.js +0 -110
  32. package/build/components/opsnow-common-pagination.js +0 -164
  33. package/build/components/opsnow-common-popup.js +0 -71
  34. package/build/components/opsnow-common-progress.js +0 -177
  35. package/build/components/opsnow-common-select.js +0 -132
  36. package/build/components/opsnow-common-stepper.js +0 -72
  37. package/build/components/opsnow-common-tab.js +0 -111
  38. package/build/components/opsnow-common-toast-popup.js +0 -135
  39. package/build/components/opsnow-common-tooltip.js +0 -204
  40. package/build/components/opsnow-common-typography.js +0 -93
  41. package/build/index.js +0 -124
@@ -1,2328 +0,0 @@
1
- // DataGrid 컴포넌트 예제 데이터
2
- export const DataGridExamples = [
3
- {
4
- title: '기본 데이터 그리드',
5
- description: '기본 데이터 그리드 예제입니다.',
6
- code_props_usage: `
7
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
8
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
9
-
10
- // 컬럼 정의
11
- const columnDefs = [
12
- { headerName: 'Make', field: 'make' },
13
- { headerName: 'Model', field: 'model' },
14
- { headerName: 'Price', field: 'price' },
15
- ]
16
-
17
- // 데이터 정의
18
- const initRowData = [
19
- { make: 'Toyota', model: 'Celica', price: 35000 },
20
- { make: 'Ford', model: 'Mondeo', price: 32000 },
21
- { make: 'Porsche', model: 'Boxster', price: 72000 }
22
- ]
23
-
24
- const gridOptions = {
25
- animateRows: true,
26
- // 체크박스 사용하고 싶지 않으면 checkboxes 를 false로 해야됨.
27
- // enableClickSelection: 행 선택은 활성화 시키고 싶으면 true로 설정
28
- rowSelection: { mode: 'singleRow', checkboxes: false, enableClickSelection: true },
29
- tooltipShowDelay: 100,
30
- domLayout: 'autoHeight',
31
- }
32
-
33
- const { OpsnowCommonDataGrid } = useCommonComponents();
34
- const { CommonConst } = useGlobalContext()
35
- // rowData와 status 상태를 관리
36
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
37
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
38
- const gridRef = useRef(null)
39
-
40
- // 데이터 지연 설정을 위한 useEffect
41
- useEffect(() => {
42
- // 1초 후에 데이터를 설정
43
- const timeoutId = setTimeout(() => {
44
- setRowData(initRowData)
45
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
46
- }, 1000)
47
-
48
- // 컴포넌트 언마운트 시 타임아웃 클리어
49
- return () => {
50
- clearTimeout(timeoutId)
51
- }
52
- }, [])
53
- `,
54
- code: `<OpsnowCommonDataGrid
55
- key={status}
56
- columnDefs={columnDefs}
57
- rowData={rowData}
58
- status={status} // 상태를 전달
59
- gridOptions={gridOptions}
60
- langCd={i18n.getLocale()}
61
- />`
62
- },
63
- {
64
- title: 'Search + Pagination 추가',
65
- description: 'Search + Pagination 추가 예제입니다.',
66
- code_props_usage: `
67
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
68
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
69
-
70
- // 컬럼 정의
71
- const columnDefs = [
72
- { headerName: 'Make', field: 'make' },
73
- { headerName: 'Model', field: 'model' },
74
- { headerName: 'Price', field: 'price' },
75
- ]
76
-
77
- // 데이터 정의
78
- const initRowData = [
79
- { make: 'Toyota', model: 'Celica', price: 35000 },
80
- { make: 'Ford', model: 'Mondeo', price: 32000 },
81
- { make: 'Porsche', model: 'Boxster', price: 72000 }
82
- ]
83
-
84
- const gridOptions = {
85
- animateRows: true,
86
- // 체크박스 사용하고 싶지 않으면 checkboxes 를 false로 해야됨.
87
- // enableClickSelection: 행 선택은 활성화 시키고 싶으면 true로 설정
88
- rowSelection: { mode: 'singleRow', checkboxes: false, enableClickSelection: true },
89
- tooltipShowDelay: 100,
90
- domLayout: 'autoHeight',
91
- }
92
-
93
- const { OpsnowCommonDataGrid } = useCommonComponents();
94
- const { CommonConst } = useGlobalContext()
95
- // rowData와 status 상태를 관리
96
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
97
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
98
- const gridRef = useRef(null)
99
-
100
- // 데이터 지연 설정을 위한 useEffect
101
- useEffect(() => {
102
- // 1초 후에 데이터를 설정
103
- const timeoutId = setTimeout(() => {
104
- setRowData(initRowData)
105
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
106
- }, 1000)
107
-
108
- // 컴포넌트 언마운트 시 타임아웃 클리어
109
- return () => {
110
- clearTimeout(timeoutId)
111
- }
112
- }, [])
113
- `,
114
- code: `<OpsnowCommonDataGrid
115
- columnDefs={columnDefs}
116
- rowData={rowData}
117
- status={status} // 상태를 전달
118
- gridOptions={gridOptions}
119
- usedSearch={true}
120
- pagination={true}
121
- langCd={i18n.getLocale()}
122
- />`
123
- },
124
- {
125
- title: 'Insert Button Inside the Common Grid Search Section',
126
- description: 'Insert Button Inside the Common Grid Search Section 예제입니다.',
127
- code_props_usage: `
128
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
129
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
130
-
131
- // 컬럼 정의
132
- const columnDefs = [
133
- { headerName: 'Make', field: 'make' },
134
- { headerName: 'Model', field: 'model' },
135
- { headerName: 'Price', field: 'price' },
136
- ]
137
-
138
- // 데이터 정의
139
- const initRowData = [
140
- { make: 'Toyota', model: 'Celica', price: 35000 },
141
- { make: 'Ford', model: 'Mondeo', price: 32000 },
142
- { make: 'Porsche', model: 'Boxster', price: 72000 }
143
- ]
144
-
145
- const gridOptions = {
146
- animateRows: true,
147
- // 체크박스 사용하고 싶지 않으면 checkboxes 를 false로 해야됨.
148
- // enableClickSelection: 행 선택은 활성화 시키고 싶으면 true로 설정
149
- rowSelection: { mode: 'singleRow', checkboxes: false, enableClickSelection: true },
150
- tooltipShowDelay: 100,
151
- domLayout: 'autoHeight',
152
- }
153
-
154
- const { OpsnowCommonDataGrid, OpsnowCommonButton } = useCommonComponents();
155
- const { CommonConst } = useGlobalContext()
156
- // rowData와 status 상태를 관리
157
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
158
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
159
- const gridRef = useRef(null)
160
-
161
- // 데이터 지연 설정을 위한 useEffect
162
- useEffect(() => {
163
- // 1초 후에 데이터를 설정
164
- const timeoutId = setTimeout(() => {
165
- setRowData(initRowData)
166
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
167
- }, 1000)
168
-
169
- // 컴포넌트 언마운트 시 타임아웃 클리어
170
- return () => {
171
- clearTimeout(timeoutId)
172
- }
173
- }, [])
174
-
175
- // 다운로드 핸들러
176
- const downloadTest = () => {
177
- if (gridRef.current) {
178
- gridRef.current.downloadExcel('test.xlsx')
179
- // 또는 CSV 다운로드
180
- // gridRef1.current.downloadCsv('test.csv')
181
- }
182
- }
183
- `,
184
- code: `<OpsnowCommonDataGrid
185
- ref={gridRef}
186
- columnDefs={columnDefs}
187
- rowData={rowData}
188
- status={status} // 상태를 전달
189
- gridOptions={gridOptions}
190
- usedSearch={true}
191
- pagination={true}
192
- langCd={i18n.getLocale()}
193
- >
194
- <OpsnowCommonButton
195
- label={'Download Excel'}
196
- size="large"
197
- variant="outlined"
198
- color="secondary"
199
- onClick={downloadTest}
200
- style={{ marginRight: '8px' }}
201
- />
202
- <OpsnowCommonButton
203
- label={'Download CSV'}
204
- size="large"
205
- variant="outlined"
206
- color="secondary"
207
- onClick={() => gridRef.current?.downloadCsv('test.csv')}
208
- />
209
- </OpsnowCommonDataGrid>`
210
- },
211
- {
212
- title: 'Header Filter, Tooltip, Sort',
213
- description: 'Header Filter, Tooltip, Sort 예제입니다.',
214
- code_props_usage: `
215
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
216
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
217
-
218
- // 컬럼 정의
219
- const columnDefs = [
220
- {
221
- headerName: 'Make',
222
- field: 'make',
223
- colId: 'make',
224
- headerComponentParams: { tooltipInfoText: 'Percentage Share of Sales' },
225
- },
226
- {
227
- headerName: 'Model',
228
- field: 'model',
229
- colId: 'model',
230
- },
231
- {
232
- headerName: 'Price',
233
- field: 'price',
234
- colId: 'price',
235
- headerComponentParams: { filter: true },
236
- // sortable: false,
237
- },
238
- {
239
- headerName: 'Test1',
240
- field: 'test1',
241
- colId: 'test1',
242
- headerComponentParams: {
243
- tooltipInfoText: 'test22',
244
- tooltipField: 'title',
245
- filter: true,
246
- filterParams: { showTooltips: true },
247
- },
248
- },
249
- ]
250
-
251
- // 데이터 정의
252
- const initRowData = [
253
- {
254
- make: 'Toyota',
255
- model: 'Celica',
256
- price: 35000,
257
- test1: 'abc',
258
- test2: 'def'
259
- },
260
- {
261
- make: 'Ford',
262
- model: 'Mondeo',
263
- price: 32000,
264
- test1: 'abc',
265
- test2: 'def'
266
- },
267
- {
268
- make: 'Porsche',
269
- model: 'Boxter',
270
- price: 72000,
271
- test1: 'abc',
272
- test2: 'def'
273
- },
274
- ]
275
-
276
- const gridOptions = {
277
- animateRows: true,
278
- rowSelection: { mode: 'multiRow', enableSelectionWithoutKeys: true, headerCheckbox: true },
279
- tooltipShowDelay: 100,
280
- domLayout: 'autoHeight',
281
- }
282
-
283
- const defaultColDef = {
284
- wrapText: true,
285
- autoHeight: true,
286
- suppressMenu: true,
287
- unSortIcon: true,
288
- sortable: true,
289
- }
290
-
291
- const { OpsnowCommonDataGrid, OpsnowCommonButton } = useCommonComponents();
292
- const { CommonConst } = useGlobalContext()
293
- // rowData와 status 상태를 관리
294
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
295
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
296
- const gridRef = useRef(null)
297
-
298
- // 데이터 지연 설정을 위한 useEffect
299
- useEffect(() => {
300
- // 1초 후에 데이터를 설정
301
- const timeoutId = setTimeout(() => {
302
- setRowData(initRowData)
303
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
304
- }, 1000)
305
-
306
- // 컴포넌트 언마운트 시 타임아웃 클리어
307
- return () => {
308
- clearTimeout(timeoutId)
309
- }
310
- }, [])
311
-
312
- const filterClickTest = (columnName, data) => {
313
- if (gridRef.current) {
314
- gridRef.current.updateFilter(columnName, data)
315
- }
316
- }
317
- `,
318
- code: `<OpsnowCommonDataGrid
319
- ref={gridRef}
320
- key={status}
321
- columnDefs={columnDefs}
322
- defaultColDef={defaultColDef}
323
- rowData={rowData}
324
- status={status} // 상태를 전달
325
- gridOptions={gridOptions}
326
- langCd={i18n.getLocale()}
327
- >
328
- <OpsnowCommonButton
329
- label={'Filter click'}
330
- size="large"
331
- variant="outlined"
332
- color="secondary"
333
- onClick={() => filterClickTest('test2', ['def', 'def1'])}
334
- style={{ marginRight: '8px' }}
335
- />
336
- </OpsnowCommonDataGrid>`
337
- },
338
- {
339
- title: 'Custom Header and Number Tooltip',
340
- description: 'Custom Header and Number Tooltip 예제입니다.',
341
- code_props_usage: `
342
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
343
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
344
- import UserCustomHeaderCellRenderer from './renderer/UserCustomCellRenderer.jsx'
345
-
346
- // 날짜 범위 정의
347
- const dateRange = [
348
- '2024-11-05',
349
- '2024-11-06',
350
- '2024-11-07'
351
- ]
352
-
353
- // 데이터 정의
354
- const initRowData = [
355
- {
356
- 'displayItem': 'OpsNow - NOS (557892227155)',
357
- 'item': '557892227155',
358
- 'total': 31102.50521165911,
359
- 'share': '34.08',
360
- '2024-11-05': 519.7175092481002,
361
- '2024-11-06': 609.6942034389001,
362
- '2024-11-07': 519.8121360272003
363
- },
364
- {
365
- 'displayItem': 'OpsNow - PRD (216093335544)',
366
- 'item': '216093335544',
367
- 'total': 30617.525577458808,
368
- 'share': '33.55',
369
- '2024-11-05': 1211.0008080524017,
370
- '2024-11-06': 1044.3593467060014,
371
- '2024-11-07': 1019.0596313015008
372
- },
373
- {
374
- 'displayItem': '766276932394 (766276932394)',
375
- 'item': '766276932394',
376
- 'total': 4723.605532871798,
377
- 'share': '5.18',
378
- '2024-11-05': 0,
379
- '2024-11-06': 0,
380
- '2024-11-07': 0
381
- },
382
- ]
383
-
384
- // 컬럼 정의
385
- const columnDefs = [
386
- {
387
- headerName: 'Display Item',
388
- field: 'displayItem',
389
- pinned: 'left',
390
- width: 300,
391
- minWidth: 300,
392
- },
393
- {
394
- headerName: 'Total Spend',
395
- field: 'total',
396
- pinned: 'left',
397
- type: ['number', 'mixFormat'],
398
- cellRendererParams: (params) => {
399
- // any 대신 ICellRendererParams<RowData, number> 사용
400
- // params.value가 number인지 확인하는 타입 가드
401
- if (typeof params.value === 'number' && params.value > 4500) {
402
- return {
403
- typeParams: { isPercent: true },
404
- }
405
- }
406
-
407
- return {
408
- typeParams: { currency: 'USD' },
409
- }
410
- },
411
- },
412
- ...dateRange.map((element) => ({
413
- headerName: element,
414
- field: element,
415
- width: 150,
416
- minWidth: 150,
417
- type: ['number', 'cost', 'numberTooltip'],
418
- cellRendererParams: {
419
- typeParams: {
420
- currency: 'USD',
421
- iconRight: true,
422
- },
423
- },
424
- headerComponent: UserCustomHeaderCellRenderer,
425
- headerComponentParams: { dropdownList: dateRange, defaultValue: element },
426
- })),
427
- ]
428
-
429
- const gridOptions = {
430
- animateRows: true,
431
- rowSelection: { mode: 'multiRow', enableSelectionWithoutKeys: true },
432
- tooltipShowDelay: 100,
433
- domLayout: 'autoHeight',
434
- }
435
-
436
- const defaultColDef = {
437
- wrapText: true,
438
- autoHeight: true,
439
- suppressMenu: true,
440
- unSortIcon: true,
441
- sortable: true,
442
- }
443
-
444
- const { OpsnowCommonDataGrid } = useCommonComponents();
445
- const { CommonConst } = useGlobalContext()
446
- // rowData와 status 상태를 관리
447
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
448
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
449
- const [pinnedTopRowData, setPinnedTopRowData] = useState(null)
450
- const gridRef = useRef(null)
451
-
452
- // 데이터 지연 설정을 위한 useEffect
453
- useEffect(() => {
454
- const timeoutId = setTimeout(() => {
455
- // (1) totalCost를 직접 계산하거나 임의로 지정
456
- const totalCost = 99999.99
457
-
458
- // (2) totalItem 생성
459
- const totalItem = {
460
- displayItem: 'Total',
461
- total: totalCost,
462
- share: totalCost === 0 ? '0' : '100.00',
463
- }
464
-
465
- // (3) 날짜별 합계 계산 → totalItem에 해당 날짜 키로 저장
466
- dateRange.forEach((date) => {
467
- totalItem[date] = initRowData.reduce((acc, obj) => {
468
- return acc + (obj[date] || 0)
469
- }, 0)
470
- })
471
-
472
- // (4) 기존 rowData 끝에 totalItem 추가
473
- const newRowData = [...initRowData, totalItem]
474
-
475
- // (5) pinned top row로 totalItem 설정
476
- setPinnedTopRowData([totalItem])
477
-
478
- // (6) setRowData 호출 → 실제 데이터 그리드 표에 표시될 rowData 갱신
479
- setRowData(newRowData)
480
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
481
- }, 1000)
482
-
483
- return () => {
484
- clearTimeout(timeoutId)
485
- }
486
- }, [])
487
- `,
488
- code: `<OpsnowCommonDataGrid
489
- ref={gridRef}
490
- key={status}
491
- columnDefs={columnDefs}
492
- defaultColDef={defaultColDef}
493
- rowData={rowData}
494
- status={status} // 상태를 전달
495
- gridOptions={gridOptions}
496
- pagination={true}
497
- pinnedTopRowData={pinnedTopRowData} // pinned row 전달
498
- langCd={i18n.getLocale()}
499
- />`
500
- },
501
- {
502
- title: 'Using a three-dots header with a custom header (including filter and sort)',
503
- description: 'Using a three-dots header with a custom header (including filter and sort) 예제입니다.',
504
- code_props_usage: `
505
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
506
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
507
- import SingleHeaderTwoLineCustomHeader from './renderer/SingleHeaderTwoLineCustomHeader' // 커스텀 헤더 컴포넌트
508
-
509
- // 기본 컬럼 정의
510
- const defaultColDef = {
511
- wrapText: true,
512
- autoHeight: true,
513
- suppressMenu: true, // 개별 컬럼에서 메뉴를 노출하려면 재설정할 예정
514
- resizable: true,
515
- sortable: false,
516
- unSortIcon: true,
517
- }
518
-
519
- // 컬럼 정의 (custom header 사용)
520
- const columnDefs = [
521
- {
522
- headerName: 'Days (Values Not Provided)',
523
- field: 'days',
524
- headerComponent: SingleHeaderTwoLineCustomHeader,
525
- headerComponentParams: {
526
- displayData1: 'P1 (8/8-15)',
527
- isUsedMenuFilter: false, // 필터 버튼은 노출하지 않음
528
- },
529
- sortable: true,
530
- },
531
- {
532
- headerName: 'Numbers',
533
- field: 'numbers',
534
- // 필요한 경우 suppressHeaderMenuButton 등 추가 옵션 적용 가능
535
- },
536
- ]
537
-
538
- const gridOptions = {
539
- animateRows: true,
540
- suppressCellFocus: true,
541
- suppressPaginationPanel: true,
542
- rowSelection: { mode: 'singleRow', checkboxes: false, enableSelectionWithoutKeys: true },
543
- domLayout: 'autoHeight',
544
- suppressMenuHide: false, // 마우스 오버 없이 메뉴 버튼 항상 표시 (필요시 조정)
545
- }
546
-
547
- const { OpsnowCommonDataGrid } = useCommonComponents();
548
- const { CommonConst } = useGlobalContext()
549
- // rowData와 status 상태를 관리
550
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
551
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
552
- const gridRef = useRef(null)
553
-
554
- // 데이터 지연 설정을 위한 useEffect
555
- useEffect(() => {
556
- const timeoutId = setTimeout(() => {
557
- setRowData(getRowData())
558
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
559
- }, 1000)
560
-
561
- return () => {
562
- clearTimeout(timeoutId)
563
- }
564
- }, [])
565
-
566
- // 행 데이터 생성 함수
567
- const getRowData = () => {
568
- const weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
569
- const rows = []
570
- for (let i = 0; i < 200; i++) {
571
- const index = Math.floor(Math.random() * weekdays.length)
572
- rows.push({ days: weekdays[index], numbers: index })
573
- }
574
- return rows
575
- }
576
- `,
577
- code: `<OpsnowCommonDataGrid
578
- ref={gridRef}
579
- key={status}
580
- columnDefs={columnDefs}
581
- defaultColDef={defaultColDef}
582
- rowData={rowData}
583
- status={status} // 상태 전달
584
- gridOptions={gridOptions}
585
- usedSearch={true}
586
- usedMenuItem={true}
587
- langCd={i18n.getLocale()}
588
- />`
589
- },
590
- {
591
- title: 'Master / Detail Cell',
592
- description: 'Master / Detail Cell 예제입니다.',
593
- code_props_usage: `
594
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
595
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
596
- import DetailCellRenderer from './renderer/DetailCellRenderer' // 커스텀 헤더 컴포넌트
597
-
598
- // 컬럼 정의 (custom header 사용)
599
- const columnDefs = [
600
- {
601
- field: 'make',
602
- pinned: 'left',
603
- lockPinned: true,
604
- // AG Grid의 그룹 셀 렌더러 (마스터-디테일에서 그룹 펼치기/접기 사용)
605
- cellRenderer: 'agGroupCellRenderer',
606
- },
607
- { field: 'model' },
608
- { field: 'price' },
609
- { field: 'test1' },
610
- { field: 'test2' },
611
- ]
612
-
613
- // 데이터 정의
614
- const initRowData = [
615
- { make: 'Total', price: 3948475 },
616
- { make: 'Toyota', model: 'Celica', price: 35000, test1: 'test1', test2: 'test2' },
617
- { make: 'Ford', model: 'Mondeo', price: 32000, test1: 'test1', test2: 'test2' },
618
- { make: 'Porsche', model: 'Boxster', price: 72000, test1: 'test1', test2: 'test2' }
619
- ]
620
-
621
- const gridOptions = {
622
- animateRows: true,
623
- //rowSelection: { mode: 'multiRow', checkboxes: false, headerCheckbox: false },
624
- masterDetail: true,
625
- domLayout: 'autoHeight',
626
- detailCellRenderer: DetailCellRenderer,
627
- }
628
-
629
- const { OpsnowCommonDataGrid } = useCommonComponents();
630
- const { CommonConst } = useGlobalContext()
631
- // rowData와 status 상태를 관리
632
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
633
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
634
-
635
- // 마운트 시점에 데이터 로딩 시뮬레이션
636
- useEffect(() => {
637
- const timer = setTimeout(() => {
638
- setRowData(initRowData)
639
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
640
- }, 1000)
641
-
642
- return () => clearTimeout(timer)
643
- }, [])
644
- `,
645
- code: `<OpsnowCommonDataGrid
646
- columnDefs={columnDefs}
647
- rowData={rowData}
648
- status={status}
649
- gridOptions={gridOptions}
650
- langCd={i18n.getLocale()}
651
- />`
652
- },
653
- {
654
- title: 'No Data',
655
- description: 'No Data 예제입니다.',
656
- code_props_usage: `
657
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
658
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
659
-
660
- // 컬럼 정의 (custom header 사용)
661
- const columnDefs = [
662
- { headerName: 'Make', field: 'make' },
663
- { headerName: 'Model', field: 'model' },
664
- { headerName: 'Price', field: 'price' },
665
- ]
666
-
667
- const defaultColDef = {
668
- wrapText: true,
669
- autoHeight: true,
670
- suppressMenu: true,
671
- unSortIcon: true,
672
- sortable: false,
673
- }
674
-
675
- const gridOptions = {
676
- animateRows: true,
677
- domLayout: 'autoHeight',
678
- }
679
-
680
- const { OpsnowCommonDataGrid } = useCommonComponents();
681
- const { CommonConst } = useGlobalContext()
682
- `,
683
- code: `<OpsnowCommonDataGrid
684
- columnDefs={columnDefs}
685
- rowData={[]}
686
- gridOptions={gridOptions}
687
- status={CommonConst.GRID_STATUS.DATA_EXISTS}
688
- defaultColDef={defaultColDef}
689
- langCd={i18n.getLocale()}
690
- />`
691
- },
692
- {
693
- title: 'Custom No Data',
694
- description: 'Custom No Data 예제입니다.',
695
- code_props_usage: `
696
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
697
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
698
- import CustomNoData from './renderer/CustomNoData'
699
-
700
- // 컬럼 정의 (custom header 사용)
701
- const columnDefs = [
702
- { headerName: 'Make', field: 'make' },
703
- { headerName: 'Model', field: 'model' },
704
- { headerName: 'Price', field: 'price' },
705
- ]
706
-
707
- const defaultColDef = {
708
- wrapText: true,
709
- autoHeight: true,
710
- suppressMenu: true,
711
- unSortIcon: true,
712
- sortable: false,
713
- }
714
-
715
- const gridOptions = {
716
- animateRows: true,
717
- domLayout: 'autoHeight',
718
- }
719
-
720
- const { OpsnowCommonDataGrid } = useCommonComponents();
721
- const { CommonConst } = useGlobalContext()
722
- `,
723
- code: `<OpsnowCommonDataGrid
724
- columnDefs={columnDefs}
725
- rowData={[]}
726
- gridOptions={gridOptions}
727
- status={CommonConst.GRID_STATUS.DATA_EXISTS}
728
- defaultColDef={defaultColDef}
729
- noDataCustomComponent={CustomNoData}
730
- langCd={i18n.getLocale()}
731
- />`
732
- },
733
- {
734
- title: 'Pivot, Sidebar',
735
- description: 'Pivot, Sidebar 예제입니다. 피벗이나 사이드바를 사용할 때는 높이가 항상 고정되어야 함(autoHeight는 허용되지 않음).',
736
- code_props_usage: `
737
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
738
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
739
-
740
- // defaultColDef
741
- const defaultColDef = {
742
- suppressMenu: true,
743
- unSortIcon: false,
744
- sortable: false,
745
- flex: 1,
746
- }
747
-
748
- // 컬럼 정의
749
- const columnDefs = [
750
- {
751
- field: 'company_name',
752
- rowGroup: true,
753
- enableRowGroup: true,
754
- enablePivot: true,
755
- },
756
- {
757
- field: 'linked_account_id',
758
- rowGroup: true,
759
- pivot: true,
760
- enableRowGroup: true,
761
- enablePivot: true,
762
- },
763
- {
764
- field: 'product_name',
765
- rowGroup: true,
766
- enableRowGroup: true,
767
- enablePivot: true,
768
- },
769
- {
770
- field: 'region_name',
771
- rowGroup: true,
772
- enableRowGroup: true,
773
- enablePivot: true,
774
- },
775
- {
776
- field: 'instance_family',
777
- rowGroup: true,
778
- enableRowGroup: true,
779
- enablePivot: true,
780
- },
781
- {
782
- field: 'on_demand_cost',
783
- aggFunc: 'sum',
784
- enableValue: true,
785
- type: ['number', 'cost', 'numberTooltip'],
786
- cellRendererParams: {
787
- typeParams: {
788
- currency: 'USD',
789
- },
790
- },
791
- },
792
- {
793
- field: 'savings_plans_on_demand_cost_equivalent',
794
- aggFunc: 'sum',
795
- enableValue: true,
796
- type: ['number', 'cost', 'numberTooltip'],
797
- cellRendererParams: {
798
- typeParams: {
799
- currency: 'USD',
800
- },
801
- },
802
- },
803
- {
804
- field: 'total_on_demand_cost_equivalent',
805
- aggFunc: 'sum',
806
- enableValue: true,
807
- type: ['number', 'cost', 'numberTooltip'],
808
- cellRendererParams: {
809
- typeParams: {
810
- currency: 'USD',
811
- },
812
- },
813
- },
814
- ]
815
-
816
- // 데이터 정의
817
- const initRowData = [
818
- {
819
- "company_name": "smilegate",
820
- "linked_account_id": "008969382493",
821
- "product_name": "EC2",
822
- "region_name": "Asia Pacific (Tokyo)",
823
- "instance_family": "t2",
824
- "on_demand_cost": 0,
825
- "savings_plans_on_demand_cost_equivalent": 80.79280000000004,
826
- "total_on_demand_cost_equivalent": 80.79280000000004
827
- },
828
- {
829
- "company_name": "smilegate",
830
- "linked_account_id": "008969382493",
831
- "product_name": "EC2",
832
- "region_name": "Asia Pacific (Tokyo)",
833
- "instance_family": "t3",
834
- "on_demand_cost": 0,
835
- "savings_plans_on_demand_cost_equivalent": 120.71359999999994,
836
- "total_on_demand_cost_equivalent": 120.71359999999994
837
- },
838
- {
839
- "company_name": "smilegate",
840
- "linked_account_id": "050451403493",
841
- "product_name": "EC2",
842
- "region_name": "Asia Pacific (Seoul)",
843
- "instance_family": "t2",
844
- "on_demand_cost": 0,
845
- "savings_plans_on_demand_cost_equivalent": 10.655999999999997,
846
- "total_on_demand_cost_equivalent": 10.655999999999997
847
- }
848
- ]
849
-
850
- const gridOptions = {
851
- animateRows: true,
852
- suppressCellFocus: true,
853
- suppressPaginationPanel: true,
854
- rowSelection: { mode: 'singleRow', enableClickSelection: true },
855
- pivotMode: true, // pivot 기본 활성
856
- autoGroupColumnDef: { minWidth: 300, sortable: false },
857
- sideBar: 'columns', // 사이드바 활성
858
- groupDefaultExpanded: -1,
859
- }
860
-
861
- const { OpsnowCommonDataGrid } = useCommonComponents();
862
- const { CommonConst } = useGlobalContext()
863
- // rowData와 status 상태를 관리
864
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
865
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
866
-
867
- // 데이터 지연 설정을 위한 useEffect
868
- useEffect(() => {
869
- // 1초 후에 데이터를 설정
870
- const timeoutId = setTimeout(() => {
871
- setRowData(initRowData)
872
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
873
- }, 1000)
874
-
875
- // 컴포넌트 언마운트 시 타임아웃 클리어
876
- return () => {
877
- clearTimeout(timeoutId)
878
- }
879
- }, [])
880
- `,
881
- code: `<OpsnowCommonDataGrid
882
- rowData={currentDataList}
883
- columnDefs={columnDefs}
884
- defaultColDef={defaultColDef}
885
- status={gridStatus}
886
- gridOptions={gridOptions}
887
- useOpsnowUs={true}
888
- usedSearch={true}
889
- gridHeight={800} // 높이 고정
890
- langCd={i18n.getLocale()}
891
- />`
892
- },
893
- {
894
- title: 'Ratio Bar',
895
- description: 'Ratio Bar 예제입니다.',
896
- code_props_usage: `
897
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
898
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
899
-
900
- // 컬럼 정의
901
- const columnDefs = [
902
- { headerName: 'Make', field: 'make', colId: 'make' },
903
- { headerName: 'Model', field: 'model', colId: 'model' },
904
- { headerName: 'Price', field: 'price', colId: 'price' },
905
- {
906
- headerName: 'Share',
907
- field: 'shareRatio',
908
- colId: 'shareRatio', // colId 추가
909
- resizable: true,
910
- cellStyle: {
911
- display: 'flex',
912
- justifyContent: 'center',
913
- alignItems: 'center',
914
- },
915
- width: 200,
916
- minWidth: 150,
917
- maxWidth: 200,
918
- headerComponentParams: { tooltipInfoText: 'Percentage Share of Sales' }, // tooltipInfoText 수정
919
- type: ['ratioBar'],
920
- cellRendererParams: {
921
- typeParams: {
922
- value: {
923
- type: 'ratio',
924
- },
925
- label: {
926
- postfix: '%',
927
- location: 'right',
928
- },
929
- },
930
- },
931
- },
932
- {
933
- headerName: 'Cost Composition by Type',
934
- field: 'totalCost',
935
- colId: 'totalCost', // colId 추가
936
- resizable: true,
937
- cellStyle: {
938
- display: 'flex',
939
- justifyContent: 'center',
940
- alignItems: 'center',
941
- },
942
- width: 230,
943
- minWidth: 230,
944
- maxWidth: 260,
945
- type: ['ratioBar'],
946
- cellRendererParams: {
947
- typeParams: {
948
- fields: ['riCost', 'spCost'],
949
- value: {
950
- type: 'value',
951
- },
952
- },
953
- },
954
- },
955
- ]
956
-
957
- // 데이터 정의
958
- const initRowData = [
959
- {
960
- make: 'Toyota',
961
- model: 'Celica',
962
- price: 35000,
963
- spCost: '2.5',
964
- riCost: 20.5,
965
- totalCost: 50.0,
966
- shareRatio: 40,
967
- },
968
- {
969
- make: 'Ford',
970
- model: 'Mondeo',
971
- price: 32000,
972
- spCost: '3.0',
973
- riCost: 15.0,
974
- totalCost: 45.0,
975
- shareRatio: 35,
976
- },
977
- {
978
- make: 'Porsche',
979
- model: 'Boxter',
980
- price: 72000,
981
- spCost: '4.0',
982
- riCost: 25.0,
983
- totalCost: 70.0,
984
- shareRatio: 50,
985
- }
986
- ]
987
-
988
- const gridOptions = {
989
- animateRows: true,
990
- rowSelection: { mode: 'multiRow' },
991
- tooltipShowDelay: 100,
992
- domLayout: 'autoHeight',
993
- }
994
-
995
- const defaultColDef = {
996
- wrapText: true,
997
- autoHeight: true,
998
- suppressMenu: true,
999
- unSortIcon: true,
1000
- sortable: true,
1001
- }
1002
-
1003
- const { OpsnowCommonDataGrid } = useCommonComponents();
1004
- const { CommonConst } = useGlobalContext()
1005
- // rowData와 status 상태를 관리
1006
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
1007
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
1008
- const gridRef = useRef(null)
1009
-
1010
- // 데이터 지연 설정을 위한 useEffect
1011
- useEffect(() => {
1012
- // 1초 후에 데이터를 설정
1013
- const timeoutId = setTimeout(() => {
1014
- setRowData(initRowData)
1015
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
1016
- }, 1000)
1017
-
1018
- // 컴포넌트 언마운트 시 타임아웃 클리어
1019
- return () => {
1020
- clearTimeout(timeoutId)
1021
- }
1022
- }, [])
1023
- `,
1024
- code: `<OpsnowCommonDataGrid
1025
- ref={gridRef}
1026
- key={status}
1027
- columnDefs={columnDefs}
1028
- defaultColDef={defaultColDef}
1029
- rowData={rowData}
1030
- status={status} // 상태를 전달
1031
- gridOptions={gridOptions}
1032
- langCd={i18n.getLocale()}
1033
- />`
1034
- },
1035
- {
1036
- title: 'Data Bar',
1037
- description: 'Excel 스타일의 Data Bar 예제입니다. 셀 배경에 값에 비례하는 막대를 표시합니다. 월별 비용 데이터를 시각화하는 예제입니다.',
1038
- code_props_usage: `
1039
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
1040
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
1041
-
1042
- // 월별 비용 데이터
1043
- const initRowData = [
1044
- { product: 'Amazon Elastic Compute Cloud', cost_202410: 11255, cost_202411: 18464, cost_202412: 17335, cost_202501: 18731, cost_202502: 20358, cost_202503: 27291 },
1045
- { product: 'Amazon CloudFront', cost_202410: 10055, cost_202411: 13741, cost_202412: 12527, cost_202501: 14702, cost_202502: 17044, cost_202503: 23615 },
1046
- { product: 'AWS Data Transfer', cost_202410: 13308, cost_202411: 18896, cost_202412: 16358, cost_202501: 16044, cost_202502: 15475, cost_202503: 21206 },
1047
- { product: 'Amazon Relational Database Service', cost_202410: 12057, cost_202411: 13592, cost_202412: 12883, cost_202501: 11609, cost_202502: 10681, cost_202503: 13413 },
1048
- { product: 'AmazonCloudWatch', cost_202410: 11107, cost_202411: 6883, cost_202412: 6623, cost_202501: 6391, cost_202502: 6295, cost_202503: 8128 },
1049
- { product: 'Amazon Managed Streaming for Apache Kafka', cost_202410: 5555, cost_202411: 5423, cost_202412: 5555, cost_202501: 6131, cost_202502: 6193, cost_202503: 7631 },
1050
- { product: 'Elastic Load Balancing', cost_202410: 2482, cost_202411: 4760, cost_202412: 3651, cost_202501: 4464, cost_202502: 4219, cost_202503: 6394 },
1051
- { product: 'AWS WAF', cost_202410: 3714, cost_202411: 4362, cost_202412: 3768, cost_202501: 3490, cost_202502: 3776, cost_202503: 4905 },
1052
- ]
1053
-
1054
- // 월 필드 목록
1055
- const monthFields = [
1056
- 'cost_202410', 'cost_202411', 'cost_202412',
1057
- 'cost_202501', 'cost_202502', 'cost_202503'
1058
- ]
1059
-
1060
- // 최대값 계산 (바 스케일링용)
1061
- const maxCost = Math.max(...initRowData.flatMap(row =>
1062
- monthFields.map(field => row[field])
1063
- ))
1064
-
1065
- // 합계 행 계산
1066
- const totals = monthFields.reduce((acc, field) => {
1067
- acc[field] = initRowData.reduce((sum, r) => sum + r[field], 0)
1068
- return acc
1069
- }, { product: 'Total' })
1070
-
1071
- // 컬럼 정의
1072
- const columnDefs = [
1073
- { headerName: 'Product', field: 'product', colId: 'product', width: 280, pinned: 'left' },
1074
- ...monthFields.map(field => {
1075
- const year = field.slice(5, 9)
1076
- const month = field.slice(9, 11)
1077
- return {
1078
- headerName: \`\${year}-\${month}\`,
1079
- field: field,
1080
- width: 120,
1081
- type: ['dataBar'],
1082
- cellRendererParams: {
1083
- typeParams: {
1084
- maxValue: maxCost, // 모든 컬럼에서 동일한 스케일 적용
1085
- barColor: '#E91E8C', // 막대 색상
1086
- barOpacity: 0.5, // 막대 투명도
1087
- valuePrefix: '$', // 값 앞에 $ 표시
1088
- },
1089
- },
1090
- }
1091
- })
1092
- ]
1093
-
1094
- const gridOptions = {
1095
- animateRows: true,
1096
- tooltipShowDelay: 100,
1097
- domLayout: 'autoHeight',
1098
- pinnedBottomRowData: [totals], // 합계 행을 하단에 고정
1099
- }
1100
-
1101
- const defaultColDef = {
1102
- suppressMenu: true,
1103
- sortable: true,
1104
- resizable: true,
1105
- }
1106
-
1107
- const { OpsnowCommonDataGrid } = useCommonComponents();
1108
- const { CommonConst } = useGlobalContext()
1109
- // rowData와 status 상태를 관리
1110
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
1111
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
1112
- const gridRef = useRef(null)
1113
-
1114
- // 데이터 지연 설정을 위한 useEffect
1115
- useEffect(() => {
1116
- // 1초 후에 데이터를 설정
1117
- const timeoutId = setTimeout(() => {
1118
- setRowData(initRowData)
1119
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
1120
- }, 1000)
1121
-
1122
- // 컴포넌트 언마운트 시 타임아웃 클리어
1123
- return () => {
1124
- clearTimeout(timeoutId)
1125
- }
1126
- }, [])
1127
- `,
1128
- code: `<OpsnowCommonDataGrid
1129
- ref={gridRef}
1130
- key={status}
1131
- columnDefs={columnDefs}
1132
- defaultColDef={defaultColDef}
1133
- rowData={rowData}
1134
- status={status} // 상태를 전달
1135
- gridOptions={gridOptions}
1136
- langCd={i18n.getLocale()}
1137
- />`
1138
- },
1139
- {
1140
- title: 'How to insert into the slot to the left of the search',
1141
- description: 'Search 왼쪽에 컴포넌트를 추가하는 방법입니다.',
1142
- code_props_usage: `
1143
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
1144
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
1145
-
1146
- const defaultColDef = {
1147
- wrapText: true,
1148
- autoHeight: true,
1149
- suppressMenu: true,
1150
- unSortIcon: true,
1151
- resizable: true,
1152
- }
1153
-
1154
- // 컬럼 정의
1155
- const getColumnDefs = () => [
1156
- {
1157
- headerName: 'Period',
1158
- field: 'period',
1159
- },
1160
- {
1161
- headerName: 'Company',
1162
- field: 'company',
1163
- width: 150,
1164
- minWidth: 150,
1165
- },
1166
- {
1167
- headerName: 'Commit/h',
1168
- field: 'commit',
1169
- type: ['number', 'cost'],
1170
- cellRendererParams: {
1171
- typeParams: {
1172
- currency: 'USD',
1173
- digits: 0,
1174
- },
1175
- },
1176
- },
1177
- {
1178
- headerName: 'Transfer Amount',
1179
- field: 'amount',
1180
- type: ['number', 'cost', 'numberTooltip'],
1181
- cellRendererParams: {
1182
- typeParams: {
1183
- currency: 'USD',
1184
- iconRight: true,
1185
- },
1186
- },
1187
- },
1188
- {
1189
- headerName: 'P1->Est. Util',
1190
- field: 'util',
1191
- type: ['number', 'ratio'],
1192
- },
1193
- ]
1194
-
1195
- const gridOptions = {
1196
- animateRows: true,
1197
- suppressCellFocus: true,
1198
- suppressPaginationPanel: true,
1199
- rowSelection: { mode: 'multiRow' },
1200
- tooltipShowDelay: 100,
1201
- domLayout: 'autoHeight',
1202
- }
1203
-
1204
- const { OpsnowCommonDataGrid } = useCommonComponents();
1205
- const { CommonConst } = useGlobalContext()
1206
- // rowData와 status 상태를 관리
1207
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
1208
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
1209
- const [colDefs, setColDefs] = useState([])
1210
- const [time, setTime] = useState(null) // 달력에서 선택된 날짜 (Dayjs 객체)
1211
- const gridRef = useRef(null)
1212
-
1213
- // 행 데이터 설정
1214
- const getRowData = () => {
1215
- setStatus(CommonConst.GRID_STATUS.LOADING)
1216
- setTimeout(() => {
1217
- const data = [
1218
- { period: '2024-08', company: '111111', commit: '5', amount: 34.048487477575, util: 93 },
1219
- { period: '2024-08', company: '222222', commit: '5', amount: 56.048487477575, util: 100 },
1220
- { period: '2024-08', company: '333333', commit: '5', amount: 234.048487477575, util: 57 },
1221
- { period: '2024-07', company: '444444', commit: '5', amount: 77.048487477575, util: 99 },
1222
- { period: '2024-07', company: '555555', commit: '5', amount: 88.048487477575, util: 89 },
1223
- { period: '2024-06', company: '666666', commit: '5', amount: 12.048487477575, util: 100 },
1224
- ]
1225
- setRowData(data)
1226
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
1227
- }, 1000)
1228
- }
1229
-
1230
- // 컴포넌트 마운트 시 초기화
1231
- useEffect(() => {
1232
- setColDefs(getColumnDefs())
1233
- getRowData()
1234
- // eslint-disable-next-line react-hooks/exhaustive-deps
1235
- }, [])
1236
-
1237
- // gridStatus가 DATA_EXISTS일 때만 rowData1을 전달
1238
- const emptyComputedGridData =
1239
- status === CommonConst.GRID_STATUS.DATA_EXISTS && rowData ? rowData : []
1240
-
1241
- // 달력에서 날짜 변경 시
1242
- const onChangeMonth = (newValue) => {
1243
- const selectedMonth = newValue ? newValue.format('YYYY-MM') : ''
1244
- let filteredData = rowData
1245
-
1246
- if (selectedMonth) {
1247
- filteredData = rowData.filter(row => row.period === selectedMonth)
1248
- }
1249
-
1250
- if (gridRef.current) {
1251
- // 필터링된 데이터 설정
1252
- gridRef.current.setRowData(filteredData)
1253
- // 약간의 지연 후에 컬럼 사이즈 맞추기
1254
- setTimeout(() => {
1255
- gridRef.current.sizeColumnsToFit()
1256
- }, 0)
1257
- }
1258
- setTime(newValue)
1259
- }
1260
- `,
1261
- code: `<OpsnowCommonDataGrid
1262
- ref={gridRef}
1263
- rowData={emptyComputedGridData}
1264
- columnDefs={colDefs}
1265
- defaultColDef={defaultColDef}
1266
- status={status}
1267
- gridOptions={gridOptions}
1268
- useOpsnowUs={true}
1269
- usedSearch={true}
1270
- langCd={i18n.getLocale()}
1271
- // 달력 컴포넌트를 searchAddon에 전달
1272
- searchAddon={
1273
- <OpsnowCommonDatePicker
1274
- clearable={true}
1275
- placeholderText="날짜를 선택해주세요"
1276
- type="date"
1277
- value={time}
1278
- onChange={onChangeMonth}
1279
- />
1280
- }
1281
- />`
1282
- },
1283
- {
1284
- title: 'Tree data drag',
1285
- description: 'Tree data drag 예제입니다.',
1286
- code_props_usage: `
1287
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
1288
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
1289
- import AddButtonRenderer from './renderer/AddButtonRenderer.jsx'
1290
-
1291
- const { OpsnowCommonDataGrid } = useCommonComponents();
1292
- const { CommonConst } = useGlobalContext()
1293
- const [treeRowData, setTreeRowData] = useState([])
1294
- const [treeColumnDefs, setTreeColumnDefs] = useState([])
1295
- const [gridStatus, setGridStatus] = useState(CommonConst.GRID_STATUS.LOADING)
1296
- const [draggedNode, setDraggedNode] = useState(null) // onRowDragEnter에서 저장할 노드
1297
-
1298
- // ▶ 변경: tempGroupCount를 useState 대신 useRef로 관리
1299
- // useState: 상태가 변하면 UI를 다시 그려야 하는 데이터를 관리 (→ 변경 시 컴포넌트 재렌더링).
1300
- // useRef: 렌더링과 직접 관련 없는 값을 관리하거나, DOM 요소를 직접 참조할 때 사용 (→ 값 변경해도 재렌더링 없음).
1301
- const tempGroupCountRef = useRef(1)
1302
-
1303
- // OpsnowCommonDataGrid ref
1304
- const treeDataGridRef = useRef(null)
1305
-
1306
- // 기본 컬럼 설정
1307
- const defaultColDef = {
1308
- wrapText: true,
1309
- autoHeight: true,
1310
- suppressMenu: true,
1311
- unSortIcon: true,
1312
- sortable: false,
1313
- }
1314
-
1315
- // onAddRowClick: pinned bottom row에 있는 Add Group 버튼 클릭 시
1316
- const onAddRowClick = useCallback(() => {
1317
- // 현재 count를 ref에서 읽어옴
1318
- const currentCount = tempGroupCountRef.current
1319
-
1320
- const newRow = [
1321
- {
1322
- id: Date.now(),
1323
- filePath: ['FinOps Practitioner', \`New Group\${currentCount}\`],
1324
- type: 'group',
1325
- },
1326
- ]
1327
- if (treeDataGridRef.current) {
1328
- // OpsnowCommonDataGrid의 applyTransaction API
1329
- treeDataGridRef.current.applyTransaction({ add: newRow })
1330
- }
1331
-
1332
- // useRef로 관리하므로, React 재렌더링 없이 값만 업데이트
1333
- tempGroupCountRef.current = currentCount + 1
1334
- }, [])
1335
-
1336
- // sizeFormatter: 'MB' 접미사 추가
1337
- const sizeFormatter = (params) => {
1338
- return params.value ? \`\${params.value} MB\` : ''
1339
- }
1340
-
1341
- // Vue의 onRowDragEnter => React로 변환
1342
- const onRowDragEnter = useCallback((event) => {
1343
- // event.node에 드래그한 노드 정보가 담겨 있음
1344
- setDraggedNode(event.node)
1345
- }, [])
1346
-
1347
- // myCustomDropTargetFunc: 특정 조건(type='group')만 drop 가능
1348
- const myCustomDropTargetFunc = useCallback(
1349
- (overNode) => {
1350
- if (!overNode) return null
1351
-
1352
- let newPotentialParent =
1353
- overNode.data && overNode.data.type === 'group'
1354
- ? overNode
1355
- : overNode.parent
1356
-
1357
- // draggedNode가 group이면서 자식이 있으면, 이동 불가 → 부모로 되돌림
1358
- if (
1359
- draggedNode &&
1360
- draggedNode.data &&
1361
- draggedNode.data.type === 'group' &&
1362
- draggedNode.childrenAfterGroup &&
1363
- draggedNode.childrenAfterGroup.length > 0
1364
- ) {
1365
- newPotentialParent = draggedNode.parent || null
1366
- }
1367
- return newPotentialParent
1368
- },
1369
- [draggedNode],
1370
- )
1371
-
1372
- // gridOptions
1373
- const treeGridOptions = {
1374
- animateRows: true,
1375
- treeData: true,
1376
- suppressCellFocus: true,
1377
- autoGroupColumnDef: {
1378
- // 이거 설정 안해줘도 :useTreeDataDragDrop="true" 넘기면 자동 세팅
1379
- //rowDrag: true,
1380
- headerName: 'Files',
1381
- minWidth: 300,
1382
- unSortIcon: false,
1383
- sortable: false,
1384
- cellRendererParams: {
1385
- suppressCount: true,
1386
- },
1387
- },
1388
- groupDefaultExpanded: -1,
1389
- // row data에서 array로 들어오는 데이터를 path로 설정
1390
- getDataPath: (data) => data.filePath,
1391
- // dataPath가 data 에서도 키가 dataPath가 아닌이상
1392
- // dataPath 를 어디로 지정했는지 common-grid에 알려주어야함. (common-grid에서는 알수가없음)
1393
- // 즉, 키가 dataPath가 아닌 이상 필수
1394
- // ex) dataPath: ['FinOps Practitioner', 'Group 01', 'Sub Group 01-01'], -> setDataPath 필요없음
1395
- // filePath: ['FinOps Practitioner', 'Group 01', 'Sub Group 01-01'], -> setDataPath 해줘야함
1396
- setDataPath: (data, newPath) => {
1397
- data.filePath = newPath
1398
- },
1399
- pinnedBottomRowData: [{ isAddButtonRow: true }],
1400
- // onRowDragEnter 이벤트 등록
1401
- onRowDragEnter: onRowDragEnter,
1402
- }
1403
-
1404
- // 컬럼 정의
1405
- const getTreeColumnDefs = useCallback(() => {
1406
- return [
1407
- {
1408
- field: 'dateModified',
1409
- suppressHeaderMenuButton: true,
1410
- // pinned row인 경우 전체 컬럼 수만큼 병합
1411
- colSpan: (params) => {
1412
- if (params.node.rowPinned) {
1413
- // API가 없거나 이미 파괴된 경우엔 안전하게 1 반환
1414
- if (!params.api || (params.api.isDestroyed && params.api.isDestroyed())) {
1415
- return 1
1416
- }
1417
- const allDisplayedColumns = params.api.getAllDisplayedColumns()
1418
- return allDisplayedColumns && allDisplayedColumns.length
1419
- ? allDisplayedColumns.length
1420
- : 1
1421
- }
1422
- return 1
1423
- },
1424
- // pinned row인 경우 AddButtonRenderer 사용
1425
- cellRendererSelector: (params) => {
1426
- if (params.node.rowPinned) {
1427
- return {
1428
- component: AddButtonRenderer,
1429
- params: {
1430
- onClickAddGroup: () => {
1431
- onAddRowClick()
1432
- },
1433
- },
1434
- }
1435
- }
1436
- return undefined
1437
- },
1438
- },
1439
- {
1440
- field: 'size',
1441
- valueFormatter: sizeFormatter,
1442
- suppressHeaderMenuButton: true,
1443
- },
1444
- ]
1445
- }, [onAddRowClick])
1446
-
1447
- // 행 데이터 로딩
1448
- const getTreeRowData = useCallback(() => {
1449
- setGridStatus(CommonConst.GRID_STATUS.LOADING)
1450
- setTimeout(() => {
1451
- // ** 주의 **
1452
- // path 구성시 상위 그룹을 반드시 생성후 그 아래 자식 그룹 생성해주세요
1453
- // ex) 1단계 : filePath: ['FinOps Practitioner'] 생성
1454
- // 2단계 : filePath: ['FinOps Practitioner', 'Group 01'] 생성
1455
- // 1단계 없이 바로 2단계로 할 경우 이동이 올바르게 실행되지 않음.
1456
- const rowData = [
1457
- { id: 1, filePath: ['FinOps Practitioner'], type: 'parent' },
1458
- { id: 2, filePath: ['FinOps Practitioner', 'Group 01'], type: 'group' },
1459
- {
1460
- id: 3,
1461
- filePath: ['FinOps Practitioner', 'Group 01', 'Sub Group 01-01'],
1462
- type: 'sub-group',
1463
- dateModified: 'May 21 2017 01:50:00 PM',
1464
- size: 14.7,
1465
- },
1466
- ]
1467
- setTreeRowData(rowData)
1468
- setGridStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
1469
- }, 1000)
1470
- }, [])
1471
-
1472
- // 컴포넌트 마운트 시 컬럼/데이터 초기화
1473
- useEffect(() => {
1474
- setTreeColumnDefs(getTreeColumnDefs())
1475
- getTreeRowData()
1476
- }, [getTreeColumnDefs, getTreeRowData])
1477
- `,
1478
- code: `<OpsnowCommonDataGrid
1479
- ref={treeDataGridRef}
1480
- rowData={treeRowData}
1481
- columnDefs={treeColumnDefs}
1482
- defaultColDef={defaultColDef}
1483
- status={gridStatus}
1484
- gridOptions={treeGridOptions}
1485
- pagination={true}
1486
- useOpsnowUs={true}
1487
- usedSearch={true}
1488
- usedMenuItem={true}
1489
- // 트리 데이터 드래그 기능
1490
- useTreeDataDragDrop={true}
1491
- // 특정 drop target 로직
1492
- getDropTargetNode={myCustomDropTargetFunc}
1493
- langCd={i18n.getLocale()}
1494
- />`
1495
- },
1496
- {
1497
- title: 'Grid row drag (transferring rows between two grids)',
1498
- description: 'Grid row drag 예제입니다.',
1499
- code_props_usage: `
1500
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
1501
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
1502
-
1503
- const { OpsnowCommonDataGrid } = useCommonComponents()
1504
- const { CommonConst } = useGlobalContext()
1505
- // 상태 정의
1506
- const [rowData1, setRowData1] = useState([])
1507
- const [rowData2, setRowData2] = useState([])
1508
- const [colDefs1, setColDefs1] = useState([])
1509
- const [colDefs2, setColDefs2] = useState([])
1510
- const defaultColDef = {
1511
- wrapText: true,
1512
- autoHeight: true,
1513
- suppressMenu: true,
1514
- unSortIcon: true,
1515
- resizable: true,
1516
- }
1517
- const gridOptions1 = {
1518
- animateRows: true,
1519
- suppressCellFocus: true,
1520
- suppressPaginationPanel: true,
1521
- rowSelection: { mode: 'multiRow', checkboxes: true, enableClickSelection: true, headerCheckbox: true },
1522
- tooltipShowDelay: 100,
1523
- domLayout: 'autoHeight',
1524
- rowDragMultiRow: true,
1525
- rowDragManaged: true,
1526
- suppressMoveWhenRowDragging: true,
1527
- }
1528
- const gridOptions2 = {
1529
- animateRows: true,
1530
- suppressCellFocus: true,
1531
- suppressPaginationPanel: true,
1532
- rowSelection: { mode: 'multiRow', checkboxes: true, enableClickSelection: true, headerCheckbox: true },
1533
- tooltipShowDelay: 100,
1534
- domLayout: 'autoHeight',
1535
- rowDragMultiRow: true,
1536
- rowDragManaged: true,
1537
- suppressMoveWhenRowDragging: true,
1538
- }
1539
- const [gridStatus1, setGridStatus1] = useState(CommonConst.GRID_STATUS.LOADING)
1540
- const [gridStatus2, setGridStatus2] = useState(CommonConst.GRID_STATUS.LOADING)
1541
- const [leftGridReady, setLeftGridReady] = useState(false)
1542
- const [rightGridReady, setRightGridReady] = useState(false)
1543
-
1544
- // OpsnowCommonDataGrid ref
1545
- const leftGridRef = useRef(null)
1546
- const rightGridRef = useRef(null)
1547
-
1548
-
1549
- // 드래그 드랍 관련 함수
1550
- const addGridDropZone = useCallback(() => {
1551
- if (rightGridRef.current && leftGridRef.current) {
1552
- createDropZone(rightGridRef.current, leftGridRef.current)
1553
- createDropZone(leftGridRef.current, rightGridRef.current)
1554
- }
1555
- }, [])
1556
-
1557
- const createDropZone = (sourceGrid, targetGrid) => {
1558
- const dropZoneParams = sourceGrid.getRowDropZoneParams({
1559
- onDragStop: (params) => {
1560
- const nodes = params.nodes
1561
- targetGrid.applyTransaction({
1562
- remove: nodes.map(node => node.data),
1563
- })
1564
- },
1565
- })
1566
- targetGrid.addRowDropZone(dropZoneParams)
1567
- }
1568
-
1569
- // 데이터 그리드 준비 콜백
1570
- useEffect(() => {
1571
- if (leftGridReady && rightGridReady) {
1572
- addGridDropZone()
1573
- }
1574
- }, [leftGridReady, rightGridReady, addGridDropZone])
1575
-
1576
- const onGridReady = useCallback((gridPosition) => {
1577
- if (gridPosition === 'left') {
1578
- setLeftGridReady(true)
1579
- } else if (gridPosition === 'right') {
1580
- setRightGridReady(true)
1581
- }
1582
- }, [])
1583
-
1584
- // 컬럼 정의 함수
1585
- const getColumnDefs1 = () => {
1586
- return [
1587
- {
1588
- rowDrag: true,
1589
- maxWidth: 50,
1590
- minWidth: 50,
1591
- pinned: 'left',
1592
- sortable: false,
1593
- suppressHeaderMenuButton: true,
1594
- suppressHeaderFilterButton: true,
1595
- rowDragText: (params, dragItemCount) => {
1596
- if (dragItemCount > 1) {
1597
- return dragItemCount + ' Company'
1598
- }
1599
- return params.rowNode.data.company
1600
- },
1601
- },
1602
- {
1603
- headerName: 'Company',
1604
- field: 'company',
1605
- pinned: 'left',
1606
- width: 150,
1607
- minWidth: 150,
1608
- suppressHeaderMenuButton: true,
1609
- suppressHeaderFilterButton: true,
1610
- },
1611
- {
1612
- headerName: 'Commit/h',
1613
- field: 'commit',
1614
- type: ['number', 'cost'],
1615
- cellRendererParams: {
1616
- typeParams: {
1617
- currency: 'USD',
1618
- digits: 0,
1619
- },
1620
- },
1621
- },
1622
- {
1623
- headerName: 'Transfer Amount',
1624
- field: 'amount',
1625
- type: ['number', 'cost', 'numberTooltip'],
1626
- cellRendererParams: {
1627
- typeParams: {
1628
- currency: 'USD',
1629
- iconRight: true,
1630
- },
1631
- },
1632
- },
1633
- {
1634
- headerName: 'P1->Est. Util',
1635
- field: 'util',
1636
- type: ['number', 'ratio'],
1637
- },
1638
- ]
1639
- }
1640
-
1641
- const getColumnDefs2 = () => {
1642
- return [
1643
- {
1644
- rowDrag: true,
1645
- maxWidth: 50,
1646
- minWidth: 50,
1647
- pinned: 'left',
1648
- sortable: false,
1649
- suppressHeaderMenuButton: true,
1650
- suppressHeaderFilterButton: true,
1651
- rowDragText: (params, dragItemCount) => {
1652
- if (dragItemCount > 1) {
1653
- return dragItemCount + ' Company'
1654
- }
1655
- return params.rowNode.data.company
1656
- },
1657
- },
1658
- {
1659
- headerName: 'Company',
1660
- field: 'company',
1661
- pinned: 'left',
1662
- width: 150,
1663
- minWidth: 150,
1664
- suppressHeaderMenuButton: true,
1665
- suppressHeaderFilterButton: true,
1666
- },
1667
- {
1668
- headerName: 'Commit/h',
1669
- field: 'commit',
1670
- type: ['number', 'cost'],
1671
- cellRendererParams: {
1672
- typeParams: {
1673
- currency: 'USD',
1674
- digits: 0,
1675
- },
1676
- },
1677
- },
1678
- {
1679
- headerName: 'Transfer Amount',
1680
- field: 'amount',
1681
- type: ['number', 'cost', 'numberTooltip'],
1682
- cellRendererParams: {
1683
- typeParams: {
1684
- currency: 'USD',
1685
- iconRight: true,
1686
- },
1687
- },
1688
- },
1689
- {
1690
- headerName: 'P1->Est. Cov',
1691
- field: 'util',
1692
- type: ['number', 'ratio'],
1693
- },
1694
- ]
1695
- }
1696
-
1697
- // 행 데이터 함수 (1, 2번 데이터 그리드 각각)
1698
- const getRowData1 = () => {
1699
- setGridStatus1(CommonConst.GRID_STATUS.LOADING)
1700
- setTimeout(() => {
1701
- setRowData1([
1702
- { company: '111111', commit: '5', amount: 34.048487477575, util: 93 },
1703
- { company: '222222', commit: '5', amount: 56.048487477575, util: 100 }
1704
- ])
1705
- setGridStatus1(CommonConst.GRID_STATUS.DATA_EXISTS)
1706
- }, 1000)
1707
- }
1708
-
1709
- const getRowData2 = () => {
1710
- setGridStatus2(CommonConst.GRID_STATUS.LOADING)
1711
- setTimeout(() => {
1712
- setRowData2([
1713
- { company: '123123', commit: '5', amount: 34.048487477575, util: 93 },
1714
- { company: '234234', commit: '5', amount: 56.048487477575, util: 100 }
1715
- ])
1716
- setGridStatus2(CommonConst.GRID_STATUS.DATA_EXISTS)
1717
- }, 1000)
1718
- }
1719
-
1720
- // 컴포넌트 마운트 시 초기화
1721
- useEffect(() => {
1722
- setColDefs1(getColumnDefs1())
1723
- setColDefs2(getColumnDefs2())
1724
- getRowData1()
1725
- getRowData2()
1726
- // eslint-disable-next-line react-hooks/exhaustive-deps
1727
- }, [])
1728
- `,
1729
- code: `<Box style={{ flex: 1 }}>
1730
- <h3>left grid</h3>
1731
- <OpsnowCommonDataGrid
1732
- ref={leftGridRef}
1733
- rowData={rowData1}
1734
- columnDefs={colDefs1}
1735
- defaultColDef={defaultColDef}
1736
- status={gridStatus1}
1737
- gridOptions={gridOptions1}
1738
- usedSearch={true}
1739
- showSelectedRowCount={true}
1740
- langCd={i18n.getLocale()}
1741
- onGridReady={() => onGridReady('left')}
1742
- />
1743
- </Box>
1744
- <Box style={{ flex: 1 }}>
1745
- <h3>right grid</h3>
1746
- <OpsnowCommonDataGrid
1747
- ref={rightGridRef}
1748
- rowData={rowData2}
1749
- columnDefs={colDefs2}
1750
- defaultColDef={defaultColDef}
1751
- status={gridStatus2}
1752
- gridOptions={gridOptions2}
1753
- usedSearch={true}
1754
- showSelectedRowCount={true}
1755
- langCd={i18n.getLocale()}
1756
- onGridReady={() => onGridReady('right')}
1757
- />
1758
- </Box>
1759
- </Box>`
1760
- },
1761
- {
1762
- title: 'Server side row model',
1763
- description: 'Server side row model 예제입니다.',
1764
- code_props_usage: `
1765
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
1766
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
1767
- import { assetAlarmServiceGetServerSideAlarmHistory } from './data/serverSideAlarmService'
1768
- import CloudServiceCellRenderer from './renderer/CloudServiceCellRenderer'
1769
- import DetailCellRenderer from './renderer/DetailCellRenderer'
1770
-
1771
- const { OpsnowCommonDataGrid } = useCommonComponents()
1772
- const { CommonConst } = useGlobalContext()
1773
- const [gridStatus, setGridStatus] = useState(CommonConst.GRID_STATUS.LOADING)
1774
- const [serverSideDatasource, setServerSideDatasource] = useState(null)
1775
-
1776
- // 서버 전체 데이터(필터 생성용) - 필요시 로컬 state로 저장
1777
- const [filterOptions, setFilterOptions] = useState({})
1778
- // 페이지 사이즈
1779
- const [paginationPageSize] = useState(10)
1780
- const [totalRowCount, setTotalRowCount] = useState(0)
1781
-
1782
- const severSideCheckBoxGridRef = useRef(null)
1783
-
1784
- // 검색어 변경 확인을 위한 ref
1785
- const lastSearchQueryRef = useRef('')
1786
-
1787
- // 공통 컬럼 정의
1788
- const defaultColDef = {
1789
- wrapText: true,
1790
- autoHeight: true,
1791
- suppressMenu: true,
1792
- unSortIcon: true,
1793
- sortable: false,
1794
- }
1795
-
1796
- // (1) columnDefs를 useMemo로 감싸기
1797
- const checkBoxColumnDefs = useMemo(() => {
1798
- return [
1799
- {
1800
- field: 'no',
1801
- headerName: 'No.',
1802
- cellStyle: { justifyContent: 'center', alignItems: 'center' },
1803
- width: 110,
1804
- maxWidth: 110,
1805
- sortable: true,
1806
- },
1807
- {
1808
- field: 'cloudService',
1809
- headerName: '클라우드 서비스',
1810
- cellStyle: { justifyContent: 'left', alignItems: 'center' },
1811
- width: 200,
1812
- maxWidth: 200,
1813
- sortable: true,
1814
- cellRenderer: CloudServiceCellRenderer,
1815
- headerComponentParams: {
1816
- filter: true,
1817
- filterParams: {
1818
- values: (params) => {
1819
- if (params && typeof params.success === 'function') {
1820
- params.success(filterOptions.cloudService || [])
1821
- }
1822
- },
1823
- },
1824
- },
1825
- },
1826
- {
1827
- field: 'account',
1828
- headerName: '계정',
1829
- resizable: true,
1830
- cellStyle: { justifyContent: 'left', alignItems: 'center' },
1831
- width: 230,
1832
- minWidth: 230,
1833
- maxWidth: 260,
1834
- hide: true,
1835
- },
1836
- {
1837
- field: 'title',
1838
- headerName: '알람 제목',
1839
- resizable: true,
1840
- cellStyle: { justifyContent: 'left', alignItems: 'center' },
1841
- hide: true,
1842
- maxWidth: 300,
1843
- },
1844
- {
1845
- field: 'message',
1846
- headerName: '알람 메시지',
1847
- sortable: true,
1848
- resizable: true,
1849
- cellStyle: { justifyContent: 'left', alignItems: 'center' },
1850
- },
1851
- {
1852
- field: 'date',
1853
- headerName: '알람 일시',
1854
- sortable: true,
1855
- cellStyle: { justifyContent: 'left', alignItems: 'center' },
1856
- },
1857
- {
1858
- field: 'detail',
1859
- headerName: '상세',
1860
- width: 110,
1861
- maxWidth: 110,
1862
- cellRenderer: DetailCellRenderer,
1863
- },
1864
- ]
1865
- }, [filterOptions])
1866
-
1867
- const gridOptions = useMemo(() => ({
1868
- animateRows: true,
1869
- rowSelection: { mode: 'multiRow', enableSelectionWithoutKeys: true, headerCheckbox: true },
1870
- tooltipShowDelay: 100,
1871
- domLayout: 'autoHeight',
1872
- alwaysMultiSort: true,
1873
- serverSideSortAllLevels: true,
1874
- getRowId: (params) => params.data.no,
1875
- }), [])
1876
-
1877
- // (2) serverSideDatasource 생성 함수
1878
- const setupServerSideDatasource = useCallback((searchQuery = '') => {
1879
- setGridStatus(CommonConst.GRID_STATUS.LOADING)
1880
- return {
1881
- getRows: (params) => {
1882
- console.log('getRows 호출', params, searchQuery)
1883
-
1884
- assetAlarmServiceGetServerSideAlarmHistory(params, searchQuery)
1885
- .then((data) => {
1886
- // data: { success, allData, rows, lastRow }
1887
-
1888
- // OpsnowCommonDataGrid의 setServerSideFilterList 사용
1889
- if (severSideGridRef.current) {
1890
- const newFilterOpts = severSideGridRef.current.setServerSideFilterList(data.allData)
1891
-
1892
- // (3) 이전 filterOptions와 달라야만 업데이트
1893
- setFilterOptions(prev => {
1894
- const prevStr = JSON.stringify(prev)
1895
- const newStr = JSON.stringify(newFilterOpts)
1896
- if (prevStr === newStr) {
1897
- return prev
1898
- }
1899
- return newFilterOpts
1900
- })
1901
- }
1902
-
1903
- setTotalRowCount(data.lastRow)
1904
- // 데이터 그리드에 데이터 전달
1905
- params.success({
1906
- rowData: data.rows,
1907
- rowCount: data.lastRow,
1908
- })
1909
- setGridStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
1910
- })
1911
- .catch((error) => {
1912
- console.error('Error while loading data:', error)
1913
- setGridStatus(CommonConst.GRID_STATUS.ERROR)
1914
- params.fail()
1915
- })
1916
- },
1917
- }
1918
- }, [])
1919
-
1920
- // (4) 컴포넌트 마운트 시 1회
1921
- useEffect(() => {
1922
- const ds = setupServerSideDatasource('')
1923
- setServerSideDatasource(ds)
1924
- }, [setupServerSideDatasource])
1925
-
1926
- const handleSearchQueryChange = (searchQuery) => {
1927
- if (lastSearchQueryRef.current === searchQuery) return
1928
- lastSearchQueryRef.current = searchQuery
1929
- const newDs = setupServerSideDatasource(searchQuery)
1930
- severSideGridRef.current?.setServerSideDatasource(newDs)
1931
- severSideCheckBoxGridRef.current?.setServerSideDatasource(newDs)
1932
- }
1933
-
1934
- // 페이지 사이즈 변경 (Vue 예제: @changePageSize="getChangePageSize")
1935
- const getChangePageSize = (num, size) => {
1936
- console.log('Page changed:', num, size)
1937
- }
1938
-
1939
- // selectionChanged
1940
- const selectionChanged = (selectedNodes) => {
1941
- console.log('Selected nodes:', selectedNodes)
1942
- }
1943
-
1944
- // resetCheckBox
1945
- const resetCheckBox = () => {
1946
- severSideCheckBoxGridRef.current?.clearSelectionState()
1947
- }
1948
- // loadCheckBox
1949
- const loadCheckBox = () => {
1950
- severSideCheckBoxGridRef.current?.loadSelectionState()
1951
- }
1952
- // setCheckBox
1953
- const setCheckBox = () => {
1954
- severSideCheckBoxGridRef.current?.setSelectionState({
1955
- selectAll: false,
1956
- toggledNodes: ['50', '48', '35'],
1957
- })
1958
- }
1959
-
1960
- // 아직 datasource가 준비 안 되었으면 로딩 표시
1961
- if (!serverSideDatasource) {
1962
- return <div>Loading datasource...</div>
1963
- }
1964
- `,
1965
- code: `<OpsnowCommonDataGrid
1966
- ref={severSideCheckBoxGridRef}
1967
- usedSearch={true}
1968
- columnDefs={checkBoxColumnDefs}
1969
- defaultColDef={defaultColDef}
1970
- status={gridStatus}
1971
- gridOptions={gridOptions}
1972
- useOpsnowUs={true}
1973
- rowModelType="serverSide"
1974
- serverSideDatasource={serverSideDatasource}
1975
- pagination={true}
1976
- cacheBlockSize={10}
1977
- paginationPageSize={paginationPageSize}
1978
- serverSideTotalPageSize={totalRowCount}
1979
- langCd={i18n.getLocale()}
1980
- onSearchQueryChanged={handleSearchQueryChange}
1981
- onSelectionChanged={selectionChanged}
1982
- >
1983
- <button onClick={resetCheckBox} style={{ marginRight: '1rem' }}>
1984
- reset check box
1985
- </button>
1986
- <button onClick={loadCheckBox} style={{ marginRight: '1rem' }}>
1987
- load check box
1988
- </button>
1989
- <button onClick={setCheckBox}>set check box</button>
1990
- </OpsnowCommonDataGrid>`
1991
- },
1992
- {
1993
- title: 'Column Group - Basic',
1994
- description: 'children 속성을 사용한 기본 컬럼 그룹 예제입니다.',
1995
- code_props_usage: `
1996
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
1997
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
1998
-
1999
- // 컬럼 그룹 정의 - children을 사용한 예제
2000
- const columnDefs = [
2001
- {
2002
- groupId: 'vehicleGroup',
2003
- headerName: 'Vehicle Info',
2004
- children: [
2005
- { headerName: 'Make', field: 'make' },
2006
- { headerName: 'Model', field: 'model' },
2007
- ],
2008
- },
2009
- {
2010
- groupId: 'financialGroup',
2011
- headerName: 'Financial Info',
2012
- children: [
2013
- {
2014
- headerName: 'Price',
2015
- field: 'price',
2016
- valueFormatter: params => params.value ? \`$\${params.value.toLocaleString()}\` : ''
2017
- },
2018
- {
2019
- headerName: 'Tax',
2020
- field: 'tax',
2021
- valueFormatter: params => params.value ? \`$\${params.value.toLocaleString()}\` : ''
2022
- },
2023
- ],
2024
- },
2025
- {
2026
- groupId: 'salesGroup',
2027
- headerName: 'Sales Info',
2028
- children: [
2029
- { headerName: 'Year', field: 'year' },
2030
- { headerName: 'Country', field: 'country' },
2031
- ],
2032
- },
2033
- ]
2034
-
2035
- // 초기 행 데이터
2036
- const initialRowData = [
2037
- { make: 'Toyota', model: 'Celica', price: 35000, tax: 3500, year: 2020, country: 'Japan' },
2038
- { make: 'Ford', model: 'Mondeo', price: 32000, tax: 3200, year: 2019, country: 'USA' },
2039
- { make: 'Porsche', model: 'Boxter', price: 72000, tax: 7200, year: 2021, country: 'Germany' },
2040
- { make: 'BMW', model: 'M3', price: 65000, tax: 6500, year: 2020, country: 'Germany' },
2041
- { make: 'Honda', model: 'Civic', price: 28000, tax: 2800, year: 2019, country: 'Japan' },
2042
- { make: 'Tesla', model: 'Model S', price: 95000, tax: 9500, year: 2022, country: 'USA' },
2043
- { make: 'Audi', model: 'A4', price: 45000, tax: 4500, year: 2020, country: 'Germany' },
2044
- { make: 'Mercedes', model: 'C-Class', price: 55000, tax: 5500, year: 2021, country: 'Germany' },
2045
- { make: 'Nissan', model: 'Altima', price: 30000, tax: 3000, year: 2019, country: 'Japan' },
2046
- { make: 'Chevrolet', model: 'Malibu', price: 33000, tax: 3300, year: 2020, country: 'USA' },
2047
- ]
2048
-
2049
- const gridOptions = {
2050
- animateRows: true,
2051
- rowSelection: { mode: 'singleRow', checkboxes: false, enableClickSelection: true },
2052
- tooltipShowDelay: 100,
2053
- domLayout: 'autoHeight',
2054
- suppressCellFocus: true,
2055
- }
2056
-
2057
- const { OpsnowCommonDataGrid } = useCommonComponents();
2058
- const { CommonConst } = useGlobalContext()
2059
- // rowData와 status 상태를 관리
2060
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
2061
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
2062
-
2063
- // 데이터 지연 설정을 위한 useEffect
2064
- useEffect(() => {
2065
- // 1초 후에 데이터를 설정
2066
- const timeoutId = setTimeout(() => {
2067
- setRowData(initialRowData)
2068
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
2069
- }, 1000)
2070
-
2071
- // 컴포넌트 언마운트 시 타임아웃 클리어
2072
- return () => {
2073
- clearTimeout(timeoutId)
2074
- }
2075
- }, [])
2076
- `,
2077
- code: `<OpsnowCommonDataGrid
2078
- columnDefs={columnDefs}
2079
- rowData={rowData}
2080
- status={status}
2081
- gridOptions={gridOptions}
2082
- usedSearch={true}
2083
- pagination={true}
2084
- paginationPageSize={5}
2085
- pageSizeList={[
2086
- { label: '5', value: 5 },
2087
- { label: '10', value: 10 },
2088
- { label: '20', value: 20 },
2089
- ]}
2090
- langCd={i18n.getLocale()}
2091
- />`
2092
- },
2093
- {
2094
- title: 'Column Group - Nested',
2095
- description: '다층 구조의 중첩된 컬럼 그룹 예제입니다.',
2096
- code_props_usage: `
2097
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
2098
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
2099
-
2100
- // 중첩된 컬럼 그룹 정의
2101
- const nestedColumnDefs = [
2102
- {
2103
- groupId: 'vehicleMainGroup',
2104
- headerName: 'Vehicle',
2105
- children: [
2106
- {
2107
- groupId: 'vehicleBasicGroup',
2108
- headerName: 'Basic Info',
2109
- children: [
2110
- { headerName: 'Make', field: 'make' },
2111
- { headerName: 'Model', field: 'model' },
2112
- ],
2113
- },
2114
- {
2115
- groupId: 'vehicleDetailsGroup',
2116
- headerName: 'Details',
2117
- children: [
2118
- { headerName: 'Year', field: 'year' },
2119
- { headerName: 'Country', field: 'country' },
2120
- ],
2121
- },
2122
- ],
2123
- },
2124
- {
2125
- groupId: 'financialMainGroup',
2126
- headerName: 'Financial',
2127
- children: [
2128
- {
2129
- headerName: 'Price',
2130
- field: 'price',
2131
- valueFormatter: params => params.value ? \`$\${params.value.toLocaleString()}\` : ''
2132
- },
2133
- {
2134
- headerName: 'Tax',
2135
- field: 'tax',
2136
- valueFormatter: params => params.value ? \`$\${params.value.toLocaleString()}\` : ''
2137
- },
2138
- ],
2139
- },
2140
- ]
2141
-
2142
- // 초기 행 데이터
2143
- const initialRowData = [
2144
- { make: 'Toyota', model: 'Celica', price: 35000, tax: 3500, year: 2020, country: 'Japan' },
2145
- { make: 'Ford', model: 'Mondeo', price: 32000, tax: 3200, year: 2019, country: 'USA' },
2146
- { make: 'Porsche', model: 'Boxter', price: 72000, tax: 7200, year: 2021, country: 'Germany' },
2147
- { make: 'BMW', model: 'M3', price: 65000, tax: 6500, year: 2020, country: 'Germany' },
2148
- { make: 'Honda', model: 'Civic', price: 28000, tax: 2800, year: 2019, country: 'Japan' },
2149
- { make: 'Tesla', model: 'Model S', price: 95000, tax: 9500, year: 2022, country: 'USA' },
2150
- { make: 'Audi', model: 'A4', price: 45000, tax: 4500, year: 2020, country: 'Germany' },
2151
- { make: 'Mercedes', model: 'C-Class', price: 55000, tax: 5500, year: 2021, country: 'Germany' },
2152
- { make: 'Nissan', model: 'Altima', price: 30000, tax: 3000, year: 2019, country: 'Japan' },
2153
- { make: 'Chevrolet', model: 'Malibu', price: 33000, tax: 3300, year: 2020, country: 'USA' },
2154
- ]
2155
-
2156
- const gridOptions = {
2157
- animateRows: true,
2158
- rowSelection: { mode: 'singleRow', checkboxes: false, enableClickSelection: true },
2159
- tooltipShowDelay: 100,
2160
- domLayout: 'autoHeight',
2161
- suppressCellFocus: true,
2162
- }
2163
-
2164
- const { OpsnowCommonDataGrid } = useCommonComponents();
2165
- const { CommonConst } = useGlobalContext()
2166
- // rowData와 status 상태를 관리
2167
- const [rowData, setRowData] = useState([]) // 초기에는 빈 배열로 설정
2168
- const [status, setStatus] = useState(CommonConst.GRID_STATUS.LOADING) // 초기에는 LOADING 상태
2169
-
2170
- // 데이터 지연 설정을 위한 useEffect
2171
- useEffect(() => {
2172
- // 1초 후에 데이터를 설정
2173
- const timeoutId = setTimeout(() => {
2174
- setRowData(initialRowData)
2175
- setStatus(CommonConst.GRID_STATUS.DATA_EXISTS)
2176
- }, 1000)
2177
-
2178
- // 컴포넌트 언마운트 시 타임아웃 클리어
2179
- return () => {
2180
- clearTimeout(timeoutId)
2181
- }
2182
- }, [])
2183
- `,
2184
- code: `<OpsnowCommonDataGrid
2185
- key={status}
2186
- columnDefs={nestedColumnDefs}
2187
- rowData={rowData}
2188
- status={status}
2189
- gridOptions={gridOptions}
2190
- usedSearch={true}
2191
- langCd={i18n.getLocale()}
2192
- />`
2193
- },
2194
- {
2195
- title: 'Error Status',
2196
- description: 'Error Status 예제입니다.',
2197
- code_props_usage: `
2198
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
2199
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
2200
-
2201
- // 컬럼 정의
2202
- const columnDefs = [
2203
- { headerName: 'Make', field: 'make' },
2204
- { headerName: 'Model', field: 'model' },
2205
- { headerName: 'Price', field: 'price' },
2206
- ]
2207
-
2208
- const gridOptions = {
2209
- animateRows: true,
2210
- rowSelection: { mode: 'singleRow', checkboxes: false, enableClickSelection: true },
2211
- tooltipShowDelay: 100,
2212
- domLayout: 'autoHeight',
2213
- suppressCellFocus: true,
2214
- }
2215
-
2216
- const { OpsnowCommonDataGrid } = useCommonComponents();
2217
- const { CommonConst } = useGlobalContext()
2218
- // errorStatus 상태를 관리
2219
- const [errorStatus, setErrorStatus] = useState(CommonConst.GRID_STATUS.LOADING)
2220
-
2221
- // 에러 상태 시뮬레이션을 위한 useEffect
2222
- useEffect(() => {
2223
- // 1초 후에 에러 상태로 설정
2224
- const timeoutId = setTimeout(() => {
2225
- setErrorStatus(CommonConst.GRID_STATUS.ERROR)
2226
- }, 1000)
2227
-
2228
- // 컴포넌트 언마운트 시 타임아웃 클리어
2229
- return () => {
2230
- clearTimeout(timeoutId)
2231
- }
2232
- }, [])
2233
- `,
2234
- code: `<OpsnowCommonDataGrid
2235
- columnDefs={columnDefs}
2236
- rowData={[]}
2237
- status={errorStatus}
2238
- gridOptions={gridOptions}
2239
- textErrorTitle="데이터 로드 실패"
2240
- textErrorDescription="데이터를 불러오는 중 오류가 발생했습니다."
2241
- langCd={i18n.getLocale()}
2242
- />`
2243
- },
2244
- {
2245
- title: 'Auto Row Height',
2246
- description: '행 높이 자동 조절 예제입니다. 다음 경우 반드시 적용: 1) 긴 텍스트가 들어올 수 있는 컬럼이 있는 경우 (설명, 메시지, 항목, 이름, 제목, 등) 2) 컬럼이 resizable인 경우 - 폭을 줄여도 텍스트가 잘리지 않고 여러 줄로 정상 표시되어야 함 (ellipsis로 자르면 안됨)',
2247
- code_props_usage: `
2248
- import { useCommonComponents, useGlobalContext } from '@opsnow-common/opsnow-finops-common-ui-loader'
2249
- import i18n from '@opsnow-common/opsnow-finops-common-i18n'
2250
-
2251
- // Long Text용 컬럼 정의
2252
- const columnDefs = [
2253
- {
2254
- headerName: 'ID',
2255
- field: 'id',
2256
- flex: 1,
2257
- minWidth: 80
2258
- },
2259
- {
2260
- headerName: 'Description',
2261
- field: 'description',
2262
- flex: 3, // 가장 넓은 비율
2263
- minWidth: 300,
2264
- wrapText: true, // 텍스트 줄바꿈 - 필수
2265
- autoHeight: true, // 행 높이 자동 조절 - 필수
2266
- suppressSizeToFit: true, // 자동 리사이즈 방지
2267
- cellStyle: {
2268
- alignItems: 'center' // autoHeight 작동을 위해 필수
2269
- }
2270
- },
2271
- {
2272
- headerName: 'Status',
2273
- field: 'status',
2274
- flex: 1,
2275
- minWidth: 120
2276
- },
2277
- ]
2278
-
2279
- // Long Text용 행 데이터
2280
- const rowData = [
2281
- {
2282
- id: 1,
2283
- description: 'This is a very long description text that will wrap to multiple lines when the column width is not sufficient to display all content in a single line. This demonstrates the autoHeight feature.',
2284
- status: 'Active'
2285
- },
2286
- {
2287
- id: 2,
2288
- description: 'Short text',
2289
- status: 'Inactive'
2290
- },
2291
- {
2292
- id: 3,
2293
- description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.',
2294
- status: 'Pending'
2295
- },
2296
- {
2297
- id: 4,
2298
- description: 'Another example of long text content that needs multiple lines',
2299
- status: 'Active'
2300
- },
2301
- ]
2302
-
2303
- const defaultColDef = {
2304
- wrapText: true, // 텍스트 줄바꿈 활성화
2305
- autoHeight: true, // 셀 높이 자동 조절
2306
- }
2307
-
2308
- const gridOptions = {
2309
- animateRows: true,
2310
- rowSelection: { mode: 'singleRow', checkboxes: false, enableClickSelection: true },
2311
- tooltipShowDelay: 100,
2312
- domLayout: 'autoHeight', // 그리드 전체 레이아웃 자동 높이
2313
- suppressCellFocus: true,
2314
- }
2315
-
2316
- const { OpsnowCommonDataGrid } = useCommonComponents();
2317
- const { CommonConst } = useGlobalContext()
2318
- `,
2319
- code: `<OpsnowCommonDataGrid
2320
- columnDefs={columnDefs}
2321
- defaultColDef={defaultColDef}
2322
- rowData={rowData}
2323
- status={CommonConst.GRID_STATUS.DATA_EXISTS}
2324
- gridOptions={gridOptions}
2325
- langCd={i18n.getLocale()}
2326
- />`
2327
- },
2328
- ];