@iyulab/flex-table 0.50.3 → 0.51.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 +24 -0
- package/README.md +1 -1
- package/dist/core/source-error.d.ts +8 -1
- package/dist/{flex-table-Hx-xTm0e.js → flex-table-CEmUq0Rp.js} +7 -3
- package/dist/flex-table.js +2 -2
- package/dist/locale.d.ts +1 -1
- package/dist/odata/types.d.ts +4 -0
- package/dist/react.js +101 -90
- package/package.json +1 -1
- package/skills/iyulab-flex-table/references/react.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.51.0] - 2026-10-06
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **A data-source failure the server said nothing about is described in the table's language.** With no message in
|
|
8
|
+
the response, `SourceError.message` was a fixed English `Request failed (<status>)`; with no response at all it was
|
|
9
|
+
the transport's exception text, which differs by browser (`Failed to fetch`, `NetworkError when attempting to fetch
|
|
10
|
+
resource.`). Both rendered in English in any locale, and telling them from a server sentence meant matching the
|
|
11
|
+
string's shape. They now come from `flexTableLocale` — `requestFailed` (`{status}` parameter) and `networkFailed`
|
|
12
|
+
(en and ko built in, others via `register`). A server sentence still wins.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- `SourceError.cause` — on a failure with no response, the exception the transport threw (for diagnostics).
|
|
17
|
+
|
|
18
|
+
## [0.50.4] - 2026-10-06
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **`useODataSource` reports `loading: true` from the first render** until the first response settles. The first
|
|
23
|
+
render used to return `loading: false` with no rows before the request went out, so a screen that shows an empty
|
|
24
|
+
state on `!loading && totalCount === 0` flashed "no results" for a frame on every mount. Mounting with
|
|
25
|
+
`enabled: false` already reported `loading: true`; both paths now follow one rule.
|
|
26
|
+
|
|
3
27
|
## [0.50.3] - 2026-10-06
|
|
4
28
|
|
|
5
29
|
### Documentation
|
package/README.md
CHANGED
|
@@ -815,7 +815,7 @@ The hook returns:
|
|
|
815
815
|
| Field | Description |
|
|
816
816
|
|---|---|
|
|
817
817
|
| `data` / `totalCount` | Current page rows and the server's total (`@odata.count`). When the server pages its response (`@odata.nextLink`, e.g. a page size smaller than `pageSize`), the hook follows the link until the page is filled; a link outside the request's origin, or one that returns to a page already read, is reported through `error` instead of showing a short page |
|
|
818
|
-
| `loading` | A request is in flight |
|
|
818
|
+
| `loading` | A request is in flight, or none has answered yet (true from the first render until the first response settles, and while `enabled: false`) |
|
|
819
819
|
| `error` | The last failed request, or `null`: `{ message, status?, code?, details?, body? }`. **Render `error.message`** — a failed request otherwise leaves the grid silently empty. Branch on `status` (HTTP), `code` (the server's rejection code, OData `error.code`) and `details` (OData `error.details`); `body` is the parsed response (or its text). A failure with no response — a network error, or a `@odata.nextLink` the hook refused — has a `message` only |
|
|
820
820
|
| `page` / `setPage` | Zero-based page index |
|
|
821
821
|
| `sortCriteria` / `onSortChange` | Bind `onSortChange` to the table's `sort-change` event |
|
|
@@ -13,7 +13,10 @@ export interface SourceErrorDetail {
|
|
|
13
13
|
* 엿보는 것 말고는 길이 없다.
|
|
14
14
|
*/
|
|
15
15
|
export interface SourceError {
|
|
16
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* 보여 줄 문장 — 서버가 준 메시지가 있으면 그것. 없으면 이 패키지가 채우는 문장이고 로케일(`flexTableLocale`)을
|
|
18
|
+
* 따른다: 응답은 있었으면 `requestFailed`(`Request failed ({status})`), 응답이 없었으면 `networkFailed`.
|
|
19
|
+
*/
|
|
17
20
|
message: string;
|
|
18
21
|
/** HTTP 상태. 응답이 없던 실패(네트워크 오류 · `@odata.nextLink` 검사)에는 없다. */
|
|
19
22
|
status?: number;
|
|
@@ -23,6 +26,8 @@ export interface SourceError {
|
|
|
23
26
|
details?: SourceErrorDetail[];
|
|
24
27
|
/** 응답 본문 — JSON 이면 파싱한 값, 아니면 텍스트. 비어 있으면 없다. */
|
|
25
28
|
body?: unknown;
|
|
29
|
+
/** 응답이 없던 실패에서 전송(`fetcher`)이 던진 예외 — 진단용. 화면에는 `message` 를 그린다. */
|
|
30
|
+
cause?: unknown;
|
|
26
31
|
}
|
|
27
32
|
/** 실패 응답을 `SourceError` 로 읽는다. 본문을 읽을 수 없어도 상태와 기본 문장은 남긴다. */
|
|
28
33
|
export declare function readFailedResponse(res: Response): Promise<SourceError>;
|
|
@@ -31,5 +36,7 @@ export declare class SourceRequestError extends Error {
|
|
|
31
36
|
readonly failure: SourceError;
|
|
32
37
|
constructor(failure: SourceError);
|
|
33
38
|
}
|
|
39
|
+
/** 전송이 응답 없이 던진 실패(네트워크 · 오프라인)를 `SourceError` 로 — 브라우저마다 다른 예외 문구 대신 로케일 문장. */
|
|
40
|
+
export declare function networkFailure(cause: unknown): SourceRequestError;
|
|
34
41
|
/** 잡힌 예외를 `SourceError` 로 — 응답이 있던 실패는 그 구조 그대로, 나머지는 메시지만. */
|
|
35
42
|
export declare function toSourceError(err: unknown): SourceError;
|
|
@@ -1159,7 +1159,9 @@ O.register("en", {
|
|
|
1159
1159
|
notANumber: "Enter a number",
|
|
1160
1160
|
notADate: "Enter a date as YYYY-MM-DD",
|
|
1161
1161
|
notADateTime: "Enter a date and time as YYYY-MM-DD HH:mm",
|
|
1162
|
-
notInList: "Value must be from the existing list"
|
|
1162
|
+
notInList: "Value must be from the existing list",
|
|
1163
|
+
requestFailed: "Request failed ({status})",
|
|
1164
|
+
networkFailed: "Could not reach the server."
|
|
1163
1165
|
}), O.register("ko", {
|
|
1164
1166
|
showHiddenColumns: "숨긴 열 보기",
|
|
1165
1167
|
columnMenu: "열 메뉴",
|
|
@@ -1227,7 +1229,9 @@ O.register("en", {
|
|
|
1227
1229
|
notANumber: "숫자를 입력하세요",
|
|
1228
1230
|
notADate: "날짜를 YYYY-MM-DD 로 입력하세요",
|
|
1229
1231
|
notADateTime: "날짜와 시간을 YYYY-MM-DD HH:mm 으로 입력하세요",
|
|
1230
|
-
notInList: "목록에 있는 값이어야 합니다"
|
|
1232
|
+
notInList: "목록에 있는 값이어야 합니다",
|
|
1233
|
+
requestFailed: "요청이 실패했습니다 ({status})",
|
|
1234
|
+
networkFailed: "서버에 연결하지 못했습니다."
|
|
1231
1235
|
});
|
|
1232
1236
|
var k = (e, t) => O.text(e, t);
|
|
1233
1237
|
//#endregion
|
|
@@ -4624,4 +4628,4 @@ function $(e) {
|
|
|
4624
4628
|
}
|
|
4625
4629
|
}
|
|
4626
4630
|
//#endregion
|
|
4627
|
-
export { A as a, j as i, W as n, O as o, B as r,
|
|
4631
|
+
export { A as a, T as c, j as i, W as n, O as o, B as r, k as s, Q as t };
|
package/dist/flex-table.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e,
|
|
2
|
-
export { o as FlexTable, e as RowSelectionState,
|
|
1
|
+
import { a as e, c as t, i as n, n as r, o as i, r as a, t as o } from "./flex-table-CEmUq0Rp.js";
|
|
2
|
+
export { o as FlexTable, e as RowSelectionState, n as UndoStack, r as effectiveAlign, a as exportData, i as flexTableLocale, t as renderCell };
|
package/dist/locale.d.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* (아이콘 자리의 글리프)는 어느 로케일에서도 같은 것을 뜻하며, 번역하면 오히려 읽히지 않는다.
|
|
26
26
|
* 그 판단은 «번역하지 않기로 한 것»이지 «빠뜨린 것»이 아니다.
|
|
27
27
|
*/
|
|
28
|
-
export type FlexTableMessageKey = 'showHiddenColumns' | 'columnMenu' | 'cellActions' | 'noColumnsDefined' | 'addCommentPlaceholder' | 'cancel' | 'save' | 'clear' | 'blankCells' | 'emptyOnly' | 'nonEmptyOnly' | 'blankAll' | 'all' | 'contains' | 'startsWith' | 'endsWith' | 'wildcard' | 'searchPlaceholder' | 'valuePlaceholder' | 'fromPlaceholder' | 'toPlaceholder' | 'findPlaceholder' | 'findPrevious' | 'findNext' | 'matchCase' | 'wholeCell' | 'closeFind' | 'findNoResults' | 'replaceWithPlaceholder' | 'replace' | 'replaceAll' | 'findInput' | 'replaceInput' | 'filterFor' | 'filterMatchMode' | 'filterText' | 'conditionOperator' | 'conditionValue' | 'conditionJoin' | 'sortAscending' | 'sortDescending' | 'filter' | 'clearFilter' | 'hideColumn' | 'showColumn' | 'autoFitWidth' | 'wider' | 'narrower' | 'columnMenuFor' | 'columnMenuRegion' | 'copy' | 'insertRowAbove' | 'insertRowBelow' | 'deleteRow' | 'selectRow' | 'selectAllRows' | 'filterByThisValue' | 'addComment' | 'editComment' | 'deleteComment' | 'booleanTrue' | 'booleanFalse' | 'dropFileToImport' | 'notANumber' | 'notADate' | 'notADateTime' | 'notInList';
|
|
28
|
+
export type FlexTableMessageKey = 'showHiddenColumns' | 'columnMenu' | 'cellActions' | 'noColumnsDefined' | 'addCommentPlaceholder' | 'cancel' | 'save' | 'clear' | 'blankCells' | 'emptyOnly' | 'nonEmptyOnly' | 'blankAll' | 'all' | 'contains' | 'startsWith' | 'endsWith' | 'wildcard' | 'searchPlaceholder' | 'valuePlaceholder' | 'fromPlaceholder' | 'toPlaceholder' | 'findPlaceholder' | 'findPrevious' | 'findNext' | 'matchCase' | 'wholeCell' | 'closeFind' | 'findNoResults' | 'replaceWithPlaceholder' | 'replace' | 'replaceAll' | 'findInput' | 'replaceInput' | 'filterFor' | 'filterMatchMode' | 'filterText' | 'conditionOperator' | 'conditionValue' | 'conditionJoin' | 'sortAscending' | 'sortDescending' | 'filter' | 'clearFilter' | 'hideColumn' | 'showColumn' | 'autoFitWidth' | 'wider' | 'narrower' | 'columnMenuFor' | 'columnMenuRegion' | 'copy' | 'insertRowAbove' | 'insertRowBelow' | 'deleteRow' | 'selectRow' | 'selectAllRows' | 'filterByThisValue' | 'addComment' | 'editComment' | 'deleteComment' | 'booleanTrue' | 'booleanFalse' | 'dropFileToImport' | 'notANumber' | 'notADate' | 'notADateTime' | 'notInList' | 'requestFailed' | 'networkFailed';
|
|
29
29
|
/** 이 패키지의 chrome 문자열 묶음. 소비자가 `register()` 로 언어를 더하거나 문구를 덮을 수 있다. */
|
|
30
30
|
export declare const flexTableLocale: import("@iyulab/components/dist/utilities/Locale.js").LocaleNamespace<FlexTableMessageKey>;
|
|
31
31
|
/** 짧은 조회 별칭 — 렌더 코드가 읽히게 유지한다. */
|
package/dist/odata/types.d.ts
CHANGED
|
@@ -43,6 +43,10 @@ export interface UseODataSourceOptions {
|
|
|
43
43
|
export interface UseODataSourceResult<T> {
|
|
44
44
|
data: T[];
|
|
45
45
|
totalCount: number;
|
|
46
|
+
/**
|
|
47
|
+
* 조회 중이거나 아직 한 번도 답을 받지 않았으면 `true` — 첫 렌더부터 첫 응답(성공·실패)이 정착할 때까지,
|
|
48
|
+
* 그리고 `enabled: false` 인 동안. 그래서 `!loading && totalCount === 0` 이 곧 «결과 없음» 이다.
|
|
49
|
+
*/
|
|
46
50
|
loading: boolean;
|
|
47
51
|
/**
|
|
48
52
|
* 마지막 요청의 실패, 없으면 `null`. 화면에는 `error.message` 를 그린다. «어떤 실패인가» 는
|
package/dist/react.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as
|
|
3
|
-
import { t as
|
|
4
|
-
import
|
|
5
|
-
import { createComponent as
|
|
1
|
+
import { s as e, t } from "./flex-table-CEmUq0Rp.js";
|
|
2
|
+
import { i as n, t as r } from "./query-Dw4iO0ir.js";
|
|
3
|
+
import { t as i } from "./view-DiLr-TdY.js";
|
|
4
|
+
import a, { useCallback as o, useEffect as s, useMemo as c, useRef as l, useState as u } from "react";
|
|
5
|
+
import { createComponent as d } from "@lit/react";
|
|
6
6
|
//#region src/core/source-error.ts
|
|
7
|
-
async function
|
|
8
|
-
let
|
|
9
|
-
message:
|
|
10
|
-
status:
|
|
7
|
+
async function f(t) {
|
|
8
|
+
let n = await t.text().catch(() => ""), r = {
|
|
9
|
+
message: e("requestFailed", { status: t.status }),
|
|
10
|
+
status: t.status
|
|
11
11
|
};
|
|
12
|
-
if (!
|
|
13
|
-
let
|
|
12
|
+
if (!n) return r;
|
|
13
|
+
let i = n;
|
|
14
14
|
try {
|
|
15
|
-
|
|
15
|
+
i = JSON.parse(n);
|
|
16
16
|
} catch {}
|
|
17
|
-
if (
|
|
18
|
-
let
|
|
19
|
-
typeof
|
|
20
|
-
let
|
|
21
|
-
return
|
|
17
|
+
if (r.body = i, !i || typeof i != "object") return r;
|
|
18
|
+
let a = i, o = a.error && typeof a.error == "object" ? a.error : a;
|
|
19
|
+
typeof o.message == "string" && o.message ? r.message = o.message : typeof a.message == "string" && a.message && (r.message = a.message), typeof o.code == "string" && o.code && (r.code = o.code);
|
|
20
|
+
let s = p(o.details);
|
|
21
|
+
return s && (r.details = s), r;
|
|
22
22
|
}
|
|
23
|
-
function
|
|
23
|
+
function p(e) {
|
|
24
24
|
if (!Array.isArray(e)) return;
|
|
25
25
|
let t = e.filter((e) => {
|
|
26
26
|
if (!e || typeof e != "object") return !1;
|
|
@@ -29,56 +29,67 @@ function f(e) {
|
|
|
29
29
|
});
|
|
30
30
|
return t.length > 0 ? t : void 0;
|
|
31
31
|
}
|
|
32
|
-
var
|
|
32
|
+
var m = class extends Error {
|
|
33
33
|
constructor(e) {
|
|
34
34
|
super(e.message), this.name = "SourceRequestError", this.failure = e;
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
-
function
|
|
38
|
-
return
|
|
37
|
+
function h(t) {
|
|
38
|
+
return new m({
|
|
39
|
+
message: e("networkFailed"),
|
|
40
|
+
cause: t
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function g(e) {
|
|
44
|
+
return e instanceof m ? e.failure : e instanceof Error ? { message: e.message } : { message: String(e) };
|
|
39
45
|
}
|
|
40
46
|
//#endregion
|
|
41
47
|
//#region src/odata/use-odata-source.ts
|
|
42
|
-
function
|
|
43
|
-
let { pageSize: i = 20, defaultOrderBy:
|
|
44
|
-
defaultOrderBy:
|
|
45
|
-
initialPage:
|
|
46
|
-
initialSearch:
|
|
47
|
-
initialSort:
|
|
48
|
-
}), [
|
|
49
|
-
|
|
50
|
-
let
|
|
51
|
-
|
|
52
|
-
}, []),
|
|
53
|
-
|
|
54
|
-
}, []),
|
|
48
|
+
function _(e, t = {}) {
|
|
49
|
+
let { pageSize: i = 20, defaultOrderBy: a, initialPage: c = 0, initialSearch: d = "", initialSort: p, fixedFilter: _, baseUrl: v, fetcher: y = fetch, onUnauthorized: b, enabled: x = !0 } = t, S = _ ? JSON.stringify(_) : "", [C, w] = u([]), [T, E] = u(0), [D, O] = u(!0), [k, A] = u(null), j = n({
|
|
50
|
+
defaultOrderBy: a,
|
|
51
|
+
initialPage: c,
|
|
52
|
+
initialSearch: d,
|
|
53
|
+
initialSort: p
|
|
54
|
+
}), [M, N] = u(j.page), [P, F] = u(j.sortCriteria), [I, L] = u(j.search), [R, z] = u(0), [B, V] = u(S);
|
|
55
|
+
S !== B && (V(S), N(0));
|
|
56
|
+
let H = l(null), U = o(() => {
|
|
57
|
+
z((e) => e + 1);
|
|
58
|
+
}, []), W = o((e) => {
|
|
59
|
+
L(e), N(0);
|
|
60
|
+
}, []), G = o((e) => {
|
|
55
61
|
let t = e.detail?.criteria;
|
|
56
|
-
t && (
|
|
62
|
+
t && (F(t), N(0));
|
|
57
63
|
}, []);
|
|
58
|
-
return
|
|
59
|
-
if (
|
|
64
|
+
return s(() => {
|
|
65
|
+
if (H.current?.abort(), !x) return;
|
|
60
66
|
let t = new AbortController();
|
|
61
|
-
|
|
62
|
-
let
|
|
63
|
-
page:
|
|
67
|
+
H.current = t, O(!0), A(null);
|
|
68
|
+
let n = r({
|
|
69
|
+
page: M,
|
|
64
70
|
pageSize: i,
|
|
65
|
-
sortCriteria:
|
|
66
|
-
defaultOrderBy:
|
|
67
|
-
search:
|
|
68
|
-
fixedFilter:
|
|
69
|
-
}),
|
|
70
|
-
let n
|
|
71
|
-
|
|
71
|
+
sortCriteria: P,
|
|
72
|
+
defaultOrderBy: a,
|
|
73
|
+
search: I,
|
|
74
|
+
fixedFilter: _
|
|
75
|
+
}), o = `${v ?? window.location.origin}${e}${n}`, s = async (e) => {
|
|
76
|
+
let n;
|
|
77
|
+
try {
|
|
78
|
+
n = await y(e, { signal: t.signal });
|
|
79
|
+
} catch (e) {
|
|
80
|
+
throw e?.name === "AbortError" ? e : h(e);
|
|
81
|
+
}
|
|
82
|
+
if (!n.ok) throw n.status === 401 && b && b(n), new m(await f(n));
|
|
72
83
|
return n.json();
|
|
73
84
|
};
|
|
74
85
|
return (async () => {
|
|
75
|
-
let e = await o
|
|
86
|
+
let e = await s(o), t = [...e.value ?? e], n = new URL(o).origin, r = /* @__PURE__ */ new Set([o]), a = o, c = e["@odata.nextLink"];
|
|
76
87
|
for (; typeof c == "string" && c && t.length < i;) {
|
|
77
|
-
let e = new URL(c,
|
|
88
|
+
let e = new URL(c, a);
|
|
78
89
|
if (e.origin !== n) throw Error(`OData nextLink points outside the source origin (${e.origin})`);
|
|
79
|
-
if (
|
|
80
|
-
r.add(
|
|
81
|
-
let i = await
|
|
90
|
+
if (a = e.toString(), r.has(a)) throw Error(`OData nextLink repeats an already-read page (${a})`);
|
|
91
|
+
r.add(a);
|
|
92
|
+
let i = await s(a);
|
|
82
93
|
t.push(...i.value ?? []), c = i["@odata.nextLink"];
|
|
83
94
|
}
|
|
84
95
|
return {
|
|
@@ -88,57 +99,57 @@ function h(e, r = {}) {
|
|
|
88
99
|
})().then(({ count: e, rows: n }) => {
|
|
89
100
|
if (t.signal.aborted) return;
|
|
90
101
|
let r = e ?? 0;
|
|
91
|
-
|
|
102
|
+
w(n), E(r), A(null);
|
|
92
103
|
let a = r === 0 ? 0 : Math.ceil(r / i) - 1;
|
|
93
|
-
|
|
104
|
+
M > a && N(a);
|
|
94
105
|
}).catch((e) => {
|
|
95
|
-
t.signal.aborted || e.name !== "AbortError" && (
|
|
106
|
+
t.signal.aborted || e.name !== "AbortError" && (A(g(e)), w([]), E(0));
|
|
96
107
|
}).finally(() => {
|
|
97
|
-
t.signal.aborted ||
|
|
108
|
+
t.signal.aborted || O(!1);
|
|
98
109
|
}), () => t.abort();
|
|
99
110
|
}, [
|
|
100
|
-
|
|
111
|
+
x,
|
|
101
112
|
e,
|
|
102
|
-
|
|
113
|
+
M,
|
|
103
114
|
i,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
115
|
+
P,
|
|
116
|
+
I,
|
|
117
|
+
S,
|
|
118
|
+
a,
|
|
119
|
+
R,
|
|
120
|
+
v
|
|
110
121
|
]), {
|
|
111
|
-
data:
|
|
112
|
-
totalCount:
|
|
113
|
-
loading:
|
|
114
|
-
error:
|
|
115
|
-
page:
|
|
116
|
-
setPage:
|
|
117
|
-
sortCriteria:
|
|
118
|
-
onSortChange:
|
|
119
|
-
search:
|
|
120
|
-
setSearch:
|
|
121
|
-
refresh:
|
|
122
|
+
data: C,
|
|
123
|
+
totalCount: T,
|
|
124
|
+
loading: D || !x,
|
|
125
|
+
error: k,
|
|
126
|
+
page: M,
|
|
127
|
+
setPage: N,
|
|
128
|
+
sortCriteria: P,
|
|
129
|
+
onSortChange: G,
|
|
130
|
+
search: I,
|
|
131
|
+
setSearch: W,
|
|
132
|
+
refresh: U
|
|
122
133
|
};
|
|
123
134
|
}
|
|
124
135
|
//#endregion
|
|
125
136
|
//#region src/array/use-array-source.ts
|
|
126
|
-
function
|
|
127
|
-
let { pageSize:
|
|
128
|
-
defaultOrderBy:
|
|
129
|
-
initialPage:
|
|
130
|
-
initialSearch:
|
|
137
|
+
function v(e, t = {}) {
|
|
138
|
+
let { pageSize: r = 20, defaultOrderBy: a, initialPage: s = 0, initialSearch: l = "", initialSort: d, columns: f, searchFields: p } = t, m = n({
|
|
139
|
+
defaultOrderBy: a,
|
|
140
|
+
initialPage: s,
|
|
141
|
+
initialSearch: l,
|
|
131
142
|
initialSort: d
|
|
132
|
-
}), [h, g] =
|
|
143
|
+
}), [h, g] = u(m.page), [_, v] = u(m.sortCriteria), [y, b] = u(m.search), x = o((e) => {
|
|
133
144
|
b(e), g(0);
|
|
134
|
-
}, []), S =
|
|
145
|
+
}, []), S = o((e) => {
|
|
135
146
|
let t = e.detail?.criteria;
|
|
136
147
|
t && (v(t), g(0));
|
|
137
|
-
}, []), C =
|
|
148
|
+
}, []), C = o(() => {}, []), { data: w, totalCount: T } = c(() => i(e, {
|
|
138
149
|
search: y,
|
|
139
150
|
sortCriteria: _,
|
|
140
151
|
page: h,
|
|
141
|
-
pageSize:
|
|
152
|
+
pageSize: r,
|
|
142
153
|
columns: f,
|
|
143
154
|
searchFields: p
|
|
144
155
|
}), [
|
|
@@ -146,10 +157,10 @@ function g(e, n = {}) {
|
|
|
146
157
|
y,
|
|
147
158
|
_,
|
|
148
159
|
h,
|
|
149
|
-
|
|
160
|
+
r,
|
|
150
161
|
f,
|
|
151
162
|
p
|
|
152
|
-
]), E = T === 0 ? 0 : Math.ceil(T /
|
|
163
|
+
]), E = T === 0 ? 0 : Math.ceil(T / r) - 1;
|
|
153
164
|
return h > E && g(E), {
|
|
154
165
|
data: w,
|
|
155
166
|
totalCount: T,
|
|
@@ -164,10 +175,10 @@ function g(e, n = {}) {
|
|
|
164
175
|
refresh: C
|
|
165
176
|
};
|
|
166
177
|
}
|
|
167
|
-
var
|
|
178
|
+
var y = d({
|
|
168
179
|
tagName: "flex-table",
|
|
169
|
-
elementClass:
|
|
170
|
-
react:
|
|
180
|
+
elementClass: t,
|
|
181
|
+
react: a,
|
|
171
182
|
events: {
|
|
172
183
|
onCellSelect: "cell-select",
|
|
173
184
|
onCellEditCommit: "cell-edit-commit",
|
|
@@ -203,4 +214,4 @@ var _ = u({
|
|
|
203
214
|
}
|
|
204
215
|
});
|
|
205
216
|
//#endregion
|
|
206
|
-
export {
|
|
217
|
+
export { y as FlexTableReact, v as useArraySource, _ as useODataSource };
|
package/package.json
CHANGED
|
@@ -110,8 +110,8 @@ function Orders() {
|
|
|
110
110
|
| Field | Notes |
|
|
111
111
|
|---|---|
|
|
112
112
|
| `data`, `totalCount` | Current page and `@odata.count`; `@odata.nextLink` is followed to fill a page |
|
|
113
|
-
| `loading` | Request in flight |
|
|
114
|
-
| `error` | `SourceError \| null` — `{ message, status?, code?, details?, body? }`; render `error.message`, branch on `status` / `code` (OData `error.code`) |
|
|
113
|
+
| `loading` | Request in flight, or no answer yet (true from the first render until the first response settles, and while `enabled: false`) — so `!loading && totalCount === 0` means "no results" |
|
|
114
|
+
| `error` | `SourceError \| null` — `{ message, status?, code?, details?, body?, cause? }`; render `error.message`, branch on `status` / `code` (OData `error.code`). `message` is the server's sentence when it sent one; otherwise this package's, in the `flexTableLocale` language — `requestFailed` (`Request failed ({status})`) when a response came back, `networkFailed` when none did (the transport's exception is in `cause`) |
|
|
115
115
|
| `page`, `setPage` | Zero-based |
|
|
116
116
|
| `sortCriteria`, `onSortChange` | Pass `onSortChange` to the table's `sort-change` (resets to page 0) |
|
|
117
117
|
| `search`, `setSearch` | Literal text (resets to page 0) |
|