@iyulab/flex-table 0.51.0 → 0.53.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 +31 -0
- package/README.md +45 -2
- package/dist/{flex-table-CEmUq0Rp.js → flex-table-DUAMhXCS.js} +481 -625
- package/dist/flex-table.d.ts +4 -0
- package/dist/flex-table.js +3 -2
- package/dist/locale-B1SiVDS1.js +147 -0
- package/dist/odata/controller.d.ts +29 -0
- package/dist/odata/index.d.ts +3 -0
- package/dist/odata/index.js +18 -2
- package/dist/odata/source.d.ts +79 -0
- package/dist/odata/types.d.ts +7 -57
- package/dist/odata/use-odata-source.d.ts +5 -1
- package/dist/react.js +34 -145
- package/dist/source-CwbD-6ea.js +247 -0
- package/package.json +2 -2
- package/skills/iyulab-flex-table/SKILL.md +1 -2
- package/skills/iyulab-flex-table/references/react.md +25 -5
- package/dist/query-Dw4iO0ir.js +0 -37
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.53.0] - 2026-10-07
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`createODataSource(url, options)`** (`@iyulab/flex-table/odata`) — the OData source without React. It is what
|
|
8
|
+
`useODataSource` now runs on: the same options and state, the request, `@odata.nextLink` following, the page
|
|
9
|
+
fallback, the `fixedFilter` reset, `enabled`, cancellation and the structured `error`. `getState()` · `subscribe()` ·
|
|
10
|
+
`setPage` · `setSort` · `setSearch` · `refresh` · `update(url, options)`. Requests go out while someone is subscribed,
|
|
11
|
+
and changes in the same tick become one request.
|
|
12
|
+
- **`ODataSourceController`** — a Lit reactive controller over that source: subscribes when the element connects,
|
|
13
|
+
cancels when it disconnects, re-renders it on every change. A custom-element list page gets the same server paging
|
|
14
|
+
a React page gets from the hook.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `useODataSource` reads `fetcher` and `onUnauthorized` when each request starts. A fresh function on every render no
|
|
19
|
+
longer needs `useCallback`; before, the one captured by the last request kept being used.
|
|
20
|
+
|
|
21
|
+
## [0.52.0] - 2026-10-07
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **Requires `@iyulab/components` 2.8.0** (peer `>=2.8.0`) — for its locale change notification.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- **`flex-table` follows a runtime locale switch.** `Locale.set()` or registering strings (`flexTableLocale.register`)
|
|
30
|
+
re-renders the table at once — menus, filters, empty states and a cell's error marker (now looked up when drawn). It
|
|
31
|
+
kept the old language until a scroll or data change redrew it. A table detached during the switch catches up when
|
|
32
|
+
attached again.
|
|
33
|
+
|
|
3
34
|
## [0.51.0] - 2026-10-06
|
|
4
35
|
|
|
5
36
|
### Fixed
|
package/README.md
CHANGED
|
@@ -758,7 +758,7 @@ const source = useODataSource('/api/orders', {
|
|
|
758
758
|
| `onUnauthorized` | — | Called on `401` responses, before the generic error is set. A `403` (signed in, not permitted) does not call it — it surfaces as `error` |
|
|
759
759
|
| `enabled` | `true` | While `false`, no request is made and `loading` stays `true` — see below |
|
|
760
760
|
|
|
761
|
-
`fetcher`/`onUnauthorized`
|
|
761
|
+
`fetcher`/`onUnauthorized` are read when each request starts, so a fresh function on every render is fine — it neither refetches nor is ignored.
|
|
762
762
|
|
|
763
763
|
Changing `fixedFilter` resets the page to `0`, the same way `setSearch` and `onSortChange`
|
|
764
764
|
already do. All three change the size of the result set, so keeping the old `$skip` would
|
|
@@ -828,7 +828,7 @@ The hook returns:
|
|
|
828
828
|
|
|
829
829
|
Terms are always quoted because OData 4.0 only allows letters in an unquoted `searchWord`, so `2026` or `ZT-E2E-A` would be rejected by servers that follow it (4.01 relaxed this, but [Microsoft.OData still lexes as 4.0](https://github.com/OData/odata.net/issues/2445)). Quoting keeps any term valid regardless of server version. Since a `$search` phrase cannot contain `"` and OData defines no escape for it, double quotes are stripped from the term.
|
|
830
830
|
|
|
831
|
-
The quoting/escaping logic above is also available standalone as `buildSearchExpression(term)`, for consumers that need the same `$search` encoding without the pagination hook (e.g. a typeahead/combobox that isn't a table). `parseOrderBy(orderBy)` (`'a asc, b desc'` → `SortCriteria[]`) is exported the same way, for consumers driving a sort UI that isn't `useODataSource` either. The `./odata` entry
|
|
831
|
+
The quoting/escaping logic above is also available standalone as `buildSearchExpression(term)`, for consumers that need the same `$search` encoding without the pagination hook (e.g. a typeahead/combobox that isn't a table). `parseOrderBy(orderBy)` (`'a asc, b desc'` → `SortCriteria[]`) is exported the same way, for consumers driving a sort UI that isn't `useODataSource` either. The `./odata` entry does not load React, so an app without React can use it (the hooks live on `./react`):
|
|
832
832
|
|
|
833
833
|
```ts
|
|
834
834
|
import { buildSearchExpression, parseOrderBy } from '@iyulab/flex-table/odata';
|
|
@@ -852,6 +852,49 @@ buildODataQuery({
|
|
|
852
852
|
// '?$filter=IsActive eq true&$orderby=name desc&$count=true&$top=20&$skip=40&$search=%22red%22%20AND%20%22shirt%22'
|
|
853
853
|
```
|
|
854
854
|
|
|
855
|
+
### OData Source without React
|
|
856
|
+
|
|
857
|
+
`useODataSource` is a thin adapter over a framework-neutral source, and that source is public: `createODataSource(url, options)` takes the same options and does everything the hook does — the request, `@odata.nextLink` following, page fallback, `fixedFilter` reset, `enabled`, cancellation and the structured `error`. Use it from a Lit element, another framework, or plain code.
|
|
858
|
+
|
|
859
|
+
```ts
|
|
860
|
+
import { createODataSource } from '@iyulab/flex-table/odata';
|
|
861
|
+
|
|
862
|
+
const orders = createODataSource<Order>('/api/orders', { pageSize: 20 });
|
|
863
|
+
const off = orders.subscribe(() => render(orders.getState())); // the first subscriber starts loading
|
|
864
|
+
orders.setSort([{ key: 'name', direction: 'asc' }]); // also: setPage, setSearch, refresh
|
|
865
|
+
orders.update('/api/orders', { pageSize: 20, fixedFilter: { IsActive: true } }); // changed options
|
|
866
|
+
off(); // the last unsubscribe cancels a request in flight
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
| Member | Description |
|
|
870
|
+
|---|---|
|
|
871
|
+
| `getState()` | `{ data, totalCount, loading, error, page, sortCriteria, search }` — the same fields the hook returns. A new object only when something changed |
|
|
872
|
+
| `subscribe(listener)` | Called on every change; returns the unsubscribe function. Requests go out only while someone is subscribed |
|
|
873
|
+
| `setPage(page)` | Zero-based |
|
|
874
|
+
| `setSort(criteria)` / `setSearch(term)` | Change the sort or search and go back to page 0 |
|
|
875
|
+
| `refresh()` | Re-read with the same conditions (nothing while `enabled: false`) |
|
|
876
|
+
| `update(url, options)` | New options. Only a changed request re-reads; a changed `fixedFilter` value goes back to page 0; `initial*` are read at creation only |
|
|
877
|
+
|
|
878
|
+
Changes made in the same tick become one request with the final conditions, so `setSearch` followed by `setPage` does not send the intermediate one.
|
|
879
|
+
|
|
880
|
+
For a Lit element, `ODataSourceController` ties a source to the element's lifecycle — it subscribes when the element connects, cancels when it disconnects, and re-renders it on every change:
|
|
881
|
+
|
|
882
|
+
```ts
|
|
883
|
+
import { ODataSourceController } from '@iyulab/flex-table/odata';
|
|
884
|
+
|
|
885
|
+
class OrdersPage extends LitElement {
|
|
886
|
+
private orders = new ODataSourceController<Order>(this, '/api/orders', { pageSize: 20 });
|
|
887
|
+
|
|
888
|
+
render() {
|
|
889
|
+
const { data, loading, error } = this.orders.state;
|
|
890
|
+
return html`
|
|
891
|
+
${error ? html`<p role="alert">${error.message}</p>` : ''}
|
|
892
|
+
<flex-table data-mode="server" .data=${data} .loading=${loading}
|
|
893
|
+
@sort-change=${(e: CustomEvent) => this.orders.source.setSort(e.detail.criteria)}></flex-table>`;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
```
|
|
897
|
+
|
|
855
898
|
### Array Source Hook (React)
|
|
856
899
|
|
|
857
900
|
`useArraySource(data, options)` runs search/sort/pagination over an in-memory array and
|