@perspective-dev/viewer-datagrid 4.0.1 → 4.1.1
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/cdn/perspective-viewer-datagrid.js +4 -17
- package/dist/cdn/perspective-viewer-datagrid.js.map +4 -4
- package/dist/css/perspective-viewer-datagrid.css +1 -1
- package/dist/esm/color_utils.d.ts +9 -0
- package/dist/esm/custom_elements/datagrid.d.ts +52 -0
- package/dist/esm/custom_elements/toolbar.d.ts +10 -0
- package/dist/esm/data_listener/format_cell.d.ts +8 -0
- package/dist/esm/data_listener/format_tree_header.d.ts +13 -0
- package/dist/esm/data_listener/formatter_cache.d.ts +16 -0
- package/dist/esm/data_listener/index.d.ts +10 -0
- package/dist/esm/event_handlers/click/edit_click.d.ts +3 -0
- package/dist/esm/event_handlers/click.d.ts +7 -0
- package/dist/esm/event_handlers/deselect_all.d.ts +5 -0
- package/dist/esm/event_handlers/dispatch_click.d.ts +3 -0
- package/dist/esm/event_handlers/expand_collapse.d.ts +2 -0
- package/dist/esm/event_handlers/focus.d.ts +5 -0
- package/dist/esm/event_handlers/header_click.d.ts +3 -0
- package/dist/esm/event_handlers/keydown/edit_keydown.d.ts +4 -0
- package/dist/esm/event_handlers/row_select_click.d.ts +4 -0
- package/dist/esm/event_handlers/select_region.d.ts +9 -0
- package/dist/esm/event_handlers/sort.d.ts +7 -0
- package/dist/esm/get_cell_config.d.ts +8 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/model/column_overrides.d.ts +23 -0
- package/dist/esm/model/create.d.ts +3 -0
- package/dist/esm/model/index.d.ts +4 -0
- package/dist/esm/model/toolbar.d.ts +4 -0
- package/dist/esm/perspective-viewer-datagrid.js +3 -3
- package/dist/esm/perspective-viewer-datagrid.js.map +4 -4
- package/dist/esm/plugin/activate.d.ts +6 -0
- package/dist/esm/plugin/column_style_controls.d.ts +28 -0
- package/dist/esm/plugin/draw.d.ts +7 -0
- package/dist/esm/plugin/restore.d.ts +10 -0
- package/dist/esm/plugin/save.d.ts +2 -0
- package/dist/esm/style_handlers/body.d.ts +7 -0
- package/dist/esm/style_handlers/column_header.d.ts +13 -0
- package/dist/esm/style_handlers/consolidated.d.ts +57 -0
- package/dist/esm/style_handlers/editable.d.ts +7 -0
- package/dist/esm/style_handlers/focus.d.ts +16 -0
- package/dist/esm/style_handlers/group_header.d.ts +7 -0
- package/dist/esm/style_handlers/table_cell/boolean.d.ts +7 -0
- package/dist/esm/style_handlers/table_cell/cell_flash.d.ts +3 -0
- package/dist/esm/style_handlers/table_cell/datetime.d.ts +7 -0
- package/dist/esm/style_handlers/table_cell/numeric.d.ts +15 -0
- package/dist/esm/style_handlers/table_cell/row_header.d.ts +4 -0
- package/dist/esm/style_handlers/table_cell/string.d.ts +11 -0
- package/dist/esm/style_handlers/types.d.ts +20 -0
- package/dist/esm/types.d.ts +193 -0
- package/package.json +10 -5
- package/src/less/mitered-headers.less +65 -0
- package/src/less/pro.less +196 -0
- package/src/less/regular_table.less +509 -0
- package/src/less/row-hover.less +88 -0
- package/{index.d.ts → src/less/scrollbar.less} +18 -19
- package/src/less/sub-cell-scroll.less +82 -0
- package/src/less/toolbar.less +201 -0
- package/src/ts/color_utils.ts +70 -0
- package/src/ts/custom_elements/datagrid.ts +250 -0
- package/src/ts/custom_elements/toolbar.ts +75 -0
- package/src/ts/data_listener/format_cell.ts +84 -0
- package/src/ts/data_listener/format_tree_header.ts +82 -0
- package/src/ts/data_listener/formatter_cache.ts +191 -0
- package/src/ts/data_listener/index.ts +242 -0
- package/src/ts/event_handlers/click/edit_click.ts +73 -0
- package/src/ts/event_handlers/click.ts +92 -0
- package/src/ts/event_handlers/deselect_all.ts +28 -0
- package/src/ts/event_handlers/dispatch_click.ts +44 -0
- package/src/ts/event_handlers/expand_collapse.ts +44 -0
- package/src/ts/event_handlers/focus.ts +63 -0
- package/src/ts/event_handlers/header_click.ts +85 -0
- package/src/ts/event_handlers/keydown/edit_keydown.ts +213 -0
- package/src/ts/event_handlers/row_select_click.ts +87 -0
- package/src/ts/event_handlers/select_region.ts +427 -0
- package/src/ts/event_handlers/sort.ts +118 -0
- package/src/ts/get_cell_config.ts +68 -0
- package/src/ts/index.ts +49 -0
- package/src/ts/model/column_overrides.ts +112 -0
- package/src/ts/model/create.ts +247 -0
- package/src/ts/model/index.ts +19 -0
- package/src/ts/model/toolbar.ts +64 -0
- package/src/ts/plugin/activate.ts +235 -0
- package/src/ts/plugin/column_style_controls.ts +76 -0
- package/src/ts/plugin/draw.ts +69 -0
- package/src/ts/plugin/restore.ts +110 -0
- package/src/ts/plugin/save.ts +45 -0
- package/src/ts/style_handlers/body.ts +228 -0
- package/src/ts/style_handlers/column_header.ts +183 -0
- package/src/ts/style_handlers/consolidated.ts +223 -0
- package/src/ts/style_handlers/editable.ts +94 -0
- package/src/ts/style_handlers/focus.ts +106 -0
- package/src/ts/style_handlers/group_header.ts +78 -0
- package/src/ts/style_handlers/table_cell/boolean.ts +39 -0
- package/src/ts/style_handlers/table_cell/cell_flash.ts +75 -0
- package/src/ts/style_handlers/table_cell/datetime.ts +64 -0
- package/src/ts/style_handlers/table_cell/numeric.ts +186 -0
- package/src/ts/style_handlers/table_cell/row_header.ts +53 -0
- package/src/ts/style_handlers/table_cell/string.ts +102 -0
- package/src/ts/style_handlers/types.ts +41 -0
- package/src/ts/types.ts +279 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
import { PRIVATE_PLUGIN_SYMBOL } from "../types.js";
|
|
14
|
+
import { format_cell } from "./format_cell.js";
|
|
15
|
+
import {
|
|
16
|
+
format_tree_header,
|
|
17
|
+
format_tree_header_row_path,
|
|
18
|
+
} from "./format_tree_header.js";
|
|
19
|
+
import type {
|
|
20
|
+
DatagridModel,
|
|
21
|
+
PerspectiveViewerElement,
|
|
22
|
+
RegularTable,
|
|
23
|
+
Schema,
|
|
24
|
+
} from "../types.js";
|
|
25
|
+
import type { CellScalar, DataResponse } from "regular-table/dist/esm/types.js";
|
|
26
|
+
import { ViewWindow } from "@perspective-dev/client";
|
|
27
|
+
|
|
28
|
+
interface ColumnData {
|
|
29
|
+
__ROW_PATH__?: unknown[][];
|
|
30
|
+
__ID__?: unknown[][];
|
|
31
|
+
[key: string]: unknown[] | undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Creates a new DataListener, suitable for passing to `regular-table`'s
|
|
36
|
+
* `.setDataListener()` method. This should be called as a method on the
|
|
37
|
+
* plugin.
|
|
38
|
+
*
|
|
39
|
+
* @returns A data listener for the plugin.
|
|
40
|
+
*/
|
|
41
|
+
export function createDataListener(
|
|
42
|
+
viewer: PerspectiveViewerElement,
|
|
43
|
+
): (
|
|
44
|
+
regularTable: RegularTable,
|
|
45
|
+
x0: number,
|
|
46
|
+
y0: number,
|
|
47
|
+
x1: number,
|
|
48
|
+
y1: number,
|
|
49
|
+
) => Promise<DataResponse> {
|
|
50
|
+
let last_meta: unknown[][] | undefined;
|
|
51
|
+
let last_column_paths: string[] | undefined;
|
|
52
|
+
let last_ids: unknown[][] | undefined;
|
|
53
|
+
let last_reverse_ids: Map<string, number> | undefined;
|
|
54
|
+
let last_reverse_columns: Map<string, number> | undefined;
|
|
55
|
+
|
|
56
|
+
return async function dataListener(
|
|
57
|
+
this: DatagridModel,
|
|
58
|
+
regularTable: RegularTable,
|
|
59
|
+
x0: number,
|
|
60
|
+
y0: number,
|
|
61
|
+
x1: number,
|
|
62
|
+
y1: number,
|
|
63
|
+
): Promise<DataResponse> {
|
|
64
|
+
let columns: ColumnData = {};
|
|
65
|
+
const new_window: ViewWindow = {
|
|
66
|
+
start_row: y0,
|
|
67
|
+
start_col: x0,
|
|
68
|
+
end_row: y1,
|
|
69
|
+
end_col: x1,
|
|
70
|
+
id: true,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
let num_columns: number | null = null;
|
|
74
|
+
|
|
75
|
+
if (x1 - x0 > 0 && y1 - y0 > 0) {
|
|
76
|
+
this._is_old_viewport =
|
|
77
|
+
this._last_window?.start_row === y0 &&
|
|
78
|
+
this._last_window?.end_row === y1 &&
|
|
79
|
+
this._last_window?.start_col === x0 &&
|
|
80
|
+
this._last_window?.end_col === x1;
|
|
81
|
+
|
|
82
|
+
const [x, z] = await Promise.all([
|
|
83
|
+
this._view.to_columns_string(new_window as any),
|
|
84
|
+
this._view.num_columns(),
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
num_columns = z;
|
|
88
|
+
columns = JSON.parse(x as string) as ColumnData;
|
|
89
|
+
const y = Object.keys(columns);
|
|
90
|
+
const new_col_paths = y.filter(
|
|
91
|
+
(x) => x !== "__ROW_PATH__" && x !== "__ID__",
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
let changed_cols = false;
|
|
95
|
+
for (let i = 0; i < new_col_paths.length; i++) {
|
|
96
|
+
if (
|
|
97
|
+
this._column_paths[new_window.start_col! + i] !==
|
|
98
|
+
new_col_paths[i]
|
|
99
|
+
) {
|
|
100
|
+
changed_cols = true;
|
|
101
|
+
this._column_paths[new_window.start_col! + i] =
|
|
102
|
+
new_col_paths[i];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (changed_cols) {
|
|
107
|
+
const [a, b] = await Promise.all([
|
|
108
|
+
this._view.schema(),
|
|
109
|
+
this._view.expression_schema(),
|
|
110
|
+
]);
|
|
111
|
+
|
|
112
|
+
this._schema = { ...(a as Schema), ...(b as Schema) };
|
|
113
|
+
for (let i = 0; i < new_col_paths.length; i++) {
|
|
114
|
+
const column_path_parts = new_col_paths[i].split("|");
|
|
115
|
+
const column =
|
|
116
|
+
column_path_parts[this._config.split_by.length];
|
|
117
|
+
|
|
118
|
+
this._is_editable[i + new_window.start_col!] =
|
|
119
|
+
!!this._table_schema[column];
|
|
120
|
+
|
|
121
|
+
this._column_types[i + new_window.start_col!] =
|
|
122
|
+
this._schema[column];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this._last_window = new_window;
|
|
127
|
+
this._ids =
|
|
128
|
+
columns.__ID__ ||
|
|
129
|
+
Array(y1 - y0)
|
|
130
|
+
.fill(null)
|
|
131
|
+
.map((_, index) => [index + y0]);
|
|
132
|
+
|
|
133
|
+
this._reverse_columns = this._column_paths
|
|
134
|
+
.slice(x0, x1)
|
|
135
|
+
.reduce((acc, x, i) => {
|
|
136
|
+
acc.set(x, i);
|
|
137
|
+
return acc;
|
|
138
|
+
}, new Map<string, number>());
|
|
139
|
+
|
|
140
|
+
this._reverse_ids = this._ids?.reduce((acc, x, i) => {
|
|
141
|
+
acc.set(x?.join("|"), i);
|
|
142
|
+
return acc;
|
|
143
|
+
}, new Map<string, number>());
|
|
144
|
+
} else {
|
|
145
|
+
this._div_factory.clear();
|
|
146
|
+
num_columns = await this._view.num_columns();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const data: (string | HTMLElement)[][] = [];
|
|
150
|
+
const metadata: unknown[][] = [];
|
|
151
|
+
const column_headers: string[][] = [];
|
|
152
|
+
const column_paths: string[] = [];
|
|
153
|
+
|
|
154
|
+
const is_settings_open = viewer.hasAttribute("settings");
|
|
155
|
+
for (
|
|
156
|
+
let ipath = x0;
|
|
157
|
+
ipath < Math.min(x1, this._column_paths.length);
|
|
158
|
+
++ipath
|
|
159
|
+
) {
|
|
160
|
+
const path = this._column_paths[ipath];
|
|
161
|
+
const path_parts = path.split("|");
|
|
162
|
+
const column = columns[path] || new Array(y1 - y0).fill(null);
|
|
163
|
+
const agg_depth = Math.min(
|
|
164
|
+
(regularTable as any)[PRIVATE_PLUGIN_SYMBOL]?.[
|
|
165
|
+
path_parts[this._config.split_by.length]
|
|
166
|
+
]?.aggregate_depth || 0,
|
|
167
|
+
this._config.group_by.length,
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
data.push(
|
|
171
|
+
column.map((x, i) => {
|
|
172
|
+
if ((columns?.__ROW_PATH__?.[i]?.length ?? 0) < agg_depth) {
|
|
173
|
+
return "";
|
|
174
|
+
} else {
|
|
175
|
+
return format_cell.call(
|
|
176
|
+
this,
|
|
177
|
+
path_parts[this._config.split_by.length],
|
|
178
|
+
x,
|
|
179
|
+
(regularTable as any)[PRIVATE_PLUGIN_SYMBOL] || {},
|
|
180
|
+
) as string | HTMLElement;
|
|
181
|
+
}
|
|
182
|
+
}),
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
metadata.push(column as unknown[]);
|
|
186
|
+
if (is_settings_open) {
|
|
187
|
+
path_parts.push("");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
column_headers.push(path_parts);
|
|
191
|
+
column_paths.push(path);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Only update the last state if this is not a "phantom" call.
|
|
195
|
+
if (x1 - x0 > 0 && y1 - y0 > 0) {
|
|
196
|
+
this.last_column_paths = last_column_paths;
|
|
197
|
+
this.last_meta = last_meta;
|
|
198
|
+
this.last_ids = last_ids;
|
|
199
|
+
this.last_reverse_ids = last_reverse_ids;
|
|
200
|
+
this.last_reverse_columns = last_reverse_columns;
|
|
201
|
+
|
|
202
|
+
last_column_paths = column_paths;
|
|
203
|
+
last_meta = metadata;
|
|
204
|
+
last_ids = this._ids;
|
|
205
|
+
last_reverse_ids = this._reverse_ids;
|
|
206
|
+
last_reverse_columns = this._reverse_columns;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const is_row_path = columns.__ROW_PATH__ !== undefined;
|
|
210
|
+
const row_headers = Array.from(
|
|
211
|
+
(is_row_path
|
|
212
|
+
? format_tree_header_row_path
|
|
213
|
+
: format_tree_header
|
|
214
|
+
).call(
|
|
215
|
+
this,
|
|
216
|
+
columns.__ROW_PATH__,
|
|
217
|
+
this._config.group_by,
|
|
218
|
+
regularTable,
|
|
219
|
+
),
|
|
220
|
+
) as (string | HTMLElement)[][];
|
|
221
|
+
|
|
222
|
+
const num_row_headers = row_headers[0]?.length;
|
|
223
|
+
|
|
224
|
+
const result: DataResponse = {
|
|
225
|
+
num_column_headers:
|
|
226
|
+
this._config.split_by.length + (is_settings_open ? 2 : 1),
|
|
227
|
+
num_row_headers,
|
|
228
|
+
num_rows: this._num_rows,
|
|
229
|
+
num_columns,
|
|
230
|
+
row_headers: row_headers as CellScalar[][], // Add `HTMLElement`
|
|
231
|
+
column_headers,
|
|
232
|
+
data: data as CellScalar[][],
|
|
233
|
+
metadata,
|
|
234
|
+
column_header_merge_depth: Math.max(
|
|
235
|
+
0,
|
|
236
|
+
this._config.split_by.length,
|
|
237
|
+
),
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
return result;
|
|
241
|
+
};
|
|
242
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
import type {
|
|
14
|
+
RegularTable,
|
|
15
|
+
DatagridModel,
|
|
16
|
+
PerspectiveViewerElement,
|
|
17
|
+
} from "../../types.js";
|
|
18
|
+
|
|
19
|
+
export function write_cell(
|
|
20
|
+
table: RegularTable,
|
|
21
|
+
model: DatagridModel,
|
|
22
|
+
active_cell: HTMLElement,
|
|
23
|
+
): boolean {
|
|
24
|
+
const meta = table.getMeta(active_cell);
|
|
25
|
+
if (!meta) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const type = model._schema[model._column_paths[meta.x]];
|
|
29
|
+
let text: string | number | boolean | null = active_cell.textContent || "";
|
|
30
|
+
const id = model._ids[meta.y - meta.y0][0];
|
|
31
|
+
if (type === "float" || type === "integer") {
|
|
32
|
+
const parsed = parseFloat(text.replace(/,/g, ""));
|
|
33
|
+
if (isNaN(parsed)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
text = parsed;
|
|
37
|
+
} else if (type === "date" || type === "datetime") {
|
|
38
|
+
const parsed = Date.parse(text);
|
|
39
|
+
if (isNaN(parsed)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
text = parsed;
|
|
43
|
+
} else if (type === "boolean") {
|
|
44
|
+
text = text === "true" ? false : text === "false" ? true : null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const msg = {
|
|
48
|
+
__INDEX__: id,
|
|
49
|
+
[model._column_paths[meta.x]]: text,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
model._table.update([msg], { port_id: model._edit_port, format: null });
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function clickListener(
|
|
57
|
+
this: DatagridModel,
|
|
58
|
+
table: RegularTable,
|
|
59
|
+
_viewer: PerspectiveViewerElement,
|
|
60
|
+
event: MouseEvent,
|
|
61
|
+
): void {
|
|
62
|
+
const meta = table.getMeta(event.target as Element);
|
|
63
|
+
if (typeof meta?.x !== "undefined") {
|
|
64
|
+
const is_editable2 = this._is_editable[meta.x];
|
|
65
|
+
const is_bool = this.get_psp_type(meta) === "boolean";
|
|
66
|
+
const is_null = (event.target as Element).classList.contains(
|
|
67
|
+
"psp-null",
|
|
68
|
+
);
|
|
69
|
+
if (is_editable2 && is_bool && !is_null) {
|
|
70
|
+
write_cell(table, this, event.target as HTMLElement);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
import * as edit_click from "./click/edit_click.js";
|
|
14
|
+
import * as edit_keydown from "./keydown/edit_keydown.js";
|
|
15
|
+
import type {
|
|
16
|
+
DatagridModel,
|
|
17
|
+
PerspectiveViewerElement,
|
|
18
|
+
SelectedPosition,
|
|
19
|
+
} from "../types.js";
|
|
20
|
+
import { RegularTableElement } from "regular-table";
|
|
21
|
+
import { HTMLPerspectiveViewerDatagridPluginElement } from "../custom_elements/datagrid.js";
|
|
22
|
+
|
|
23
|
+
type SelectedPositionMap = Map<RegularTableElement, SelectedPosition>;
|
|
24
|
+
|
|
25
|
+
export function is_editable(
|
|
26
|
+
this: DatagridModel,
|
|
27
|
+
viewer: PerspectiveViewerElement,
|
|
28
|
+
allowed: boolean = false,
|
|
29
|
+
): boolean {
|
|
30
|
+
const has_pivots =
|
|
31
|
+
this._config.group_by.length === 0 &&
|
|
32
|
+
this._config.split_by.length === 0;
|
|
33
|
+
const selectable = viewer.hasAttribute("selectable");
|
|
34
|
+
const plugin = viewer.children[0] as
|
|
35
|
+
| HTMLPerspectiveViewerDatagridPluginElement
|
|
36
|
+
| undefined;
|
|
37
|
+
const editable = allowed || !!(plugin?._edit_mode === "EDIT");
|
|
38
|
+
return has_pivots && !selectable && editable;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function keydownListener(
|
|
42
|
+
this: DatagridModel,
|
|
43
|
+
table: RegularTableElement,
|
|
44
|
+
viewer: PerspectiveViewerElement,
|
|
45
|
+
selected_position_map: SelectedPositionMap,
|
|
46
|
+
event: KeyboardEvent,
|
|
47
|
+
): void {
|
|
48
|
+
if (this._edit_mode === "EDIT") {
|
|
49
|
+
if (!is_editable.call(this, viewer)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
edit_keydown.keydownListener.call(
|
|
54
|
+
this,
|
|
55
|
+
table,
|
|
56
|
+
viewer,
|
|
57
|
+
selected_position_map,
|
|
58
|
+
event,
|
|
59
|
+
);
|
|
60
|
+
} else {
|
|
61
|
+
console.debug(
|
|
62
|
+
`Mode ${this._edit_mode} for "keydown" event not yet implemented`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function clickListener(
|
|
68
|
+
this: DatagridModel,
|
|
69
|
+
table: RegularTableElement,
|
|
70
|
+
viewer: PerspectiveViewerElement,
|
|
71
|
+
event: MouseEvent,
|
|
72
|
+
): void {
|
|
73
|
+
if (this._edit_mode === "EDIT") {
|
|
74
|
+
if (!is_editable.call(this, viewer)) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
edit_click.clickListener.call(this, table, viewer, event);
|
|
79
|
+
} else if (this._edit_mode === "READ_ONLY") {
|
|
80
|
+
// No-op for read-only mode
|
|
81
|
+
} else if (this._edit_mode === "SELECT_COLUMN") {
|
|
82
|
+
// Not yet implemented
|
|
83
|
+
} else if (this._edit_mode === "SELECT_ROW") {
|
|
84
|
+
// Not yet implemented
|
|
85
|
+
} else if (this._edit_mode === "SELECT_REGION") {
|
|
86
|
+
// Not yet implemented
|
|
87
|
+
} else {
|
|
88
|
+
console.debug(
|
|
89
|
+
`Mode ${this._edit_mode} for "click" event not yet implemented`,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
import { RegularTableElement } from "regular-table";
|
|
14
|
+
import type { PerspectiveViewerElement } from "../types.js";
|
|
15
|
+
|
|
16
|
+
type SelectedRowsMap = Map<RegularTableElement, unknown[]>;
|
|
17
|
+
|
|
18
|
+
export async function deselect_all_listener(
|
|
19
|
+
regularTable: RegularTableElement,
|
|
20
|
+
_viewer: PerspectiveViewerElement,
|
|
21
|
+
selected_rows_map: SelectedRowsMap,
|
|
22
|
+
): Promise<void> {
|
|
23
|
+
selected_rows_map.delete(regularTable);
|
|
24
|
+
for (const td of regularTable.querySelectorAll("td,th")) {
|
|
25
|
+
td.classList.toggle("psp-row-selected", false);
|
|
26
|
+
td.classList.toggle("psp-row-subselected", false);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
import { RegularTableElement } from "regular-table";
|
|
14
|
+
import getCellConfig from "../get_cell_config.js";
|
|
15
|
+
import type {
|
|
16
|
+
DatagridModel,
|
|
17
|
+
PerspectiveViewerElement,
|
|
18
|
+
PerspectiveClickDetail,
|
|
19
|
+
} from "../types.js";
|
|
20
|
+
|
|
21
|
+
export async function dispatch_click_listener(
|
|
22
|
+
this: DatagridModel,
|
|
23
|
+
table: RegularTableElement,
|
|
24
|
+
viewer: PerspectiveViewerElement,
|
|
25
|
+
event: MouseEvent,
|
|
26
|
+
): Promise<void> {
|
|
27
|
+
const meta = table.getMeta(event.target as Element);
|
|
28
|
+
if (!meta) return;
|
|
29
|
+
const { x, y } = meta;
|
|
30
|
+
|
|
31
|
+
const { row, column_names, config } = await getCellConfig(this, y, x);
|
|
32
|
+
|
|
33
|
+
viewer.dispatchEvent(
|
|
34
|
+
new CustomEvent<PerspectiveClickDetail>("perspective-click", {
|
|
35
|
+
bubbles: true,
|
|
36
|
+
composed: true,
|
|
37
|
+
detail: {
|
|
38
|
+
row,
|
|
39
|
+
column_names,
|
|
40
|
+
config,
|
|
41
|
+
},
|
|
42
|
+
}),
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
import type { RegularTable, DatagridModel } from "../types.js";
|
|
14
|
+
|
|
15
|
+
export async function expandCollapseHandler(
|
|
16
|
+
this: DatagridModel,
|
|
17
|
+
regularTable: RegularTable,
|
|
18
|
+
event: MouseEvent,
|
|
19
|
+
): Promise<void> {
|
|
20
|
+
const meta = regularTable.getMeta(event.target as Element);
|
|
21
|
+
if (!meta?.row_header) return;
|
|
22
|
+
|
|
23
|
+
const is_collapse = (event.target as Element).classList.contains(
|
|
24
|
+
"psp-tree-label-collapse",
|
|
25
|
+
);
|
|
26
|
+
if (event.shiftKey && is_collapse) {
|
|
27
|
+
this._view.set_depth(
|
|
28
|
+
(meta.row_header as unknown[]).filter((x) => x !== undefined)
|
|
29
|
+
.length - 2,
|
|
30
|
+
);
|
|
31
|
+
} else if (event.shiftKey) {
|
|
32
|
+
this._view.set_depth(
|
|
33
|
+
(meta.row_header as unknown[]).filter((x) => x !== undefined)
|
|
34
|
+
.length - 1,
|
|
35
|
+
);
|
|
36
|
+
} else if (is_collapse) {
|
|
37
|
+
this._view.collapse(meta.y);
|
|
38
|
+
} else {
|
|
39
|
+
this._view.expand(meta.y);
|
|
40
|
+
}
|
|
41
|
+
this._num_rows = await this._view.num_rows();
|
|
42
|
+
this._num_columns = await this._view.num_columns();
|
|
43
|
+
regularTable.draw();
|
|
44
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
2
|
+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
|
|
3
|
+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
|
|
4
|
+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
|
|
5
|
+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
|
|
6
|
+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
|
|
7
|
+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
|
|
8
|
+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
|
|
9
|
+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
|
|
10
|
+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
|
+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
|
+
|
|
13
|
+
import { is_editable } from "./click.js";
|
|
14
|
+
import { write_cell } from "./click/edit_click.js";
|
|
15
|
+
import type {
|
|
16
|
+
RegularTable,
|
|
17
|
+
DatagridModel,
|
|
18
|
+
PerspectiveViewerElement,
|
|
19
|
+
SelectedPosition,
|
|
20
|
+
} from "../types.js";
|
|
21
|
+
|
|
22
|
+
type SelectedPositionMap = Map<RegularTable, SelectedPosition>;
|
|
23
|
+
|
|
24
|
+
export function focusoutListener(
|
|
25
|
+
this: DatagridModel,
|
|
26
|
+
table: RegularTable,
|
|
27
|
+
viewer: PerspectiveViewerElement,
|
|
28
|
+
selected_position_map: SelectedPositionMap,
|
|
29
|
+
event: FocusEvent,
|
|
30
|
+
): void {
|
|
31
|
+
if (is_editable.call(this, viewer) && selected_position_map.has(table)) {
|
|
32
|
+
const target = event.target as HTMLElement;
|
|
33
|
+
target.classList.remove("psp-error");
|
|
34
|
+
const selectedPosition = selected_position_map.get(table)!;
|
|
35
|
+
selected_position_map.delete(table);
|
|
36
|
+
if (selectedPosition.content !== target.textContent) {
|
|
37
|
+
if (!write_cell(table, this, target)) {
|
|
38
|
+
target.textContent = selectedPosition.content || "";
|
|
39
|
+
target.classList.add("psp-error");
|
|
40
|
+
target.focus();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function focusinListener(
|
|
47
|
+
this: DatagridModel,
|
|
48
|
+
table: RegularTable,
|
|
49
|
+
_viewer: PerspectiveViewerElement,
|
|
50
|
+
selected_position_map: SelectedPositionMap,
|
|
51
|
+
event: FocusEvent,
|
|
52
|
+
): void {
|
|
53
|
+
const target = event.target as HTMLElement;
|
|
54
|
+
const meta = table.getMeta(target);
|
|
55
|
+
if (meta) {
|
|
56
|
+
const new_state: SelectedPosition = {
|
|
57
|
+
x: meta.x,
|
|
58
|
+
y: meta.y,
|
|
59
|
+
content: target.textContent || undefined,
|
|
60
|
+
};
|
|
61
|
+
selected_position_map.set(table, new_state);
|
|
62
|
+
}
|
|
63
|
+
}
|