onekijs-ui 0.19.19 → 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/dropdown/typings.d.ts +1 -0
- 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 +96 -2
- package/dist/index.js.map +1 -1
- package/dist/index.module.js +95 -3
- 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 +3 -3
- package/src/components/dropdown/components/DropdownComponent.tsx +3 -1
- package/src/components/dropdown/typings.ts +1 -0
- 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;
|
|
@@ -1094,7 +1112,7 @@ const sameWidthPopperModifier = refWidth('width');
|
|
|
1094
1112
|
const minWidthPopperModifier = refWidth('minWidth');
|
|
1095
1113
|
const maxWidthPopperModifier = refWidth('maxWidth');
|
|
1096
1114
|
|
|
1097
|
-
const DropdownComponent = ({ animationTimeout = 0, attachToBody = false, className, refElement, open, children, skidding = 0, distance = 0, onUpdate, onDropDone, onDropStart, onCollapseDone, onCollapseStart, onDropping, onCollapsing, placement = 'auto', width, widthModifier = 'same', zIndex = 1, }) => {
|
|
1115
|
+
const DropdownComponent = ({ animationTimeout = 0, attachToBody = false, className, refElement, open, children, skidding = 0, distance = 0, onUpdate, onDropDone, onDropStart, onCollapseDone, onCollapseStart, onDropping, onCollapsing, placement = 'auto', fallbackPlacements, width, widthModifier = 'same', zIndex = 1, }) => {
|
|
1098
1116
|
const [popperElement, setPopperElement] = React.useState(null);
|
|
1099
1117
|
const popperWidthModifier = widthModifier === 'same'
|
|
1100
1118
|
? sameWidthPopperModifier
|
|
@@ -1113,7 +1131,8 @@ const DropdownComponent = ({ animationTimeout = 0, attachToBody = false, classNa
|
|
|
1113
1131
|
},
|
|
1114
1132
|
{
|
|
1115
1133
|
name: 'flip',
|
|
1116
|
-
enabled: placement === 'auto',
|
|
1134
|
+
enabled: placement === 'auto' || (fallbackPlacements !== undefined && fallbackPlacements.length > 0),
|
|
1135
|
+
options: fallbackPlacements && fallbackPlacements.length > 0 ? { fallbackPlacements } : undefined,
|
|
1117
1136
|
},
|
|
1118
1137
|
{
|
|
1119
1138
|
name: 'eventListeners',
|
|
@@ -9181,6 +9200,36 @@ let TableService = class TableService extends onekijsFramework.CollectionService
|
|
|
9181
9200
|
column.computedWidth = undefined;
|
|
9182
9201
|
});
|
|
9183
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
|
+
}
|
|
9184
9233
|
toggle(item) {
|
|
9185
9234
|
this.setMeta('item', item, 'expanded', !item.expanded);
|
|
9186
9235
|
}
|
|
@@ -10481,6 +10530,10 @@ const DefaultFormCellDisplayer = (props) => {
|
|
|
10481
10530
|
return null;
|
|
10482
10531
|
};
|
|
10483
10532
|
|
|
10533
|
+
const defaultCellSerializer = (data, column) => {
|
|
10534
|
+
return onekijsFramework.get(data, column.id, null);
|
|
10535
|
+
};
|
|
10536
|
+
|
|
10484
10537
|
const checkboxColumn = (id, options) => {
|
|
10485
10538
|
const Component = options.CellComponent || CheckboxCellComponent;
|
|
10486
10539
|
return Object.assign({
|
|
@@ -10488,6 +10541,7 @@ const checkboxColumn = (id, options) => {
|
|
|
10488
10541
|
sortable: false,
|
|
10489
10542
|
className: 'o-checkbox-cell',
|
|
10490
10543
|
Displayer: DefaultFormCellDisplayer,
|
|
10544
|
+
serializer: defaultCellSerializer,
|
|
10491
10545
|
}, options, {
|
|
10492
10546
|
id,
|
|
10493
10547
|
CellComponent: Component(options),
|
|
@@ -10540,12 +10594,28 @@ const TableSelectFilterComponent = ({ column, dataSource, }) => {
|
|
|
10540
10594
|
TableSelectFilterComponent.displayName = 'TableInputFilterComponent';
|
|
10541
10595
|
|
|
10542
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
|
+
};
|
|
10543
10612
|
return Object.assign({
|
|
10544
10613
|
CellComponent: DefaultCellComponent,
|
|
10545
10614
|
filterable: true,
|
|
10546
10615
|
FilterComponent: (props) => (React.createElement(TableSelectFilterComponent, { ...props, dataSource: options.filterDataSource })),
|
|
10547
10616
|
sortable: true,
|
|
10548
10617
|
Displayer: DefaultFormCellDisplayer,
|
|
10618
|
+
serializer,
|
|
10549
10619
|
}, options, {
|
|
10550
10620
|
id,
|
|
10551
10621
|
});
|
|
@@ -10569,6 +10639,7 @@ const inputColumn = (id, options) => {
|
|
|
10569
10639
|
filterable: false,
|
|
10570
10640
|
sortable: false,
|
|
10571
10641
|
Displayer: DefaultFormCellDisplayer,
|
|
10642
|
+
serializer: defaultCellSerializer,
|
|
10572
10643
|
}, options, {
|
|
10573
10644
|
id,
|
|
10574
10645
|
CellComponent: Component(options),
|
|
@@ -10592,6 +10663,7 @@ const textColumn = (id, options) => {
|
|
|
10592
10663
|
FilterComponent: TableTextFilterComponent,
|
|
10593
10664
|
sortable: true,
|
|
10594
10665
|
Displayer: DefaultFormCellDisplayer,
|
|
10666
|
+
serializer: defaultCellSerializer,
|
|
10595
10667
|
}, options, {
|
|
10596
10668
|
id,
|
|
10597
10669
|
});
|
|
@@ -10623,6 +10695,7 @@ const numberColumn = (id, options) => {
|
|
|
10623
10695
|
FilterComponent: TableNumberFilterComponent,
|
|
10624
10696
|
sortable: true,
|
|
10625
10697
|
Displayer: DefaultFormCellDisplayer,
|
|
10698
|
+
serializer: defaultCellSerializer,
|
|
10626
10699
|
}, options, {
|
|
10627
10700
|
id,
|
|
10628
10701
|
});
|
|
@@ -10662,12 +10735,30 @@ const selectColumn = (id, options) => {
|
|
|
10662
10735
|
};
|
|
10663
10736
|
opts.adapter = adapter;
|
|
10664
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
|
+
};
|
|
10665
10755
|
const broker = new DefaultSelectBroker(dataSource, opts);
|
|
10666
10756
|
const Component = opts.CellComponent || SelectCellComponent;
|
|
10667
10757
|
return Object.assign({
|
|
10668
10758
|
filterable: false,
|
|
10669
10759
|
sortable: false,
|
|
10670
10760
|
Displayer: DefaultFormCellDisplayer,
|
|
10761
|
+
serializer,
|
|
10671
10762
|
}, opts, {
|
|
10672
10763
|
id,
|
|
10673
10764
|
CellComponent: Component(opts, broker),
|
|
@@ -10819,6 +10910,7 @@ const textareaColumn = (id, options) => {
|
|
|
10819
10910
|
filterable: false,
|
|
10820
10911
|
sortable: false,
|
|
10821
10912
|
Displayer: DefaultFormCellDisplayer,
|
|
10913
|
+
serializer: defaultCellSerializer,
|
|
10822
10914
|
}, options, {
|
|
10823
10915
|
id,
|
|
10824
10916
|
CellComponent: Component(options),
|
|
@@ -12610,6 +12702,7 @@ exports.cssProperty = cssProperty;
|
|
|
12610
12702
|
exports.cursor = cursor;
|
|
12611
12703
|
exports.darken = darken;
|
|
12612
12704
|
exports.dashboardOverlayStyle = dashboardOverlayStyle;
|
|
12705
|
+
exports.defaultCellSerializer = defaultCellSerializer;
|
|
12613
12706
|
exports.defaultTreeQueryEngine = defaultTreeQueryEngine;
|
|
12614
12707
|
exports.deriveColor = deriveColor;
|
|
12615
12708
|
exports.display = display;
|
|
@@ -12618,6 +12711,7 @@ exports.dropdownStyle = dropdownStyle;
|
|
|
12618
12711
|
exports.emptyCells = emptyCells;
|
|
12619
12712
|
exports.enumColumn = enumColumn;
|
|
12620
12713
|
exports.enumFormatter = enumFormatter;
|
|
12714
|
+
exports.escapeCsvValue = escapeCsvValue;
|
|
12621
12715
|
exports.fieldDescriptionStyle = fieldDescriptionStyle;
|
|
12622
12716
|
exports.fieldDisplayerStyle = fieldDisplayerStyle;
|
|
12623
12717
|
exports.fieldHelpStyle = fieldHelpStyle;
|