@iyulab/flex-table 0.58.0 → 0.60.0
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/CHANGELOG.md +39 -0
- package/README.md +28 -6
- package/dist/array/index.d.ts +3 -0
- package/dist/array/index.js +46 -38
- package/dist/array/source.d.ts +3 -0
- package/dist/array/types.d.ts +3 -0
- package/dist/array/view.d.ts +6 -0
- package/dist/core/fetch-all.d.ts +14 -0
- package/dist/core/source-error.d.ts +13 -1
- package/dist/events.d.ts +14 -4
- package/dist/fetch-all-J37bOtgc.js +86 -0
- package/dist/{flex-table-B1W8VEBa.js → flex-table-kM69-hSo.js} +157 -145
- package/dist/flex-table.d.ts +22 -9
- package/dist/flex-table.js +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/{locale-Cfm-vJji.js → locale-D9g0ksXq.js} +4 -2
- package/dist/locale.d.ts +1 -1
- package/dist/odata/index.d.ts +4 -0
- package/dist/odata/index.js +5 -5
- package/dist/odata/query.d.ts +7 -3
- package/dist/odata/source.d.ts +9 -0
- package/dist/odata/types.d.ts +3 -0
- package/dist/react.d.ts +2 -0
- package/dist/react.js +75 -62
- package/dist/source-DNPtWmC3.js +202 -0
- package/dist/{view-DiLr-TdY.js → view-BtoXdUGF.js} +13 -2
- package/package.json +2 -2
- package/skills/iyulab-flex-table/SKILL.md +2 -1
- package/skills/iyulab-flex-table/references/api.md +9 -5
- package/skills/iyulab-flex-table/references/react.md +2 -1
- package/dist/query-Dw4iO0ir.js +0 -37
- package/dist/source-DOue0Ti3.js +0 -223
|
@@ -131,9 +131,13 @@ Enter/Escape and blur-to-commit behavior.
|
|
|
131
131
|
| `setComment(dataIndex, colKey, text)` | `null` or `''` removes; undoable |
|
|
132
132
|
| `getComment(dataIndex, colKey)` / `clearComments()` | |
|
|
133
133
|
| `importFromFile(file)` | `Promise<void>`; `.xlsx`, `.csv`, `.tsv`; fires `data-import` |
|
|
134
|
-
| `exportToString(format, { selectionOnly? })` | `string \| Uint8Array`; format `'csv' \| 'tsv' \| 'json' \| 'xlsx'` (xlsx returns uncompressed bytes — synchronous) |
|
|
135
|
-
| `exportToBlob(format,
|
|
136
|
-
| `exportToFile(format, filename?)` | `Promise<void>` — triggers a download (xlsx compressed) |
|
|
134
|
+
| `exportToString(format, { selectionOnly? } \| { rows })` | `string \| Uint8Array`; format `'csv' \| 'tsv' \| 'json' \| 'xlsx'` (xlsx returns uncompressed bytes — synchronous). `rows`: export these rows with the visible columns |
|
|
135
|
+
| `exportToBlob(format, options?)` | `Promise<Blob>` typed with the format's MIME; xlsx is DEFLATE-compressed |
|
|
136
|
+
| `exportToFile(format, filename?, options?)` | `Promise<void>` — triggers a download (xlsx compressed) |
|
|
137
|
+
|
|
138
|
+
A server-paged table holds one page. Export the list's whole result with
|
|
139
|
+
`table.exportToFile('xlsx', 'x.xlsx', { rows: await source.fetchAll() })` — never the table's own rows there.
|
|
140
|
+
Table-less: `exportDataBlob(rows, columns, format)` + `downloadBlob(blob, name)` from the root entry.
|
|
137
141
|
|
|
138
142
|
## Events
|
|
139
143
|
|
|
@@ -143,14 +147,14 @@ cast, and the React `on*` props carry the same types.
|
|
|
143
147
|
|
|
144
148
|
| Event | `detail` |
|
|
145
149
|
|---|---|
|
|
146
|
-
| `cell-select` | `{ row, col }` (or `null`) |
|
|
150
|
+
| `cell-select` | `{ row, col, id }` (or `null`) — focus moved (also when the keyboard arrives); `row`/`col` visible positions |
|
|
147
151
|
| `cell-edit-start` | `{ row, col, key, value }` |
|
|
148
152
|
| `cell-edit-commit` | `{ row, col, key, oldValue, newValue }` |
|
|
149
153
|
| `cell-edit-cancel` | `{ row, col }` — `row`: data index (`-1` once the row left `data`) |
|
|
150
154
|
| `validation-error` | `{ row, col, key, value, error }` |
|
|
151
155
|
| `row-add` | `{ row, index }` |
|
|
152
156
|
| `row-delete` | `{ indices, rows }` |
|
|
153
|
-
| `row-activate` | `{ row, id, index, col, key }` — Enter on a non-editable cell |
|
|
157
|
+
| `row-activate` | `{ row, id, via, index, col, key }` — a plain click on a cell (`via: 'click'`) or Enter on a non-editable cell (`'keyboard'`); not a Shift/Ctrl/Cmd click, a drag, or a control in the cell |
|
|
154
158
|
| `row-reorder` | `{ from, to }` |
|
|
155
159
|
| `batch-update` | `{ changes }` |
|
|
156
160
|
| `column-add` | `{ column, index }` |
|
|
@@ -114,6 +114,7 @@ function Orders() {
|
|
|
114
114
|
| `sortCriteria`, `onSortChange` | Pass `onSortChange` to the table's `sort-change` (resets to page 0) |
|
|
115
115
|
| `search`, `setSearch` | Literal text (resets to page 0) |
|
|
116
116
|
| `refresh` | Re-run the current request |
|
|
117
|
+
| `fetchAll(options?)` | The whole result of the current sort/search/filter (no paging, follows `@odata.nextLink`) — for export. `maxRows` (default 100000) rejects with `RowLimitError` rather than cutting; `signal`, `onProgress` |
|
|
117
118
|
|
|
118
119
|
Search is literal: each whitespace-separated token becomes a quoted phrase joined with `AND`
|
|
119
120
|
(`red shirt` → `"red" AND "shirt"`); double quotes are stripped. If the result set shrinks below
|
|
@@ -159,7 +160,7 @@ Differences: `totalCount` is the count after search, `loading` is always `false`
|
|
|
159
160
|
|
|
160
161
|
`useODataSource` adapts a framework-neutral source with the same options and state:
|
|
161
162
|
`createODataSource(url, options)` → `getState()` · `subscribe(listener)` (the first subscriber starts loading, the last
|
|
162
|
-
unsubscribe cancels) · `setPage` · `setPageSize` · `setSort(criteria)` · `setSearch` · `refresh` · `update(url, options)`. Changes in one
|
|
163
|
+
unsubscribe cancels) · `setPage` · `setPageSize` · `setSort(criteria)` · `setSearch` · `refresh` · `update(url, options)` · `fetchAll(options?)`. Changes in one
|
|
163
164
|
tick become one request. For Lit, `ODataSourceController` subscribes on connect, cancels on disconnect and re-renders
|
|
164
165
|
the host — from a URL, or from a source you already have (`new ODataSourceController(this, source)`, so a table and a pager share it):
|
|
165
166
|
|
package/dist/query-Dw4iO0ir.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import e from "odata-query";
|
|
2
|
-
//#region src/odata/query.ts
|
|
3
|
-
function t(e) {
|
|
4
|
-
let t = e.split(/\s+/).map((e) => e.replace(/"/g, "")).filter((e) => e.length > 0);
|
|
5
|
-
if (t.length !== 0) return t.map((e) => `"${e}"`).join(" AND ");
|
|
6
|
-
}
|
|
7
|
-
function n(e) {
|
|
8
|
-
let { defaultOrderBy: t, initialPage: n = 0, initialSearch: i = "", initialSort: a } = e;
|
|
9
|
-
return {
|
|
10
|
-
page: n,
|
|
11
|
-
search: i,
|
|
12
|
-
sortCriteria: a ?? (t ? r(t) : [])
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
function r(e) {
|
|
16
|
-
return e.split(",").map((e) => {
|
|
17
|
-
let t = e.trim().split(/\s+/);
|
|
18
|
-
return {
|
|
19
|
-
key: t[0],
|
|
20
|
-
direction: t[1]?.toLowerCase() === "desc" ? "desc" : "asc"
|
|
21
|
-
};
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
function i(n) {
|
|
25
|
-
let { page: r, pageSize: i, sortCriteria: a = [], defaultOrderBy: o, search: s, fixedFilter: c } = n, l = a.length > 0 ? a.map((e) => `${e.key} ${e.direction}`).join(", ") : o, u = {
|
|
26
|
-
top: i,
|
|
27
|
-
skip: r * i,
|
|
28
|
-
count: !0
|
|
29
|
-
};
|
|
30
|
-
if (l && (u.orderBy = l), c && (u.filter = c), s) {
|
|
31
|
-
let e = t(s);
|
|
32
|
-
e && (u.search = e);
|
|
33
|
-
}
|
|
34
|
-
return e(u);
|
|
35
|
-
}
|
|
36
|
-
//#endregion
|
|
37
|
-
export { n as i, t as n, r, i as t };
|
package/dist/source-DOue0Ti3.js
DELETED
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
import { n as e } from "./locale-Cfm-vJji.js";
|
|
2
|
-
import { i as t, t as n } from "./query-Dw4iO0ir.js";
|
|
3
|
-
//#region src/core/source-error.ts
|
|
4
|
-
async function r(t) {
|
|
5
|
-
let n = await t.text().catch(() => ""), r = {
|
|
6
|
-
message: e("requestFailed", { status: t.status }),
|
|
7
|
-
status: t.status
|
|
8
|
-
};
|
|
9
|
-
if (!n) return r;
|
|
10
|
-
let a = n;
|
|
11
|
-
try {
|
|
12
|
-
a = JSON.parse(n);
|
|
13
|
-
} catch {}
|
|
14
|
-
if (r.body = a, !a || typeof a != "object") return r;
|
|
15
|
-
let o = a, s = o.error && typeof o.error == "object" ? o.error : o;
|
|
16
|
-
typeof s.message == "string" && s.message ? r.message = s.message : typeof o.message == "string" && o.message && (r.message = o.message), typeof s.code == "string" && s.code && (r.code = s.code);
|
|
17
|
-
let c = i(s.details);
|
|
18
|
-
return c && (r.details = c), r;
|
|
19
|
-
}
|
|
20
|
-
function i(e) {
|
|
21
|
-
if (!Array.isArray(e)) return;
|
|
22
|
-
let t = e.filter((e) => {
|
|
23
|
-
if (!e || typeof e != "object") return !1;
|
|
24
|
-
let t = e;
|
|
25
|
-
return typeof t.code == "string" && typeof t.message == "string";
|
|
26
|
-
});
|
|
27
|
-
return t.length > 0 ? t : void 0;
|
|
28
|
-
}
|
|
29
|
-
var a = class extends Error {
|
|
30
|
-
constructor(e) {
|
|
31
|
-
super(e.message), this.name = "SourceRequestError", this.failure = e;
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
function o(t) {
|
|
35
|
-
return new a({
|
|
36
|
-
message: e("networkFailed"),
|
|
37
|
-
cause: t
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
function s(e) {
|
|
41
|
-
return e instanceof a ? e.failure : e instanceof Error ? { message: e.message } : { message: String(e) };
|
|
42
|
-
}
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region src/odata/source.ts
|
|
45
|
-
function c(e, i = {}) {
|
|
46
|
-
let c = e, u = i, d = l(i.fixedFilter), f = t({
|
|
47
|
-
defaultOrderBy: i.defaultOrderBy,
|
|
48
|
-
initialPage: i.initialPage ?? 0,
|
|
49
|
-
initialSearch: i.initialSearch ?? "",
|
|
50
|
-
initialSort: i.initialSort
|
|
51
|
-
}), p = {
|
|
52
|
-
data: [],
|
|
53
|
-
totalCount: 0,
|
|
54
|
-
loading: !0,
|
|
55
|
-
error: null,
|
|
56
|
-
page: f.page,
|
|
57
|
-
pageSize: i.pageSize ?? 20,
|
|
58
|
-
sortCriteria: f.sortCriteria,
|
|
59
|
-
search: f.search
|
|
60
|
-
}, m = x(), h = /* @__PURE__ */ new Set(), g = null, _ = !1, v = null;
|
|
61
|
-
function y() {
|
|
62
|
-
return u.enabled ?? !0;
|
|
63
|
-
}
|
|
64
|
-
function b() {
|
|
65
|
-
return p.pageSize;
|
|
66
|
-
}
|
|
67
|
-
function x() {
|
|
68
|
-
return {
|
|
69
|
-
...p,
|
|
70
|
-
loading: p.loading || !y()
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
function S(e) {
|
|
74
|
-
p = {
|
|
75
|
-
...p,
|
|
76
|
-
...e
|
|
77
|
-
}, C();
|
|
78
|
-
}
|
|
79
|
-
function C() {
|
|
80
|
-
let e = x();
|
|
81
|
-
if (!Object.keys(e).every((t) => e[t] === m[t])) {
|
|
82
|
-
m = e;
|
|
83
|
-
for (let e of [...h]) e();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
function w() {
|
|
87
|
-
return JSON.stringify([
|
|
88
|
-
c,
|
|
89
|
-
u.baseUrl,
|
|
90
|
-
b(),
|
|
91
|
-
u.defaultOrderBy,
|
|
92
|
-
d,
|
|
93
|
-
p.page,
|
|
94
|
-
p.sortCriteria,
|
|
95
|
-
p.search
|
|
96
|
-
]);
|
|
97
|
-
}
|
|
98
|
-
function T() {
|
|
99
|
-
_ || (_ = !0, queueMicrotask(() => {
|
|
100
|
-
_ = !1, E();
|
|
101
|
-
}));
|
|
102
|
-
}
|
|
103
|
-
function E() {
|
|
104
|
-
if (h.size === 0) return;
|
|
105
|
-
if (!y()) {
|
|
106
|
-
g?.abort(), g = null, v = null, C();
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
let e = w();
|
|
110
|
-
e !== v && (v = e, D());
|
|
111
|
-
}
|
|
112
|
-
function D() {
|
|
113
|
-
g?.abort();
|
|
114
|
-
let e = new AbortController();
|
|
115
|
-
g = e;
|
|
116
|
-
let { page: t, sortCriteria: i, search: l } = p, d = b(), f = u.fetcher ?? fetch, m = u.onUnauthorized;
|
|
117
|
-
S({
|
|
118
|
-
loading: !0,
|
|
119
|
-
error: null
|
|
120
|
-
});
|
|
121
|
-
let h = n({
|
|
122
|
-
page: t,
|
|
123
|
-
pageSize: d,
|
|
124
|
-
sortCriteria: i,
|
|
125
|
-
defaultOrderBy: u.defaultOrderBy,
|
|
126
|
-
search: l,
|
|
127
|
-
fixedFilter: u.fixedFilter
|
|
128
|
-
}), _ = `${u.baseUrl ?? window.location.origin}${c}${h}`, v = async (t) => {
|
|
129
|
-
let n;
|
|
130
|
-
try {
|
|
131
|
-
n = await f(t, { signal: e.signal });
|
|
132
|
-
} catch (e) {
|
|
133
|
-
throw e?.name === "AbortError" ? e : o(e);
|
|
134
|
-
}
|
|
135
|
-
if (!n.ok) throw n.status === 401 && m && m(n), new a(await r(n));
|
|
136
|
-
return n.json();
|
|
137
|
-
};
|
|
138
|
-
(async () => {
|
|
139
|
-
let e = await v(_), t = [...e.value ?? e], n = new URL(_).origin, r = /* @__PURE__ */ new Set([_]), i = _, a = e["@odata.nextLink"];
|
|
140
|
-
for (; typeof a == "string" && a && t.length < d;) {
|
|
141
|
-
let e = new URL(a, i);
|
|
142
|
-
if (e.origin !== n) throw Error(`OData nextLink points outside the source origin (${e.origin})`);
|
|
143
|
-
if (i = e.toString(), r.has(i)) throw Error(`OData nextLink repeats an already-read page (${i})`);
|
|
144
|
-
r.add(i);
|
|
145
|
-
let o = await v(i);
|
|
146
|
-
t.push(...o.value ?? []), a = o["@odata.nextLink"];
|
|
147
|
-
}
|
|
148
|
-
return {
|
|
149
|
-
count: e["@odata.count"],
|
|
150
|
-
rows: t
|
|
151
|
-
};
|
|
152
|
-
})().then(({ count: n, rows: r }) => {
|
|
153
|
-
if (e.signal.aborted) return;
|
|
154
|
-
let i = n ?? 0, a = i === 0 ? 0 : Math.ceil(i / d) - 1;
|
|
155
|
-
t > a ? (S({
|
|
156
|
-
data: r,
|
|
157
|
-
totalCount: i,
|
|
158
|
-
error: null,
|
|
159
|
-
page: a
|
|
160
|
-
}), T()) : S({
|
|
161
|
-
data: r,
|
|
162
|
-
totalCount: i,
|
|
163
|
-
error: null
|
|
164
|
-
});
|
|
165
|
-
}).catch((t) => {
|
|
166
|
-
e.signal.aborted || t?.name !== "AbortError" && S({
|
|
167
|
-
error: s(t),
|
|
168
|
-
data: [],
|
|
169
|
-
totalCount: 0
|
|
170
|
-
});
|
|
171
|
-
}).finally(() => {
|
|
172
|
-
e.signal.aborted || S({ loading: !1 });
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
return {
|
|
176
|
-
getState: () => m,
|
|
177
|
-
subscribe(e) {
|
|
178
|
-
return h.add(e), h.size === 1 && T(), () => {
|
|
179
|
-
!h.delete(e) || h.size > 0 || (g?.abort(), g = null, v = null);
|
|
180
|
-
};
|
|
181
|
-
},
|
|
182
|
-
setPage(e) {
|
|
183
|
-
S({ page: e }), T();
|
|
184
|
-
},
|
|
185
|
-
setPageSize(e) {
|
|
186
|
-
e !== p.pageSize && (S({
|
|
187
|
-
pageSize: e,
|
|
188
|
-
page: 0
|
|
189
|
-
}), T());
|
|
190
|
-
},
|
|
191
|
-
setSort(e) {
|
|
192
|
-
S({
|
|
193
|
-
sortCriteria: e,
|
|
194
|
-
page: 0
|
|
195
|
-
}), T();
|
|
196
|
-
},
|
|
197
|
-
setSearch(e) {
|
|
198
|
-
S({
|
|
199
|
-
search: e,
|
|
200
|
-
page: 0
|
|
201
|
-
}), T();
|
|
202
|
-
},
|
|
203
|
-
refresh() {
|
|
204
|
-
y() && (v = null, T());
|
|
205
|
-
},
|
|
206
|
-
update(e, t = {}) {
|
|
207
|
-
let n = l(t.fixedFilter), r = n !== d, i = t.pageSize !== void 0 && t.pageSize !== u.pageSize;
|
|
208
|
-
c = e, u = t, d = n, r && (p = {
|
|
209
|
-
...p,
|
|
210
|
-
page: 0
|
|
211
|
-
}), i && t.pageSize !== p.pageSize && (p = {
|
|
212
|
-
...p,
|
|
213
|
-
pageSize: t.pageSize,
|
|
214
|
-
page: 0
|
|
215
|
-
}), C(), T();
|
|
216
|
-
}
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
function l(e) {
|
|
220
|
-
return e ? JSON.stringify(e) : "";
|
|
221
|
-
}
|
|
222
|
-
//#endregion
|
|
223
|
-
export { c as t };
|