devextreme-planit-treegrid-react 0.1.5 → 0.1.7

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,580 @@
1
+ import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
2
+
3
+ import { LoadPanel } from 'devextreme-react/load-panel';
4
+
5
+ import PivotGrid, { FieldChooser } from 'devextreme-react/pivot-grid';
6
+ import { StateStoring } from 'devextreme-react/data-grid';
7
+ import DevExpress from 'devextreme';
8
+ import { ColumnField, IColorInfo, IGroupField, Props } from './type';
9
+ import { exportPivotGrid } from 'devextreme/excel_exporter';
10
+ import { Workbook } from 'exceljs';
11
+ import saveAs from 'file-saver';
12
+ import PivotGridDataSource from 'devextreme/ui/pivot_grid/data_source';
13
+
14
+ /**
15
+ * devextreme pivotgrid Configrations 중 사용 불가 항목 : id, width, height, showColumnGrandTotals, showColumnTotals, showRowGrandTotals, FieldChooser
16
+ * devextreme pivotgrid Configrations 중 사용 방법 변경 항목 : stateStoring, Export
17
+ * onExported, onFileSaving 이벤트 사용하지 않음.
18
+ */
19
+ /**
20
+ * todoList:
21
+ * 2) columIndex 초기화 기능이 있어야 함(column 개수 변할 때)
22
+ * 3) 헤더에 테이블 삽입되면서 그리드 크기가 늘어남. height에 그리드 크기 늘어난 만큼 반영되어야 함.
23
+ */
24
+
25
+ const grandTotalCssNm = 'data-grand-total';
26
+
27
+ const DxPlanitTreeGrid = forwardRef(
28
+ (props: Props, ref: any): JSX.Element => {
29
+ const {
30
+ id = 'dx-planit-vera-pivotgrid-id',
31
+ groupField,
32
+ dataColor,
33
+ convertNullToHipen = true,
34
+ convertZeroToHipen = true,
35
+ stateStoringKey = '',
36
+ allowExpandAll = false,
37
+ allowFiltering = false,
38
+ allowSorting = false,
39
+ allowSortingBySummary = false,
40
+ dataFieldArea = 'column',
41
+ dataSource,
42
+ disabled = false,
43
+ elementAttr,
44
+ encodeHtml,
45
+ hideEmptySummaryCells = false,
46
+ hint,
47
+ rowHeaderLayout = 'standard',
48
+ rtlEnabled = false,
49
+ showBorders = true,
50
+ showRowTotals = true,
51
+ showTotalsPrior = 'none',
52
+ tabIndex = 0,
53
+ visible = true,
54
+ wordWrapEnabled = false,
55
+ customExcelButton = false,
56
+ onCellClick,
57
+ onCellPrepared,
58
+ onContentReady,
59
+ onContextMenuPreparing,
60
+ onDisposing,
61
+ onExporting,
62
+ onInitialized,
63
+ onOptionChanged,
64
+ } = props;
65
+
66
+ const [width, setWidth] = useState(0);
67
+ const [height, setHeight] = useState(0);
68
+ const [columnIndex, setColumnIndex] = useState(0);
69
+ const [gridDataSource, setGridDataSource] = useState<PivotGridDataSource>(dataSource);
70
+
71
+ const $tableRef = useRef<PivotGrid>(null);
72
+ const excelBorder = { style: 'thin', color: { argb: 'FF7E7E7E' } };
73
+
74
+ useImperativeHandle(ref, () => ({
75
+ exportToExcel,
76
+ }));
77
+
78
+ /**
79
+ * 그리드 사이즈 재조정
80
+ * @returns 그리드 사이즈
81
+ */
82
+ const getGridSize = (): { width: number; height: number } => {
83
+ const wrapper = document.querySelector('.diag-table-wrapper');
84
+ const gap = 10;
85
+ setWidth(wrapper?.clientWidth ?? 0);
86
+ setHeight(wrapper ? wrapper.clientHeight - gap : 0);
87
+
88
+ window.addEventListener('resize', () => {
89
+ setWidth(wrapper?.clientWidth ?? 0);
90
+ setHeight(wrapper ? wrapper.clientHeight - gap : 0);
91
+ });
92
+ return { width, height };
93
+ };
94
+
95
+ /**
96
+ * 'Total' 을 한글로 변경
97
+ * @param e devextreme CellPreparedEvent
98
+ */
99
+ const changeTotalText = (e: DevExpress.ui.dxPivotGrid.CellPreparedEvent): void => {
100
+ if (!e.cellElement) {
101
+ return;
102
+ }
103
+ if (e.cell?.type === 'T') {
104
+ const text = e.cell.text?.replace('Total', '합계');
105
+ e.cellElement.innerHTML = `<span>${text}</span>`;
106
+ }
107
+ };
108
+
109
+ /**
110
+ * null값을 하이픈으로 모두 변경
111
+ * @param e devextreme CellPreparedEvent
112
+ */
113
+ const changeNullToHipen = (e: DevExpress.ui.dxPivotGrid.CellPreparedEvent): void => {
114
+ if (!convertNullToHipen) {
115
+ return;
116
+ }
117
+ if (e.area === 'data' && e.cell?.text === null && e.cellElement) {
118
+ e.cellElement.innerHTML = '<span class="text-color">-</span>';
119
+ }
120
+ };
121
+
122
+ /**
123
+ * '0', '0.0%' 를 하이픈으로 모두 변경
124
+ * @param e devextreme CellPreparedEvent
125
+ */
126
+ const changeZeroToHipen = (e: DevExpress.ui.dxPivotGrid.CellPreparedEvent): void => {
127
+ if (!convertZeroToHipen) {
128
+ return;
129
+ }
130
+ if (e.area === 'data' && (e.cell?.text === '0' || e.cell?.text === '0.0%' || e.cell?.text === '') && e.cellElement) {
131
+ e.cellElement.innerHTML = '<span class="text-color">-</span>';
132
+ }
133
+ };
134
+
135
+ /**
136
+ * 테이블 헤더에 colspan, rowspan 한 HTMLElement 정보 반환
137
+ * @param groupField 사용자가 작성한 그룹 정보
138
+ * @return
139
+ */
140
+ const makeColspan = (group: IGroupField, index: number, isLast: boolean): HTMLElement => {
141
+ const td = document.createElement('td');
142
+ let text = group.groupCaption;
143
+
144
+ if (group.depth === 1) {
145
+ text = `${group.groupCaption}`;
146
+ }
147
+
148
+ td.setAttribute('colspan', group.colspan.toString());
149
+ td.setAttribute('class', 'dx-row-total dx-grand-total dx-planit-colspan');
150
+
151
+ if (isLast && index === 0) {
152
+ td.setAttribute('style', 'border-bottom: 0; border-right: 0');
153
+ } else if (isLast && index !== 0) {
154
+ td.setAttribute('style', 'border-right: 0');
155
+ } else if (!isLast && index === 0) {
156
+ td.setAttribute('style', 'border-bottom: 0');
157
+ }
158
+ td.innerHTML = `<div>${text}</div>`;
159
+
160
+ return td;
161
+ };
162
+
163
+ /**
164
+ * 그룹 필드 데이터 유효성 검증용 데이터 생성
165
+ * @param groupField
166
+ * @returns
167
+ */
168
+ const makeCheckGroupData = (groupField: IGroupField[]): any => {
169
+ const data: any = {};
170
+
171
+ groupField?.forEach((group: IGroupField) => {
172
+ if (data[group.depth]) {
173
+ data[group.depth] += group.colspan;
174
+ } else {
175
+ data[group.depth] = group.colspan;
176
+ }
177
+ });
178
+
179
+ return data;
180
+ };
181
+
182
+ /**
183
+ * GroupField 데이터 검증
184
+ * @param 사용자가 설정한 그룹 필드 정보
185
+ * @returns 데이터 검증 결과
186
+ */
187
+ const isCheckGroupField = (groupField: IGroupField[]): boolean => {
188
+ const map = makeCheckGroupData(groupField);
189
+
190
+ for (const depth of Object.keys(map)) {
191
+ if (map[depth] !== columnIndex + 1) {
192
+ console.error('그룹 데이터의 children 숫자가 columnIndex와 맞지 않습니다. 다시 한 번 확인 바랍니다.');
193
+ }
194
+ }
195
+
196
+ return true;
197
+ };
198
+
199
+ /**
200
+ * Grand Total 셀 정보 저장
201
+ * @param e
202
+ */
203
+ const setTotalElementInfo = (e: DevExpress.ui.dxPivotGrid.CellPreparedEvent): void => {
204
+ if (!groupField?.length || e.cell?.type !== 'GT' || e.cell?.text !== 'Grand Total') {
205
+ return;
206
+ }
207
+
208
+ e.cellElement?.classList.add(grandTotalCssNm);
209
+ };
210
+
211
+ /**
212
+ * cell의 columnIndex 최대값 저장
213
+ * @param e
214
+ */
215
+ const setMaxColumIndex = (e: DevExpress.ui.dxPivotGrid.CellPreparedEvent): void => {
216
+ if (!e.columnIndex) {
217
+ return;
218
+ }
219
+ if (e.columnIndex > columnIndex) {
220
+ setColumnIndex(e.columnIndex);
221
+ }
222
+ };
223
+
224
+ /**
225
+ * groupField depth의 유니크한 배열 구하기
226
+ * @param group
227
+ * @param arr
228
+ * @returns
229
+ */
230
+ const getGroupDepth = (group: IGroupField[], arr: 'asc' | 'desc'): number[] => {
231
+ const groupData = group.slice();
232
+ const set = new Set(groupData.map((group: IGroupField) => group.depth));
233
+ return Array.from(set).sort(function compare(a: number, b: number) {
234
+ if (a > b) {
235
+ return arr === 'asc' ? -1 : 1;
236
+ }
237
+ if (a < b) {
238
+ return arr === 'asc' ? 1 : -1;
239
+ }
240
+ return 0;
241
+ });
242
+ };
243
+
244
+ /**
245
+ * 현재 depth에 맞는 그룹 필드 정보 반환
246
+ * @param group
247
+ * @param depth
248
+ * @returns
249
+ */
250
+ const getCurrentGroup = (group: IGroupField[], depth: number): IGroupField[] => {
251
+ return group.filter((gr: IGroupField) => gr.depth === depth);
252
+ };
253
+
254
+ /**
255
+ * 테이블 헤더(DOM)에 colspan 적용된 테이블 삽입
256
+ */
257
+ const insertRowHeaderGroup = (): void => {
258
+ if (!groupField?.length) {
259
+ return;
260
+ }
261
+
262
+ isCheckGroupField(groupField);
263
+
264
+ const totalElement = document.querySelector('.' + grandTotalCssNm);
265
+ const targetElement = totalElement?.parentNode;
266
+ const thead = targetElement?.parentNode;
267
+
268
+ if (!targetElement || !thead) {
269
+ return;
270
+ }
271
+
272
+ const firstChild = thead?.firstChild;
273
+ if (!firstChild) {
274
+ return;
275
+ }
276
+ totalElement.innerHTML = '';
277
+ totalElement.setAttribute('style', 'padding: 0; border: 0');
278
+ const colgroup = thead.previousSibling?.cloneNode(true);
279
+
280
+ const groupData = groupField.slice();
281
+ const depth = getGroupDepth(groupData, 'asc');
282
+
283
+ const table = document.createElement('table');
284
+
285
+ depth.forEach((dep: number, index: number) => {
286
+ const groupInfo = getCurrentGroup(groupData, dep);
287
+
288
+ const tr = document.createElement('tr');
289
+
290
+ groupInfo.forEach((group: IGroupField, cellIndex: number) => {
291
+ const isLast = cellIndex === groupInfo.length - 1 ? true : false;
292
+ tr.appendChild(makeColspan(group, index, isLast));
293
+ });
294
+ (table as HTMLElement).prepend(tr);
295
+ });
296
+
297
+ table.prepend(colgroup as Node);
298
+ totalElement.appendChild(table);
299
+ };
300
+
301
+ /**
302
+ * Devextreme의 dateController columnInfo에 그룹 정보 삽입
303
+ * @param group
304
+ * @returns
305
+ */
306
+ const makeDataControllerColumnGroup = (group: IGroupField[]): ColumnField[][] => {
307
+ const groupData = group.slice();
308
+ const depth = getGroupDepth(groupData, 'desc');
309
+
310
+ return depth.map((dep: number) => {
311
+ const groupInfo = getCurrentGroup(groupData, dep);
312
+ return groupInfo.map((group: IGroupField) => ({ colspan: group.colspan, text: group.groupCaption, type: 'GT' }));
313
+ });
314
+ };
315
+
316
+ /**
317
+ * 사용자가 입력한 컬러 조건을 { standard: string; condition: string } 형식으로 변경 반환
318
+ * @param condition 사용자 입력 컬러 조건식 ex) '>= 100'
319
+ * @returns
320
+ */
321
+ const makeSplitCondtion = (condition: string): { standard: string; condition: string } => {
322
+ const newCondition = { standard: '', condition: '' };
323
+ [...condition].forEach((cond: string) => {
324
+ if (Number.isNaN(parseFloat(cond))) {
325
+ newCondition.condition += cond;
326
+ } else {
327
+ newCondition.standard += cond;
328
+ }
329
+ });
330
+
331
+ return newCondition;
332
+ };
333
+
334
+ /**
335
+ * 데이터에 색상 적용
336
+ * @param e onCellPrepared 이벤트
337
+ * @returns
338
+ */
339
+ const makeColorAtPercent = (e: any): void => {
340
+ if (!dataColor || !e.cellElement) {
341
+ return;
342
+ }
343
+
344
+ dataColor.forEach((color: IColorInfo) => {
345
+ if (e.cell.value === null) {
346
+ return;
347
+ }
348
+ if (e.cell?.format?.type === color.format && !Number.isNaN(e.cell.value)) {
349
+ const standardData = makeSplitCondtion(color.condition.replace(/(\s*)/g, ''));
350
+ const rate = color.format === 'percent' ? 0.01 : 1;
351
+ let condition = false;
352
+
353
+ switch (standardData.condition) {
354
+ case '>':
355
+ condition = e.cell.value > parseFloat(standardData.standard) * rate;
356
+ break;
357
+ case '>=':
358
+ condition = e.cell.value >= parseFloat(standardData.standard) * rate;
359
+ break;
360
+ case '<':
361
+ condition = e.cell.value < parseFloat(standardData.standard) * rate;
362
+ break;
363
+ case '<=':
364
+ condition = e.cell.value <= parseFloat(standardData.standard) * rate;
365
+ break;
366
+ }
367
+
368
+ if (condition && !(e.cell.value === 0 && convertZeroToHipen)) {
369
+ e.cellElement.style.color = color.color;
370
+ }
371
+ }
372
+ });
373
+ };
374
+
375
+ /**
376
+ * 그리드 데이터 정합성 체크. 데이터 잘못되어 있으면 에러 발생
377
+ * @param dataSource
378
+ */
379
+ const checkDataSource = (dataSource: any): void => {
380
+ const isColumns = dataSource._fields.findIndex((field: any) => field.area === 'column');
381
+ const isRows = dataSource._fields.findIndex((field: any) => field.area === 'row');
382
+ const isDatas = dataSource._fields.findIndex((field: any) => field.area === 'data');
383
+
384
+ if (isColumns > -1) {
385
+ throw Error('DxPlanitTreeGrid는 column이 존재하는 형식의 pivot grid에는 사용할 수 없습니다.');
386
+ }
387
+
388
+ if (isRows === -1 || isDatas === -1) {
389
+ throw Error('DxPlanitTreeGrid 데이터는 row와 data가 반드시 존재해야 합니다.');
390
+ }
391
+ };
392
+
393
+ /**
394
+ * 그리드 펼침 정보 세션스토리지 리셋
395
+ */
396
+ const resetSession = (): void => {
397
+ sessionStorage.removeItem('dx-vera-pivotgrid-storing');
398
+ };
399
+
400
+ /**
401
+ * 엑셀 export 명령
402
+ * @param fileName 저장하고자 하는 엑셀파일명
403
+ */
404
+ const exportToExcel = (fileName: string): void => {
405
+ setTimeout(() => exportToExcelAction($tableRef.current?.instance, fileName));
406
+ };
407
+
408
+ /**
409
+ * devextreme component 정보의 dataController의 columnInfo에 사용자가 설정한 groupFIled 정보 병합
410
+ * @param component devextreme component
411
+ * @returns devextreme component
412
+ */
413
+ const convertDataControllerColumnsInfo = (component: any): any => {
414
+ let arr: ColumnField[][] = [];
415
+ const columnInfo = component._dataController._columnsInfo.forEach((column: ColumnField[]) => {
416
+ let newColumn = column.slice();
417
+ if (groupField && newColumn.length === 1 && newColumn[0].type === 'GT' && newColumn[0].text === 'Grand Total') {
418
+ arr.push(...makeDataControllerColumnGroup(groupField));
419
+ } else {
420
+ arr.push(newColumn);
421
+ }
422
+ });
423
+ component._dataController._columnsInfo = arr;
424
+ return component;
425
+ };
426
+
427
+ /**
428
+ * 엑셀 export
429
+ * @param e
430
+ */
431
+ const exportToExcelAction = (e: any, fileName: string): void => {
432
+ const newComponent = convertDataControllerColumnsInfo(e);
433
+
434
+ const workbook = new Workbook();
435
+ const worksheet = workbook.addWorksheet(fileName);
436
+
437
+ exportPivotGrid({
438
+ component: newComponent,
439
+ worksheet,
440
+ customizeCell: ({ excelCell }) => {
441
+ const borderStyle = excelBorder;
442
+ excelCell.border = {
443
+ bottom: borderStyle,
444
+ left: borderStyle,
445
+ right: borderStyle,
446
+ top: borderStyle,
447
+ };
448
+ },
449
+ }).then(() => {
450
+ workbook.xlsx.writeBuffer().then(buffer => {
451
+ saveAs(new Blob([buffer], { type: 'application/octet-stream' }), fileName + '.xlsx');
452
+ });
453
+ });
454
+ e.cancel = true;
455
+ };
456
+
457
+ /**
458
+ * devextreme CellPreparedEvent 이벤트 실행
459
+ * @param e
460
+ */
461
+ const onCellPreparedChild = (
462
+ e: DevExpress.ui.dxPivotGrid.CellPreparedEvent
463
+ ): ((e: DevExpress.ui.dxPivotGrid.CellPreparedEvent) => void) | void => {
464
+ makeColorAtPercent(e);
465
+ setTotalElementInfo(e);
466
+ setMaxColumIndex(e);
467
+ changeTotalText(e);
468
+ changeNullToHipen(e);
469
+ changeZeroToHipen(e);
470
+
471
+ return onCellPrepared ? onCellPrepared(e) : undefined;
472
+ };
473
+
474
+ /**
475
+ * devextreme Raise Event
476
+ */
477
+ const onContentReadyChild = (
478
+ e: DevExpress.ui.dxPivotGrid.ContentReadyEvent
479
+ ): ((e: DevExpress.ui.dxPivotGrid.ContentReadyEvent) => void) | void => {
480
+ setTimeout(() => insertRowHeaderGroup(), 0);
481
+ getGridSize();
482
+
483
+ return onContentReady ? onContentReady(e) : undefined;
484
+ };
485
+
486
+ const onCellClickChild = (
487
+ e: DevExpress.ui.dxPivotGrid.CellClickEvent
488
+ ): ((e: DevExpress.ui.dxPivotGrid.CellClickEvent) => void) | void => {
489
+ return onCellClick ? onCellClick(e) : undefined;
490
+ };
491
+
492
+ const onContextMenuPreparingChild = (
493
+ e: DevExpress.ui.dxPivotGrid.ContextMenuPreparingEvent
494
+ ): ((e: DevExpress.ui.dxPivotGrid.ContextMenuPreparingEvent) => void) | void => {
495
+ return onContextMenuPreparing ? onContextMenuPreparing(e) : undefined;
496
+ };
497
+
498
+ const onDisposingChild = (
499
+ e: DevExpress.ui.dxPivotGrid.DisposingEvent
500
+ ): ((e: DevExpress.ui.dxPivotGrid.DisposingEvent) => void) | void => {
501
+ return onDisposing ? onDisposing(e) : undefined;
502
+ };
503
+
504
+ const onExportingChild = (
505
+ e: DevExpress.ui.dxPivotGrid.ExportingEvent
506
+ ): ((e: DevExpress.ui.dxPivotGrid.ExportingEvent) => void) | void => {
507
+ return onExporting ? onExporting(e) : undefined;
508
+ };
509
+
510
+ const onInitializedChild = (
511
+ e: DevExpress.ui.dxPivotGrid.InitializedEvent
512
+ ): ((e: DevExpress.ui.dxPivotGrid.InitializedEvent) => void) | void => {
513
+ return onInitialized ? onInitialized(e) : undefined;
514
+ };
515
+
516
+ const onOptionChangedChild = (
517
+ e: DevExpress.ui.dxPivotGrid.OptionChangedEvent
518
+ ): ((e: DevExpress.ui.dxPivotGrid.OptionChangedEvent) => void) | void => {
519
+ return onOptionChanged ? onOptionChanged(e) : undefined;
520
+ };
521
+
522
+ useEffect(() => {
523
+ if (customExcelButton) {
524
+ }
525
+ }, [customExcelButton]);
526
+
527
+ useEffect(() => {
528
+ setGridDataSource(dataSource);
529
+ checkDataSource(dataSource);
530
+ resetSession();
531
+ }, [dataSource]);
532
+
533
+ return (
534
+ <div>
535
+ <LoadPanel position={{ of: id }} />
536
+ <PivotGrid
537
+ id={id}
538
+ ref={$tableRef}
539
+ dataSource={gridDataSource}
540
+ showColumnTotals={false}
541
+ showColumnGrandTotals={true}
542
+ showRowGrandTotals={false}
543
+ width={width}
544
+ height={height}
545
+ allowExpandAll={allowExpandAll}
546
+ allowFiltering={allowFiltering}
547
+ allowSorting={allowSorting}
548
+ allowSortingBySummary={allowSortingBySummary}
549
+ dataFieldArea={dataFieldArea}
550
+ disabled={disabled}
551
+ elementAttr={elementAttr}
552
+ encodeHtml={encodeHtml}
553
+ hideEmptySummaryCells={hideEmptySummaryCells}
554
+ hint={hint}
555
+ rowHeaderLayout={rowHeaderLayout}
556
+ rtlEnabled={rtlEnabled}
557
+ showBorders={showBorders}
558
+ showRowTotals={showRowTotals}
559
+ showTotalsPrior={showTotalsPrior}
560
+ tabIndex={tabIndex}
561
+ visible={visible}
562
+ wordWrapEnabled={wordWrapEnabled}
563
+ onCellClick={onCellClickChild}
564
+ onContentReady={onContentReadyChild}
565
+ onCellPrepared={onCellPreparedChild}
566
+ onContextMenuPreparing={onContextMenuPreparingChild}
567
+ onDisposing={onDisposingChild}
568
+ onExporting={onExportingChild}
569
+ onInitialized={onInitializedChild}
570
+ onOptionChanged={onOptionChangedChild}
571
+ >
572
+ <StateStoring enabled={stateStoringKey?.length} type="sessionStorage" storageKey={stateStoringKey} />
573
+ <FieldChooser enabled={false} />
574
+ </PivotGrid>
575
+ </div>
576
+ );
577
+ }
578
+ );
579
+
580
+ export default DxPlanitTreeGrid;
package/dist/index.tsx ADDED
@@ -0,0 +1,3 @@
1
+ import DxPlanitTreeGrid from './DxPlanitTreeGrid';
2
+
3
+ export default DxPlanitTreeGrid;
package/dist/type.ts ADDED
@@ -0,0 +1,32 @@
1
+ import DevExpress from 'devextreme';
2
+ import { Format } from 'devextreme/localization';
3
+
4
+ export interface IGroupField {
5
+ groupCaption: string;
6
+ groupName?: string;
7
+ depth: number;
8
+ colspan: number;
9
+ }
10
+
11
+ export interface IColorInfo {
12
+ format: Format;
13
+ color: string;
14
+ condition: string;
15
+ }
16
+
17
+ export interface ColumnField {
18
+ colspan: number;
19
+ text: string;
20
+ type: string;
21
+ }
22
+
23
+ export interface Props extends DevExpress.ui.dxPivotGrid.Properties {
24
+ id?: string;
25
+ dataSource?: any;
26
+ groupField?: IGroupField[];
27
+ dataColor?: IColorInfo[];
28
+ convertNullToHipen?: boolean;
29
+ convertZeroToHipen?: boolean;
30
+ stateStoringKey?: string;
31
+ customExcelButton?: boolean;
32
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devextreme-planit-treegrid-react",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Devextreme의 DxPivotGrid를 Tree Grid처럼 보여주는 Wrapper입니다.",
5
5
  "main": "dist/index.tsx",
6
6
  "module": "dist/index.tsx",
@@ -47,7 +47,7 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "devextreme": "^22.1.6",
50
- "devextreme-planit-treegrid-react": "^0.1.4",
50
+ "devextreme-planit-treegrid-react": "^0.1.5",
51
51
  "devextreme-react": "^22.1.6",
52
52
  "exceljs": "^4.3.0",
53
53
  "file-saver": "^2.0.5",