onekijs-ui 0.19.20 → 0.19.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.
- package/dist/components/table/TableService.d.ts +2 -1
- package/dist/components/table/seralizers/defaultCellSerializer.d.ts +3 -0
- package/dist/components/table/typings.d.ts +6 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -1
- package/dist/index.module.js +92 -1
- package/dist/index.module.js.map +1 -1
- package/dist/styles/border.d.ts +1 -1
- package/dist/styles/flex.d.ts +1 -1
- package/dist/styles/size.d.ts +6 -6
- package/dist/styles/typography.d.ts +2 -2
- package/dist/utils/formatter.d.ts +1 -0
- package/package.json +2 -2
- package/src/components/table/TableService.ts +44 -2
- package/src/components/table/columns/checkboxColumn.ts +2 -0
- package/src/components/table/columns/enumColumn.tsx +20 -1
- package/src/components/table/columns/inputColumn.ts +2 -0
- package/src/components/table/columns/numberColumn.ts +2 -0
- package/src/components/table/columns/selectColumn.ts +23 -1
- package/src/components/table/columns/textColumn.ts +2 -0
- package/src/components/table/columns/textareaColumn.ts +2 -0
- package/src/components/table/seralizers/defaultCellSerializer.tsx +8 -0
- package/src/components/table/typings.ts +8 -1
- package/src/index.ts +3 -0
- package/src/utils/formatter.ts +20 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AnonymousObject, CollectionService } from 'onekijs-framework';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { TableColumn, TableColumnWidth, TableConfig, TableController, TableItem, TableState } from './typings';
|
|
3
|
+
import { TableColumn, TableColumnWidth, TableConfig, TableController, TableItem, TableSerializerFormat, TableState } from './typings';
|
|
4
4
|
export declare const parseColumnWidth: (width?: string | number) => TableColumnWidth;
|
|
5
5
|
declare class TableService<T = any, I extends TableItem<T> = TableItem<T>, S extends TableState<T, I> = TableState<T, I>> extends CollectionService<T, I, S> implements TableController<T, I> {
|
|
6
6
|
protected cells: AnonymousObject<AnonymousObject<React.RefObject<HTMLDivElement>>>;
|
|
@@ -13,6 +13,7 @@ declare class TableService<T = any, I extends TableItem<T> = TableItem<T>, S ext
|
|
|
13
13
|
initCell(rowNumber: number | 'header-title' | 'header-filter' | 'footer', colId: string, ref: React.RefObject<HTMLDivElement>): void;
|
|
14
14
|
removeColumn(id: string): void;
|
|
15
15
|
resetWidth(): void;
|
|
16
|
+
serialize(data: T[], format: TableSerializerFormat): string;
|
|
16
17
|
toggle(item: I): void;
|
|
17
18
|
protected _setCellWidth(fit: boolean): void;
|
|
18
19
|
}
|
|
@@ -92,6 +92,7 @@ export type TableBodyRowProps<T = any, I extends TableItem<T> = TableItem<T>> =
|
|
|
92
92
|
onCollapsing?: (item: I | undefined, index: number) => void;
|
|
93
93
|
onCollapsed?: (item: I | undefined, index: number) => void;
|
|
94
94
|
};
|
|
95
|
+
export type TableSerializerFormat = 'csv' | 'json';
|
|
95
96
|
export type TableConfig<T = any, I extends TableItem<T> = TableItem<T>> = {
|
|
96
97
|
autoRefresh?: number;
|
|
97
98
|
bodyClassName?: string;
|
|
@@ -127,6 +128,7 @@ export type TableConfig<T = any, I extends TableItem<T> = TableItem<T>> = {
|
|
|
127
128
|
preload?: number;
|
|
128
129
|
rowClassName?: string | ((item: I | undefined, rowIndex: number, columns: TableColumn<T, I>[]) => string);
|
|
129
130
|
RowComponent?: React.FC<TableBodyRowProps<T, I>>;
|
|
131
|
+
serializer?: (data: T[], format: TableSerializerFormat) => string;
|
|
130
132
|
sortable?: boolean;
|
|
131
133
|
stripRows?: boolean;
|
|
132
134
|
tail?: boolean;
|
|
@@ -147,6 +149,7 @@ export type TableController<T = any, I extends TableItem<T> = TableItem<T>, S ex
|
|
|
147
149
|
initCell(rowIndex: number | 'header-title' | 'header-filter' | 'footer', colId: string, ref: React.RefObject<HTMLDivElement>): void;
|
|
148
150
|
removeColumn(id: string): void;
|
|
149
151
|
removeSelected<B extends keyof CollectionBy<T, I>>(by: B, target: CollectionBy<T, I>[B] | CollectionBy<T, I>[B][]): I[];
|
|
152
|
+
serialize: (data: T[], format: TableSerializerFormat) => string;
|
|
150
153
|
setSelected<B extends keyof CollectionBy<T, I>>(by: B, target: CollectionBy<T, I>[B] | CollectionBy<T, I>[B][]): I[];
|
|
151
154
|
startAutoRefresh: (interval: number) => void;
|
|
152
155
|
stopAutoRefresh: () => void;
|
|
@@ -167,6 +170,7 @@ export type TableCellDisplayerProps<T, I extends TableItem<T> = TableItem<T>> =
|
|
|
167
170
|
value: T;
|
|
168
171
|
format: FormDisplayerProps['format'];
|
|
169
172
|
};
|
|
173
|
+
export type TableCellSerializer<T, I extends TableItem<T> = TableItem<T>> = (data: T, column: TableColumn<T, I>, format: TableSerializerFormat) => any;
|
|
170
174
|
export type TableColumnSpec<T, I extends TableItem<T> = TableItem<T>> = {
|
|
171
175
|
className?: string | ((item: I, column: TableColumn<T, I>, rowIndex: number) => string);
|
|
172
176
|
CellComponent?: Cell<T, I>;
|
|
@@ -177,15 +181,16 @@ export type TableColumnSpec<T, I extends TableItem<T> = TableItem<T>> = {
|
|
|
177
181
|
filterable?: boolean;
|
|
178
182
|
FilterComponent?: React.FC<TableHeaderCellProps<T, I>>;
|
|
179
183
|
headerClassName?: string | ((column: TableColumn<T, I>) => string);
|
|
184
|
+
help?: ReactNode;
|
|
180
185
|
id: string;
|
|
181
186
|
maxWidth?: string;
|
|
182
187
|
minWidth?: string;
|
|
188
|
+
serializer?: TableCellSerializer<T, I>;
|
|
183
189
|
sortable?: boolean;
|
|
184
190
|
title?: string;
|
|
185
191
|
TitleComponent?: React.FC<TableHeaderCellProps<T, I>>;
|
|
186
192
|
weight?: number;
|
|
187
193
|
width?: string;
|
|
188
|
-
help?: ReactNode;
|
|
189
194
|
};
|
|
190
195
|
export type TableColumnWidth = {
|
|
191
196
|
auto?: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -160,7 +160,7 @@ export { default as useTextColumn } from './components/table/hooks/useTextColumn
|
|
|
160
160
|
export { default as useTextareaColumn } from './components/table/hooks/useTextareaColumn';
|
|
161
161
|
export { default as FormCardDisplayer } from './components/card/FormCardDisplayer';
|
|
162
162
|
export { filterListStyle, tableStyle } from './components/table/style';
|
|
163
|
-
export { ArrayTableProps, Cell, CheckboxColumn, CheckboxColumnOptions, ControllerTableProps, EnumColumnOptions, FormCellDisplayerProps, FormTableContext, FormTableItemDisplayerProps, FormTableProps, TableValueDisplayerProps, InputColumn, InputColumnOptions, LinkColumnOptions, SelectCell, SelectColumn, SelectColumnOptions, TableBodyCellProps, TableBodyProps, TableBodyRowProps, TableCellDisplayerProps, TableColumn, TableColumnComputedWidth, TableColumnOptions, TableColumnSpec, TableColumnWidth, TableColumnsState, TableConfig, TableController, TableExpandedProps, TableFilterOperator, TableFilterOperatorProps, TableFooterCellProps, TableFooterProps, TableHeaderCellProps, TableHeaderProps, TableItem, TableItemAdaptee, TableItemAdapter, TableItems, TableNotFoundProps, TableProps, TableRowHandler, TableSortProps, TableState, TextareaColumn, TextareaColumnOptions, UseTableController, UseTableOptions, } from './components/table/typings';
|
|
163
|
+
export { ArrayTableProps, Cell, CheckboxColumn, CheckboxColumnOptions, ControllerTableProps, EnumColumnOptions, FormCellDisplayerProps, FormTableContext, FormTableItemDisplayerProps, FormTableProps, TableValueDisplayerProps, InputColumn, InputColumnOptions, LinkColumnOptions, SelectCell, SelectColumn, SelectColumnOptions, TableBodyCellProps, TableBodyProps, TableBodyRowProps, TableCellDisplayerProps, TableColumn, TableColumnComputedWidth, TableColumnOptions, TableColumnSpec, TableColumnWidth, TableColumnsState, TableConfig, TableController, TableExpandedProps, TableFilterOperator, TableFilterOperatorProps, TableFooterCellProps, TableFooterProps, TableHeaderCellProps, TableHeaderProps, TableItem, TableItemAdaptee, TableItemAdapter, TableItems, TableNotFoundProps, TableProps, TableRowHandler, TableSortProps, TableState, TextareaColumn, TextareaColumnOptions, UseTableController, UseTableOptions, TableCellSerializer, TableSerializerFormat } from './components/table/typings';
|
|
164
164
|
export { default as Tag } from './components/tag';
|
|
165
165
|
export { default as TagComponent } from './components/tag/components/TagComponent';
|
|
166
166
|
export { tagStyle } from './components/tag/style';
|
|
@@ -182,6 +182,7 @@ export { default as ArrayTreeComponent } from './components/tree/components/Arra
|
|
|
182
182
|
export { default as ControllerTreeComponent } from './components/tree/components/ControllerTreeComponent';
|
|
183
183
|
export { default as TreeBodyComponent } from './components/tree/components/TreeBodyComponent';
|
|
184
184
|
export { default as TreeComponent } from './components/tree/components/TreeComponent';
|
|
185
|
+
export { default as defaultCellSerializer } from './components/table/seralizers/defaultCellSerializer';
|
|
185
186
|
export { default as TreeItemComponent, TreeItemContent, TreeItemToggler, } from './components/tree/components/TreeItemComponent';
|
|
186
187
|
export { default as TreeListComponent } from './components/tree/components/TreeListComponent';
|
|
187
188
|
export { default as VirtualTreeBodyComponent } from './components/tree/components/VirtualTreeBodyComponent';
|
package/dist/index.js
CHANGED
|
@@ -405,6 +405,24 @@ const enumFormatter = (values) => {
|
|
|
405
405
|
return String(value);
|
|
406
406
|
};
|
|
407
407
|
};
|
|
408
|
+
const escapeCsvValue = (value, separator = ',') => {
|
|
409
|
+
const escape = (value) => {
|
|
410
|
+
if (Array.isArray(value)) {
|
|
411
|
+
return value.map((v) => escape(v)).join(',');
|
|
412
|
+
}
|
|
413
|
+
if (value === null || value === undefined)
|
|
414
|
+
return '';
|
|
415
|
+
return `${value}`;
|
|
416
|
+
};
|
|
417
|
+
const result = escape(value);
|
|
418
|
+
if (result.startsWith('"') && result.endsWith('"'))
|
|
419
|
+
return result; // the string is already escaped
|
|
420
|
+
// escape only if the string contains the separator
|
|
421
|
+
if (result.includes(separator)) {
|
|
422
|
+
return `"${result.replace(/"/g, '""')}"`;
|
|
423
|
+
}
|
|
424
|
+
return result;
|
|
425
|
+
};
|
|
408
426
|
const pxFormatter = (value) => {
|
|
409
427
|
if (typeof value === 'string') {
|
|
410
428
|
return value;
|
|
@@ -9182,6 +9200,36 @@ let TableService = class TableService extends onekijsFramework.CollectionService
|
|
|
9182
9200
|
column.computedWidth = undefined;
|
|
9183
9201
|
});
|
|
9184
9202
|
}
|
|
9203
|
+
serialize(data, format) {
|
|
9204
|
+
const serializer = this.config?.serializer;
|
|
9205
|
+
if (serializer) {
|
|
9206
|
+
return serializer(data, format);
|
|
9207
|
+
}
|
|
9208
|
+
const serializableColumns = (this.state.columns || []).filter((c) => c.serializer !== undefined);
|
|
9209
|
+
switch (format) {
|
|
9210
|
+
case 'csv':
|
|
9211
|
+
let result = 'sep=,';
|
|
9212
|
+
const header = serializableColumns.map((c) => escapeCsvValue(onekijsFramework.get(c, 'title', onekijsFramework.get(c, 'id')))).join(',');
|
|
9213
|
+
result = `${result}\n${header}`;
|
|
9214
|
+
const csvRows = data.map((row) => {
|
|
9215
|
+
const columns = serializableColumns
|
|
9216
|
+
.map((c) => c.serializer(row, c, format))
|
|
9217
|
+
.map((s) => {
|
|
9218
|
+
return escapeCsvValue(s, ',');
|
|
9219
|
+
});
|
|
9220
|
+
return columns.join(',');
|
|
9221
|
+
});
|
|
9222
|
+
return `${result}\n${csvRows.join('\n')}`;
|
|
9223
|
+
case 'json':
|
|
9224
|
+
const rows = data.map((row) => {
|
|
9225
|
+
return serializableColumns.reduce((accumulator, c) => {
|
|
9226
|
+
accumulator[c.title ?? c.id] = c.serializer(row, c, format);
|
|
9227
|
+
return accumulator;
|
|
9228
|
+
}, {});
|
|
9229
|
+
});
|
|
9230
|
+
return JSON.stringify(rows);
|
|
9231
|
+
}
|
|
9232
|
+
}
|
|
9185
9233
|
toggle(item) {
|
|
9186
9234
|
this.setMeta('item', item, 'expanded', !item.expanded);
|
|
9187
9235
|
}
|
|
@@ -10482,6 +10530,10 @@ const DefaultFormCellDisplayer = (props) => {
|
|
|
10482
10530
|
return null;
|
|
10483
10531
|
};
|
|
10484
10532
|
|
|
10533
|
+
const defaultCellSerializer = (data, column) => {
|
|
10534
|
+
return onekijsFramework.get(data, column.id, null);
|
|
10535
|
+
};
|
|
10536
|
+
|
|
10485
10537
|
const checkboxColumn = (id, options) => {
|
|
10486
10538
|
const Component = options.CellComponent || CheckboxCellComponent;
|
|
10487
10539
|
return Object.assign({
|
|
@@ -10489,6 +10541,7 @@ const checkboxColumn = (id, options) => {
|
|
|
10489
10541
|
sortable: false,
|
|
10490
10542
|
className: 'o-checkbox-cell',
|
|
10491
10543
|
Displayer: DefaultFormCellDisplayer,
|
|
10544
|
+
serializer: defaultCellSerializer,
|
|
10492
10545
|
}, options, {
|
|
10493
10546
|
id,
|
|
10494
10547
|
CellComponent: Component(options),
|
|
@@ -10541,12 +10594,28 @@ const TableSelectFilterComponent = ({ column, dataSource, }) => {
|
|
|
10541
10594
|
TableSelectFilterComponent.displayName = 'TableInputFilterComponent';
|
|
10542
10595
|
|
|
10543
10596
|
const enumColumn = (id, options) => {
|
|
10597
|
+
const serializer = (data, column, format) => {
|
|
10598
|
+
const value = onekijsFramework.get(data, column.id, null);
|
|
10599
|
+
const entry = options.filterDataSource.find((item) => {
|
|
10600
|
+
if (Array.isArray(item)) {
|
|
10601
|
+
if (item[0] === value) {
|
|
10602
|
+
return true;
|
|
10603
|
+
}
|
|
10604
|
+
}
|
|
10605
|
+
return false;
|
|
10606
|
+
});
|
|
10607
|
+
if (entry) {
|
|
10608
|
+
return entry[1];
|
|
10609
|
+
}
|
|
10610
|
+
return defaultCellSerializer(data, column);
|
|
10611
|
+
};
|
|
10544
10612
|
return Object.assign({
|
|
10545
10613
|
CellComponent: DefaultCellComponent,
|
|
10546
10614
|
filterable: true,
|
|
10547
10615
|
FilterComponent: (props) => (React.createElement(TableSelectFilterComponent, { ...props, dataSource: options.filterDataSource })),
|
|
10548
10616
|
sortable: true,
|
|
10549
10617
|
Displayer: DefaultFormCellDisplayer,
|
|
10618
|
+
serializer,
|
|
10550
10619
|
}, options, {
|
|
10551
10620
|
id,
|
|
10552
10621
|
});
|
|
@@ -10570,6 +10639,7 @@ const inputColumn = (id, options) => {
|
|
|
10570
10639
|
filterable: false,
|
|
10571
10640
|
sortable: false,
|
|
10572
10641
|
Displayer: DefaultFormCellDisplayer,
|
|
10642
|
+
serializer: defaultCellSerializer,
|
|
10573
10643
|
}, options, {
|
|
10574
10644
|
id,
|
|
10575
10645
|
CellComponent: Component(options),
|
|
@@ -10593,6 +10663,7 @@ const textColumn = (id, options) => {
|
|
|
10593
10663
|
FilterComponent: TableTextFilterComponent,
|
|
10594
10664
|
sortable: true,
|
|
10595
10665
|
Displayer: DefaultFormCellDisplayer,
|
|
10666
|
+
serializer: defaultCellSerializer,
|
|
10596
10667
|
}, options, {
|
|
10597
10668
|
id,
|
|
10598
10669
|
});
|
|
@@ -10624,6 +10695,7 @@ const numberColumn = (id, options) => {
|
|
|
10624
10695
|
FilterComponent: TableNumberFilterComponent,
|
|
10625
10696
|
sortable: true,
|
|
10626
10697
|
Displayer: DefaultFormCellDisplayer,
|
|
10698
|
+
serializer: defaultCellSerializer,
|
|
10627
10699
|
}, options, {
|
|
10628
10700
|
id,
|
|
10629
10701
|
});
|
|
@@ -10663,12 +10735,30 @@ const selectColumn = (id, options) => {
|
|
|
10663
10735
|
};
|
|
10664
10736
|
opts.adapter = adapter;
|
|
10665
10737
|
}
|
|
10738
|
+
const serializer = (data, column, format) => {
|
|
10739
|
+
const value = onekijsFramework.get(data, column.id, null);
|
|
10740
|
+
if (Array.isArray(opts.dataSource)) {
|
|
10741
|
+
const entry = opts.dataSource.find((item) => {
|
|
10742
|
+
if (Array.isArray(item)) {
|
|
10743
|
+
if (item[0] === value) {
|
|
10744
|
+
return true;
|
|
10745
|
+
}
|
|
10746
|
+
}
|
|
10747
|
+
return false;
|
|
10748
|
+
});
|
|
10749
|
+
if (entry && Array.isArray(entry)) {
|
|
10750
|
+
return entry[1];
|
|
10751
|
+
}
|
|
10752
|
+
}
|
|
10753
|
+
return defaultCellSerializer(data, column);
|
|
10754
|
+
};
|
|
10666
10755
|
const broker = new DefaultSelectBroker(dataSource, opts);
|
|
10667
10756
|
const Component = opts.CellComponent || SelectCellComponent;
|
|
10668
10757
|
return Object.assign({
|
|
10669
10758
|
filterable: false,
|
|
10670
10759
|
sortable: false,
|
|
10671
10760
|
Displayer: DefaultFormCellDisplayer,
|
|
10761
|
+
serializer,
|
|
10672
10762
|
}, opts, {
|
|
10673
10763
|
id,
|
|
10674
10764
|
CellComponent: Component(opts, broker),
|
|
@@ -10820,6 +10910,7 @@ const textareaColumn = (id, options) => {
|
|
|
10820
10910
|
filterable: false,
|
|
10821
10911
|
sortable: false,
|
|
10822
10912
|
Displayer: DefaultFormCellDisplayer,
|
|
10913
|
+
serializer: defaultCellSerializer,
|
|
10823
10914
|
}, options, {
|
|
10824
10915
|
id,
|
|
10825
10916
|
CellComponent: Component(options),
|
|
@@ -12611,6 +12702,7 @@ exports.cssProperty = cssProperty;
|
|
|
12611
12702
|
exports.cursor = cursor;
|
|
12612
12703
|
exports.darken = darken;
|
|
12613
12704
|
exports.dashboardOverlayStyle = dashboardOverlayStyle;
|
|
12705
|
+
exports.defaultCellSerializer = defaultCellSerializer;
|
|
12614
12706
|
exports.defaultTreeQueryEngine = defaultTreeQueryEngine;
|
|
12615
12707
|
exports.deriveColor = deriveColor;
|
|
12616
12708
|
exports.display = display;
|
|
@@ -12619,6 +12711,7 @@ exports.dropdownStyle = dropdownStyle;
|
|
|
12619
12711
|
exports.emptyCells = emptyCells;
|
|
12620
12712
|
exports.enumColumn = enumColumn;
|
|
12621
12713
|
exports.enumFormatter = enumFormatter;
|
|
12714
|
+
exports.escapeCsvValue = escapeCsvValue;
|
|
12622
12715
|
exports.fieldDescriptionStyle = fieldDescriptionStyle;
|
|
12623
12716
|
exports.fieldDisplayerStyle = fieldDisplayerStyle;
|
|
12624
12717
|
exports.fieldHelpStyle = fieldHelpStyle;
|