@plitzi/sdk-elements 0.35.10 → 0.36.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 +55 -0
- package/dist/elements/declarations/index.d.ts +3 -0
- package/dist/elements/provider/ApiContainer/ApiContainer.d.ts +13 -1
- package/dist/elements/provider/ApiContainer/ApiContainer.mjs +78 -74
- package/dist/elements/provider/ApiContainer/Settings.d.ts +4 -1
- package/dist/elements/provider/ApiContainer/Settings.mjs +141 -115
- package/dist/elements/provider/ApiContainer/declaration.d.ts +3 -0
- package/dist/elements/provider/ApiContainer/declaration.mjs +5 -2
- package/dist/elements/provider/ApiContainer/hooks/useApi.d.ts +23 -8
- package/dist/elements/provider/ApiContainer/hooks/useApi.mjs +58 -59
- package/dist/elements/provider/ApiContainer/hooks/useProviderWrite.mjs +19 -18
- package/dist/elements/provider/ApiContainer/index.d.ts +3 -0
- package/dist/index.d.ts +3 -0
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,60 @@
|
|
|
1
1
|
# @plitzi/sdk-elements
|
|
2
2
|
|
|
3
|
+
## 0.36.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- - **An `apiContainer` can keep its browser requests in a query cache, the way react-query does.** Moving between
|
|
8
|
+
sections or pages used to ask the API again every time a provider was shown: a provider in a hidden section is
|
|
9
|
+
mounted but disabled, so showing it fired a fresh request, and a page navigation remounted it and did the same.
|
|
10
|
+
With the new `cache: true` an answer is kept for `staleTime` seconds (30 by default) and shared by every cached
|
|
11
|
+
provider asking the same thing — same method, URL, credentials and headers, the token included, so two visitors
|
|
12
|
+
never share one. Past its time the answer is still drawn at once and a fresh one is fetched behind it; an answer
|
|
13
|
+
nobody shows is forgotten after `gcTime` seconds (300 by default). A refused request (`4xx`/`5xx`) is shown but
|
|
14
|
+
never kept. **The cache is off unless an element asks for it**: an uncached provider behaves as before, asking on
|
|
15
|
+
every mount and sharing nothing.
|
|
16
|
+
|
|
17
|
+
The cache is `@plitzi/sdk-shared/queries` (`queryCache`, `useQuery`, `invalidateQueries`,
|
|
18
|
+
`invalidateQueriesForWrite`), a nexus store written with the per-path `ttl` of `@plitzi/nexus` 1.2.0, which every
|
|
19
|
+
consumer now requires. It reacts to the store's own freshness events, so anything that expires a query's path
|
|
20
|
+
makes the providers on screen ask again.
|
|
21
|
+
|
|
22
|
+
An answer stops counting as current before its time when the element's `performQuery` runs (it always asks
|
|
23
|
+
again), when a flow runs the new global `invalidateQueries` step (source `queries`: `elements`, api container ids
|
|
24
|
+
— a container's requests are tagged with its own id — and/or a `url` prefix), and after a write. Both write steps
|
|
25
|
+
gained `invalidateQueries` / `invalidateElements`: a `webHook` sent with anything but `GET`/`HEAD` refreshes the
|
|
26
|
+
requests to its own site by default, a completed `runServerAction` refreshes all of them by default, and either
|
|
27
|
+
can name containers instead or refresh nothing. A `writeRecord` refreshes all. Providers on screen ask again at
|
|
28
|
+
once; the rest when they are next shown. A sign-in, sign-out or change of account drops everything held. Server-driven
|
|
29
|
+
providers and RSC are untouched.
|
|
30
|
+
|
|
31
|
+
- **A `webHook` that reads can be cached** (`cache`, `staleTime`), in the same cache and under the same key as an api
|
|
32
|
+
container asking the same thing. Its declaration now lives beside it (`utility/webHookSpec`) and the authoring
|
|
33
|
+
catalog gathers it instead of keeping a copy. A `HEAD` is no longer sent with a body, which `fetch` refused.
|
|
34
|
+
|
|
35
|
+
- **Step params can pick several elements.** A new param type, `elementIds` (with an `elementType` filter), is drawn
|
|
36
|
+
in the flow editor as a picker: the matching elements of the space to add, and the picked ones as chips to remove —
|
|
37
|
+
an id no element answers to any more is kept and flagged. The value is a list of ids, so nobody types a
|
|
38
|
+
comma-separated list; `invalidateQueries.elements` and the write steps' `invalidateElements` use it, and the MCP
|
|
39
|
+
catalog says which element type each such param takes.
|
|
40
|
+
|
|
41
|
+
- The dev-tools' Store tab lists the paths a store holds with a TTL — how long ago each was written, what is left
|
|
42
|
+
of it, and a button to expire one or all of them. The query cache appears there as "Queries".
|
|
43
|
+
|
|
44
|
+
- `useApi` no longer takes `params`: nothing passed them, and a GET cannot carry a body anyway. A mock now answers
|
|
45
|
+
synchronously, without a loading frame, and a provider whose URL has not resolved asks for nothing.
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- Updated dependencies
|
|
50
|
+
- @plitzi/sdk-auth@0.36.0
|
|
51
|
+
- @plitzi/sdk-dev-tools@0.36.0
|
|
52
|
+
- @plitzi/sdk-event-bridge@0.36.0
|
|
53
|
+
- @plitzi/sdk-interactions@0.36.0
|
|
54
|
+
- @plitzi/sdk-navigation@0.36.0
|
|
55
|
+
- @plitzi/sdk-schema@0.36.0
|
|
56
|
+
- @plitzi/sdk-shared@0.36.0
|
|
57
|
+
|
|
3
58
|
## 0.35.10
|
|
4
59
|
|
|
5
60
|
### Patch Changes
|
|
@@ -53,6 +53,9 @@ export declare const elementDeclarations: {
|
|
|
53
53
|
readonly pagination: "none";
|
|
54
54
|
readonly pageParam: "page";
|
|
55
55
|
readonly renderWhileLoading: false;
|
|
56
|
+
readonly cache: false;
|
|
57
|
+
readonly staleTime: 30;
|
|
58
|
+
readonly gcTime: 300;
|
|
56
59
|
};
|
|
57
60
|
readonly definition: {
|
|
58
61
|
readonly label: "Api Container";
|
|
@@ -48,8 +48,20 @@ export type ApiContainerProps = {
|
|
|
48
48
|
pageParam?: string;
|
|
49
49
|
/** Renders children while the first client-side request is still in flight, so a loading state can be bound. */
|
|
50
50
|
renderWhileLoading?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Keep a browser request's answer in the page's query cache, shared with every provider asking the same thing.
|
|
53
|
+
* Off by default: an author opts in knowing the page may show an answer up to `staleTime` old.
|
|
54
|
+
*/
|
|
55
|
+
cache?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* With `cache`: seconds an answer is served without asking again. A stale answer is still shown while the new one
|
|
58
|
+
* is fetched; `0` asks on every mount. A text field in the builder, hence the string.
|
|
59
|
+
*/
|
|
60
|
+
staleTime?: number | string;
|
|
61
|
+
/** With `cache`: seconds an answer nobody renders is kept, so coming back within it paints at once. */
|
|
62
|
+
gcTime?: number | string;
|
|
51
63
|
};
|
|
52
|
-
declare const ApiContainer: ({ ref, className, children, query, method, accessToken, when, headers, mockData, subType, credentials, singleRecord, pagination, pageParam, renderWhileLoading }: ApiContainerProps) => import("react").JSX.Element;
|
|
64
|
+
declare const ApiContainer: ({ ref, className, children, query, method, accessToken, when, headers, mockData, subType, credentials, singleRecord, pagination, pageParam, renderWhileLoading, cache, staleTime, gcTime }: ApiContainerProps) => import("react").JSX.Element;
|
|
53
65
|
declare const _default: {
|
|
54
66
|
(props: import('../../../Element/hocs/withElement').WithElementProps<ApiContainerProps>): import("react").JSX.Element;
|
|
55
67
|
displayName: string;
|
|
@@ -7,94 +7,98 @@ import te from "./hooks/useApi.mjs";
|
|
|
7
7
|
import ne from "./hooks/useProviderPagination.mjs";
|
|
8
8
|
import re from "./hooks/useProviderWrite.mjs";
|
|
9
9
|
import { use as ie, useCallback as i, useEffect as ae, useMemo as a } from "react";
|
|
10
|
-
import
|
|
11
|
-
import { useSdkStore as
|
|
12
|
-
import { StoreProvider as
|
|
13
|
-
import { emptyObject as
|
|
14
|
-
import { jsx as
|
|
15
|
-
import { currentRscLocation as
|
|
10
|
+
import oe from "@plitzi/sdk-shared/hooks/usePlitziServiceContext";
|
|
11
|
+
import { useSdkStore as se } from "@plitzi/sdk-shared/store";
|
|
12
|
+
import { StoreProvider as ce } from "@plitzi/nexus/react";
|
|
13
|
+
import { emptyObject as o, getPathsFromObeject as le } from "@plitzi/sdk-shared/helpers/utils";
|
|
14
|
+
import { jsx as s } from "react/jsx-runtime";
|
|
15
|
+
import { currentRscLocation as c } from "@plitzi/sdk-shared/server/rsc/refreshRsc";
|
|
16
16
|
import l from "clsx";
|
|
17
17
|
import u from "@plitzi/sdk-shared/dataSource/helpers/getSourceName";
|
|
18
18
|
import d from "@plitzi/sdk-shared/dataSource/hooks/useRegisterSource";
|
|
19
19
|
import { QueryBuilderEvaluator as ue } from "@plitzi/plitzi-ui/QueryBuilder";
|
|
20
20
|
//#region src/elements/provider/ApiContainer/ApiContainer.tsx
|
|
21
|
-
var f = ({ ref: e, className: f = "", children: p, query: m = "", method: h = "get", accessToken: g = "", when: _ =
|
|
22
|
-
let { id:
|
|
21
|
+
var f = ({ ref: e, className: f = "", children: p, query: m = "", method: h = "get", accessToken: g = "", when: _ = o, headers: v = o, mockData: y = "{}", subType: de = "", credentials: fe = "same-origin", singleRecord: b = !1, pagination: x = "none", pageParam: S = "page", renderWhileLoading: pe = !1, cache: me = !1, staleTime: he = 30, gcTime: ge = 300 }) => {
|
|
22
|
+
let { id: C, visible: w, definition: { label: T = "Api Container", runtime: _e, items: ve } } = t(), E = _e === "server", { loaded: D, stale: O, location: k, elementData: A, refresh: j } = n(), M = u(ee.sourceType, C), { settings: { previewMode: N }, contexts: { InteractionsContext: P } } = oe(), { interactionsManager: F } = ie(P), [[I, L, ye]] = se([
|
|
23
23
|
"navigation.routeParams",
|
|
24
24
|
"navigation.queryParams",
|
|
25
25
|
"navigation.navigate"
|
|
26
|
-
]),
|
|
26
|
+
]), be = a(() => g ? {
|
|
27
27
|
...v,
|
|
28
28
|
Authorization: `Bearer ${g}`
|
|
29
|
-
} : v, [v, g]),
|
|
30
|
-
...
|
|
31
|
-
...
|
|
32
|
-
})) || !
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
} : v, [v, g]), xe = a(() => E || !w ? !1 : !!(N && m && (_ === o || ue(_, {
|
|
30
|
+
...I,
|
|
31
|
+
...L
|
|
32
|
+
})) || !N && (m || y && y !== "{}" && y !== o)), [
|
|
33
|
+
E,
|
|
34
|
+
w,
|
|
35
|
+
N,
|
|
36
36
|
m,
|
|
37
37
|
_,
|
|
38
|
-
F,
|
|
39
38
|
I,
|
|
39
|
+
L,
|
|
40
40
|
y
|
|
41
|
-
]), { isLoading:
|
|
41
|
+
]), Se = a(() => [C], [C]), { isLoading: Ce, isFetching: we, data: R, refetch: z, isSuccess: B, isError: V } = te({
|
|
42
42
|
url: m,
|
|
43
43
|
method: h,
|
|
44
44
|
credentials: fe,
|
|
45
|
-
mock:
|
|
46
|
-
customHeaders:
|
|
47
|
-
enabled:
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
mock: N ? void 0 : y,
|
|
46
|
+
customHeaders: be,
|
|
47
|
+
enabled: xe,
|
|
48
|
+
cache: me,
|
|
49
|
+
staleTime: he,
|
|
50
|
+
gcTime: ge,
|
|
51
|
+
tags: Se
|
|
52
|
+
}), H = E && !!k && k !== c(), U = E && D && !H && A === null, W = a(() => {
|
|
53
|
+
if (!E) return R ?? o;
|
|
54
|
+
if (A) return A;
|
|
55
|
+
if (D) return o;
|
|
52
56
|
if (typeof y != "string") return y;
|
|
53
57
|
try {
|
|
54
58
|
return JSON.parse(y || "{}");
|
|
55
59
|
} catch {
|
|
56
|
-
return
|
|
60
|
+
return o;
|
|
57
61
|
}
|
|
58
62
|
}, [
|
|
59
|
-
T,
|
|
60
|
-
R,
|
|
61
|
-
k,
|
|
62
63
|
E,
|
|
64
|
+
R,
|
|
65
|
+
A,
|
|
66
|
+
D,
|
|
63
67
|
y
|
|
64
|
-
]), G =
|
|
65
|
-
if (!
|
|
68
|
+
]), G = E ? H : we, Te = E ? H : Ce, K = i(async () => {
|
|
69
|
+
if (!E) {
|
|
66
70
|
z();
|
|
67
71
|
return;
|
|
68
72
|
}
|
|
69
|
-
await
|
|
73
|
+
await j([C]);
|
|
70
74
|
}, [
|
|
71
|
-
|
|
75
|
+
E,
|
|
72
76
|
z,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
]), q = W,
|
|
76
|
-
elementId:
|
|
77
|
-
mode:
|
|
78
|
-
pageParam:
|
|
79
|
-
records:
|
|
77
|
+
j,
|
|
78
|
+
C
|
|
79
|
+
]), q = W, Ee = a(() => Array.isArray(q.records) ? q.records : [], [q.records]), { records: J, isLoadingMore: Y, goToPage: X, loadMore: Z } = ne({
|
|
80
|
+
elementId: C,
|
|
81
|
+
mode: x,
|
|
82
|
+
pageParam: S,
|
|
83
|
+
records: Ee,
|
|
80
84
|
page: q.pageInfo?.page ?? 1,
|
|
81
|
-
refresh:
|
|
82
|
-
navigate:
|
|
85
|
+
refresh: j,
|
|
86
|
+
navigate: ye
|
|
83
87
|
});
|
|
84
88
|
ae(() => {
|
|
85
|
-
!G &&
|
|
89
|
+
!G && C && (B ? F.interactionTrigger(C, "onApiSuccess", {
|
|
86
90
|
url: m,
|
|
87
91
|
method: h,
|
|
88
92
|
...W
|
|
89
|
-
}) : V &&
|
|
93
|
+
}) : V && F.interactionTrigger(C, "onApiError", {
|
|
90
94
|
url: m,
|
|
91
95
|
method: h,
|
|
92
96
|
...W
|
|
93
97
|
}));
|
|
94
98
|
}, [
|
|
95
99
|
W,
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
C,
|
|
101
|
+
F,
|
|
98
102
|
V,
|
|
99
103
|
G,
|
|
100
104
|
B,
|
|
@@ -103,12 +107,12 @@ var f = ({ ref: e, className: f = "", children: p, query: m = "", method: h = "g
|
|
|
103
107
|
]);
|
|
104
108
|
let Q = a(() => ({
|
|
105
109
|
...W,
|
|
106
|
-
...Array.isArray(q.records) ? { records: J } :
|
|
110
|
+
...Array.isArray(q.records) ? { records: J } : o,
|
|
107
111
|
isLoading: G || Y,
|
|
108
112
|
isEmpty: b ? q.record === void 0 : J.length === 0,
|
|
109
113
|
hasError: U,
|
|
110
114
|
errorMessage: U ? "The data provider could not be reached" : "",
|
|
111
|
-
isStale:
|
|
115
|
+
isStale: E && O
|
|
112
116
|
}), [
|
|
113
117
|
W,
|
|
114
118
|
q.records,
|
|
@@ -118,9 +122,9 @@ var f = ({ ref: e, className: f = "", children: p, query: m = "", method: h = "g
|
|
|
118
122
|
Y,
|
|
119
123
|
b,
|
|
120
124
|
U,
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
]),
|
|
125
|
+
E,
|
|
126
|
+
O
|
|
127
|
+
]), De = i(() => le(Q).reduce((e, t) => {
|
|
124
128
|
let n = t.split(".");
|
|
125
129
|
return n.length > 1 ? [...e, {
|
|
126
130
|
path: t,
|
|
@@ -131,20 +135,20 @@ var f = ({ ref: e, className: f = "", children: p, query: m = "", method: h = "g
|
|
|
131
135
|
}];
|
|
132
136
|
}, []), [Q]);
|
|
133
137
|
d({
|
|
134
|
-
id:
|
|
135
|
-
source:
|
|
136
|
-
name:
|
|
137
|
-
fields:
|
|
138
|
+
id: C,
|
|
139
|
+
source: M,
|
|
140
|
+
name: T || `API - ${C}`,
|
|
141
|
+
fields: De
|
|
138
142
|
});
|
|
139
143
|
let { writeRecord: $ } = re({
|
|
140
|
-
elementId:
|
|
141
|
-
enabled:
|
|
144
|
+
elementId: C,
|
|
145
|
+
enabled: E,
|
|
142
146
|
onDone: K
|
|
143
|
-
}),
|
|
147
|
+
}), Oe = a(() => {
|
|
144
148
|
let e = {
|
|
145
149
|
performQuery: {
|
|
146
150
|
action: "performQuery",
|
|
147
|
-
title: `Perform Query ${
|
|
151
|
+
title: `Perform Query ${T}`,
|
|
148
152
|
type: "callback",
|
|
149
153
|
callback: K,
|
|
150
154
|
preview: {},
|
|
@@ -152,7 +156,7 @@ var f = ({ ref: e, className: f = "", children: p, query: m = "", method: h = "g
|
|
|
152
156
|
},
|
|
153
157
|
loadMore: {
|
|
154
158
|
action: "loadMore",
|
|
155
|
-
title: `Load More ${
|
|
159
|
+
title: `Load More ${T}`,
|
|
156
160
|
type: "callback",
|
|
157
161
|
callback: Z,
|
|
158
162
|
preview: {},
|
|
@@ -160,7 +164,7 @@ var f = ({ ref: e, className: f = "", children: p, query: m = "", method: h = "g
|
|
|
160
164
|
},
|
|
161
165
|
goToPage: {
|
|
162
166
|
action: "goToPage",
|
|
163
|
-
title: `Go To Page ${
|
|
167
|
+
title: `Go To Page ${T}`,
|
|
164
168
|
type: "callback",
|
|
165
169
|
callback: ({ page: e }) => X(Number(e) || 1),
|
|
166
170
|
preview: {},
|
|
@@ -171,9 +175,9 @@ var f = ({ ref: e, className: f = "", children: p, query: m = "", method: h = "g
|
|
|
171
175
|
} }
|
|
172
176
|
}
|
|
173
177
|
};
|
|
174
|
-
return
|
|
178
|
+
return E && (e.writeRecord = {
|
|
175
179
|
action: "writeRecord",
|
|
176
|
-
title: `Write Record ${
|
|
180
|
+
title: `Write Record ${T}`,
|
|
177
181
|
type: "callback",
|
|
178
182
|
callback: $,
|
|
179
183
|
preview: { action: "create" },
|
|
@@ -191,13 +195,13 @@ var f = ({ ref: e, className: f = "", children: p, query: m = "", method: h = "g
|
|
|
191
195
|
}
|
|
192
196
|
}), e;
|
|
193
197
|
}, [
|
|
194
|
-
|
|
198
|
+
T,
|
|
195
199
|
K,
|
|
196
200
|
Z,
|
|
197
201
|
X,
|
|
198
|
-
|
|
202
|
+
E,
|
|
199
203
|
$
|
|
200
|
-
]),
|
|
204
|
+
]), ke = a(() => ({
|
|
201
205
|
onApiError: {
|
|
202
206
|
action: "onApiError",
|
|
203
207
|
title: "On Api Error",
|
|
@@ -222,17 +226,17 @@ var f = ({ ref: e, className: f = "", children: p, query: m = "", method: h = "g
|
|
|
222
226
|
data: ""
|
|
223
227
|
}
|
|
224
228
|
}
|
|
225
|
-
}), []),
|
|
226
|
-
return /* @__PURE__ */
|
|
229
|
+
}), []), Ae = a(() => M ? { runtime: { sources: { [M]: Q } } } : o, [Q, M]);
|
|
230
|
+
return /* @__PURE__ */ s(r, {
|
|
227
231
|
ref: e,
|
|
228
|
-
tag: !
|
|
232
|
+
tag: !N && !ve?.length ? "div" : de,
|
|
229
233
|
className: l("plitzi-component__api-container", f),
|
|
230
|
-
interactionTriggers:
|
|
231
|
-
interactionCallbacks:
|
|
232
|
-
children: (!
|
|
234
|
+
interactionTriggers: ke,
|
|
235
|
+
interactionCallbacks: Oe,
|
|
236
|
+
children: (!Te || pe) && /* @__PURE__ */ s(ce, {
|
|
233
237
|
inherit: "live",
|
|
234
|
-
name: `Api:${
|
|
235
|
-
value:
|
|
238
|
+
name: `Api:${C}`,
|
|
239
|
+
value: Ae,
|
|
236
240
|
children: p
|
|
237
241
|
})
|
|
238
242
|
});
|
|
@@ -21,7 +21,10 @@ type SettingsProps = {
|
|
|
21
21
|
pagination?: 'none' | 'url' | 'append';
|
|
22
22
|
pageParam?: string;
|
|
23
23
|
renderWhileLoading?: boolean;
|
|
24
|
+
cache?: boolean;
|
|
25
|
+
staleTime?: number | string;
|
|
26
|
+
gcTime?: number | string;
|
|
24
27
|
onUpdate?: (key: string, value: string | boolean | number | object, isDefinition?: boolean) => void;
|
|
25
28
|
};
|
|
26
|
-
declare const Settings: ({ query, method, accessToken, headers, when, subType, mockData, credentials, runtime, connector, action, endpoint, resource, limit, singleRecord, filters, pagination, pageParam, renderWhileLoading, onUpdate }: SettingsProps) => import("react").JSX.Element;
|
|
29
|
+
declare const Settings: ({ query, method, accessToken, headers, when, subType, mockData, credentials, runtime, connector, action, endpoint, resource, limit, singleRecord, filters, pagination, pageParam, renderWhileLoading, cache, staleTime, gcTime, onUpdate }: SettingsProps) => import("react").JSX.Element;
|
|
27
30
|
export default Settings;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import e from "./components/FiltersInput/index.mjs";
|
|
2
|
-
import { useCallback as t, useMemo as n, useState as
|
|
3
|
-
import { useBuilderStore as
|
|
4
|
-
import { get as
|
|
5
|
-
import { emptyObject as
|
|
6
|
-
import { Fragment as
|
|
7
|
-
import
|
|
2
|
+
import { useCallback as t, useMemo as n, useState as r } from "react";
|
|
3
|
+
import { useBuilderStore as i, useCommonStore as a, useSdkStore as o } from "@plitzi/sdk-shared/store";
|
|
4
|
+
import { get as ee } from "@plitzi/plitzi-ui/helpers";
|
|
5
|
+
import { emptyObject as te } from "@plitzi/sdk-shared/helpers/utils";
|
|
6
|
+
import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
7
|
+
import ne from "@plitzi/sdk-shared/theme/useTheme";
|
|
8
8
|
import u from "@plitzi/plitzi-ui/QueryBuilder";
|
|
9
9
|
import d from "@plitzi/plitzi-ui/CodeMirror";
|
|
10
10
|
import f from "@plitzi/plitzi-ui/Input";
|
|
@@ -12,309 +12,335 @@ import p from "@plitzi/plitzi-ui/Select";
|
|
|
12
12
|
import re from "@plitzi/plitzi-ui/KVInput";
|
|
13
13
|
import m from "@plitzi/plitzi-ui/Switch";
|
|
14
14
|
//#region src/elements/provider/ApiContainer/Settings.tsx
|
|
15
|
-
var h = [], g = ({ query: g = "", method: _ = "get", accessToken:
|
|
16
|
-
let { resolvedTheme:
|
|
15
|
+
var h = [], g = ({ query: g = "", method: _ = "get", accessToken: ie = "", headers: v = te, when: y, subType: b = "", mockData: x = "{}", credentials: S = "same-origin", runtime: C = "client", connector: w = "", action: T = "", endpoint: E = "", resource: D = "", limit: ae = "10", singleRecord: O = !1, filters: k = h, pagination: A = "none", pageParam: j = "page", renderWhileLoading: M = !1, cache: N = !1, staleTime: P = 30, gcTime: F = 300, onUpdate: I }) => {
|
|
16
|
+
let { resolvedTheme: L } = ne(), [R] = i("pageDefinitions"), [z] = i("connectors"), [B] = a("actions.catalog"), [V] = i("hasServerRendering"), [H, U] = r(!1), W = C === "server", G = W ? T && !w ? "action" : "connector" : "client", [[K, q, J]] = o([
|
|
17
17
|
"navigation.routeParams",
|
|
18
18
|
"navigation.queryParams",
|
|
19
19
|
"navigation.currentPageId"
|
|
20
|
-
]),
|
|
20
|
+
]), Y = t((e) => (t) => I?.(e, t), [I]), oe = t((e) => I?.("query", e), [I]), se = t((e) => I?.("when", e), [I]), ce = t((e) => I?.("subType", e), [I]), le = t((e) => I?.("mockData", e), [I]), ue = t((e) => U(e.target.checked), []), de = t((e, t) => I?.("headers", t), [I]), fe = t((e) => {
|
|
21
21
|
if (e === "client") {
|
|
22
|
-
|
|
22
|
+
I?.("runtime", "client", !0);
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
}, [
|
|
27
|
-
...Object.keys(
|
|
28
|
-
...Object.keys(
|
|
25
|
+
I?.("runtime", "server", !0), I?.(e === "action" ? "connector" : "action", "");
|
|
26
|
+
}, [I]), pe = t((e) => I?.("singleRecord", e.target.checked), [I]), me = t((e) => I?.("renderWhileLoading", e.target.checked), [I]), he = t((e) => I?.("cache", e.target.checked), [I]), ge = t((e) => I?.("filters", e), [I]), X = n(() => Object.values(z), [z]), Z = n(() => X.find((e) => e.identifier === w)?.manifest, [X, w]), _e = n(() => Object.keys(Z?.operators ?? {}), [Z]), Q = n(() => Object.keys(Z?.endpoints.read ?? {}), [Z]), $ = n(() => [...ee(R, `${J}.attributes.slug`, "").matchAll(/:[a-z0-9_-]+/gim)].map((e) => e[0].slice(1)), [R, J]), ve = n(() => [
|
|
27
|
+
...Object.keys(K),
|
|
28
|
+
...Object.keys(q),
|
|
29
29
|
...$
|
|
30
30
|
].map((e) => ({
|
|
31
31
|
type: "token",
|
|
32
32
|
value: e
|
|
33
33
|
})), [
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
K,
|
|
35
|
+
q,
|
|
36
36
|
$
|
|
37
37
|
]);
|
|
38
|
-
return /* @__PURE__ */
|
|
38
|
+
return /* @__PURE__ */ l("div", {
|
|
39
39
|
className: "flex grow flex-col gap-4 py-2",
|
|
40
40
|
children: [
|
|
41
|
-
/* @__PURE__ */
|
|
42
|
-
value:
|
|
41
|
+
/* @__PURE__ */ l(p, {
|
|
42
|
+
value: G,
|
|
43
43
|
label: "Data Source",
|
|
44
|
-
onChange:
|
|
44
|
+
onChange: fe,
|
|
45
45
|
size: "xs",
|
|
46
46
|
children: [
|
|
47
|
-
/* @__PURE__ */
|
|
47
|
+
/* @__PURE__ */ c("option", {
|
|
48
48
|
value: "client",
|
|
49
49
|
children: "Browser request"
|
|
50
50
|
}),
|
|
51
|
-
/* @__PURE__ */
|
|
51
|
+
/* @__PURE__ */ c("option", {
|
|
52
52
|
value: "connector",
|
|
53
53
|
children: "Connector (server-side)"
|
|
54
54
|
}),
|
|
55
|
-
/* @__PURE__ */
|
|
55
|
+
/* @__PURE__ */ c("option", {
|
|
56
56
|
value: "action",
|
|
57
57
|
children: "Server action (server-side)"
|
|
58
58
|
})
|
|
59
59
|
]
|
|
60
60
|
}),
|
|
61
|
-
/* @__PURE__ */
|
|
61
|
+
/* @__PURE__ */ l("span", {
|
|
62
62
|
className: "text-xs text-gray-500 dark:text-zinc-400",
|
|
63
63
|
children: [
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
G === "connector" && "The server calls the API and hands the page its records. The endpoint and the credential never reach the browser, and the content is in the HTML search engines see.",
|
|
65
|
+
G === "action" && "A flow runs on the server and hands the page whatever its output step returns — for the read a connector cannot express: two calls joined, a computed field, a shape that depends on who is looking. It is fed this page’s route and query params.",
|
|
66
|
+
G === "client" && "The browser calls the URL directly. Anything it needs to authenticate with is visible to the visitor, and the content is not in the initial HTML."
|
|
67
67
|
]
|
|
68
68
|
}),
|
|
69
|
-
|
|
69
|
+
G === "action" && /* @__PURE__ */ l(s, { children: [B?.length === 0 && /* @__PURE__ */ c("div", {
|
|
70
70
|
className: "rounded-sm border border-gray-300 p-2 text-xs text-gray-500 dark:border-zinc-600 dark:text-zinc-400",
|
|
71
71
|
children: "No actions yet. Add one in the Actions panel and give it a “While a page renders” trigger — that is the way in this element uses."
|
|
72
|
-
}), /* @__PURE__ */
|
|
73
|
-
value:
|
|
72
|
+
}), /* @__PURE__ */ l(p, {
|
|
73
|
+
value: T,
|
|
74
74
|
label: "Action",
|
|
75
|
-
onChange:
|
|
75
|
+
onChange: Y("action"),
|
|
76
76
|
size: "xs",
|
|
77
|
-
children: [/* @__PURE__ */
|
|
77
|
+
children: [/* @__PURE__ */ c("option", {
|
|
78
78
|
value: "",
|
|
79
79
|
children: "Select an action…"
|
|
80
|
-
}), (
|
|
80
|
+
}), (B ?? []).map((e) => /* @__PURE__ */ c("option", {
|
|
81
81
|
value: e.identifier,
|
|
82
82
|
children: e.name
|
|
83
83
|
}, e.identifier))]
|
|
84
84
|
})] }),
|
|
85
|
-
|
|
85
|
+
W && !V && /* @__PURE__ */ c("div", {
|
|
86
86
|
className: "rounded-sm border border-yellow-300 bg-yellow-50 p-2 text-xs text-yellow-800 dark:border-yellow-700 dark:bg-yellow-950 dark:text-yellow-200",
|
|
87
87
|
children: "This space has no server-rendered deployment. It resolves here in the builder, but a published page would have no server to resolve it — publish with a Plitzi SSR credential, or read the API from the browser instead."
|
|
88
88
|
}),
|
|
89
|
-
|
|
90
|
-
X.length === 0 && /* @__PURE__ */
|
|
89
|
+
G === "connector" && /* @__PURE__ */ l(s, { children: [
|
|
90
|
+
X.length === 0 && /* @__PURE__ */ c("div", {
|
|
91
91
|
className: "rounded-sm border border-gray-300 p-2 text-xs text-gray-500 dark:border-zinc-600 dark:text-zinc-400",
|
|
92
92
|
children: "No connectors yet. Add one in the Connectors panel — it holds the API endpoints, and the credential stays on the server."
|
|
93
93
|
}),
|
|
94
|
-
/* @__PURE__ */
|
|
95
|
-
value:
|
|
94
|
+
/* @__PURE__ */ l(p, {
|
|
95
|
+
value: w,
|
|
96
96
|
label: "Connector",
|
|
97
|
-
onChange:
|
|
97
|
+
onChange: Y("connector"),
|
|
98
98
|
size: "xs",
|
|
99
|
-
children: [/* @__PURE__ */
|
|
99
|
+
children: [/* @__PURE__ */ c("option", {
|
|
100
100
|
value: "",
|
|
101
101
|
children: "Select a connector…"
|
|
102
|
-
}), X.map((e) => /* @__PURE__ */
|
|
102
|
+
}), X.map((e) => /* @__PURE__ */ c("option", {
|
|
103
103
|
value: e.identifier,
|
|
104
104
|
children: e.name
|
|
105
105
|
}, e.identifier))]
|
|
106
106
|
}),
|
|
107
|
-
Q.length > 1 && /* @__PURE__ */
|
|
108
|
-
value:
|
|
107
|
+
Q.length > 1 && /* @__PURE__ */ c(p, {
|
|
108
|
+
value: E,
|
|
109
109
|
label: "Endpoint",
|
|
110
|
-
onChange:
|
|
110
|
+
onChange: Y("endpoint"),
|
|
111
111
|
size: "xs",
|
|
112
|
-
children: Q.map((e) => /* @__PURE__ */
|
|
112
|
+
children: Q.map((e) => /* @__PURE__ */ c("option", {
|
|
113
113
|
value: e,
|
|
114
114
|
children: e
|
|
115
115
|
}, e))
|
|
116
116
|
}),
|
|
117
|
-
/* @__PURE__ */
|
|
118
|
-
value:
|
|
117
|
+
/* @__PURE__ */ c(f, {
|
|
118
|
+
value: D,
|
|
119
119
|
label: "Resource",
|
|
120
120
|
placeholder: "posts",
|
|
121
121
|
title: "The collection read through the connector — what {{resource}} becomes in the endpoint path.",
|
|
122
|
-
onChange:
|
|
122
|
+
onChange: Y("resource"),
|
|
123
123
|
size: "xs"
|
|
124
124
|
}),
|
|
125
|
-
/* @__PURE__ */
|
|
125
|
+
/* @__PURE__ */ c(e, {
|
|
126
126
|
value: k,
|
|
127
|
-
operators:
|
|
128
|
-
onChange:
|
|
127
|
+
operators: _e,
|
|
128
|
+
onChange: ge
|
|
129
129
|
}),
|
|
130
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ c(m, {
|
|
131
131
|
checked: O,
|
|
132
132
|
size: "sm",
|
|
133
133
|
label: "Single record (detail page)",
|
|
134
|
-
onChange:
|
|
134
|
+
onChange: pe
|
|
135
135
|
}),
|
|
136
|
-
!O && /* @__PURE__ */
|
|
137
|
-
/* @__PURE__ */
|
|
136
|
+
!O && /* @__PURE__ */ l(s, { children: [
|
|
137
|
+
/* @__PURE__ */ c(f, {
|
|
138
138
|
value: ae,
|
|
139
139
|
label: "Records per page",
|
|
140
|
-
onChange:
|
|
140
|
+
onChange: Y("limit"),
|
|
141
141
|
size: "xs"
|
|
142
142
|
}),
|
|
143
|
-
/* @__PURE__ */
|
|
143
|
+
/* @__PURE__ */ l(p, {
|
|
144
144
|
value: A,
|
|
145
145
|
label: "Pagination",
|
|
146
|
-
onChange:
|
|
146
|
+
onChange: Y("pagination"),
|
|
147
147
|
size: "xs",
|
|
148
148
|
children: [
|
|
149
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ c("option", {
|
|
150
150
|
value: "none",
|
|
151
151
|
children: "None"
|
|
152
152
|
}),
|
|
153
|
-
/* @__PURE__ */
|
|
153
|
+
/* @__PURE__ */ c("option", {
|
|
154
154
|
value: "url",
|
|
155
155
|
children: "URL (indexable)"
|
|
156
156
|
}),
|
|
157
|
-
/* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ c("option", {
|
|
158
158
|
value: "append",
|
|
159
159
|
children: "Load more"
|
|
160
160
|
})
|
|
161
161
|
]
|
|
162
162
|
}),
|
|
163
|
-
A !== "none" && /* @__PURE__ */
|
|
163
|
+
A !== "none" && /* @__PURE__ */ c(f, {
|
|
164
164
|
value: j,
|
|
165
165
|
label: "Page parameter",
|
|
166
166
|
title: "Query-string key this list pages on. Give each list its own so they page independently.",
|
|
167
|
-
onChange:
|
|
167
|
+
onChange: Y("pageParam"),
|
|
168
168
|
size: "xs"
|
|
169
169
|
})
|
|
170
170
|
] })
|
|
171
171
|
] }),
|
|
172
|
-
!
|
|
173
|
-
/* @__PURE__ */
|
|
172
|
+
!W && /* @__PURE__ */ l(s, { children: [
|
|
173
|
+
/* @__PURE__ */ l("div", {
|
|
174
174
|
className: "flex flex-col",
|
|
175
|
-
children: [/* @__PURE__ */
|
|
175
|
+
children: [/* @__PURE__ */ c("label", { children: "Query" }), /* @__PURE__ */ c(d, {
|
|
176
176
|
className: "font-rubik min-h-6.5 basis-auto rounded-sm border border-gray-300 px-1 text-xs",
|
|
177
177
|
value: g,
|
|
178
|
-
theme:
|
|
178
|
+
theme: L,
|
|
179
179
|
mode: "text",
|
|
180
|
-
autoComplete:
|
|
180
|
+
autoComplete: ve,
|
|
181
181
|
lineWrapping: !0,
|
|
182
182
|
multiline: !1,
|
|
183
|
-
onChange:
|
|
183
|
+
onChange: oe
|
|
184
184
|
})]
|
|
185
185
|
}),
|
|
186
|
-
/* @__PURE__ */
|
|
186
|
+
/* @__PURE__ */ l(p, {
|
|
187
187
|
value: _,
|
|
188
188
|
label: "Method",
|
|
189
|
-
onChange:
|
|
189
|
+
onChange: Y("method"),
|
|
190
190
|
size: "xs",
|
|
191
|
-
children: [/* @__PURE__ */
|
|
191
|
+
children: [/* @__PURE__ */ c("option", {
|
|
192
192
|
value: "get",
|
|
193
193
|
children: "Get"
|
|
194
|
-
}), /* @__PURE__ */
|
|
194
|
+
}), /* @__PURE__ */ c("option", {
|
|
195
195
|
value: "post",
|
|
196
196
|
children: "Post"
|
|
197
197
|
})]
|
|
198
198
|
}),
|
|
199
|
-
/* @__PURE__ */
|
|
200
|
-
value:
|
|
199
|
+
/* @__PURE__ */ c(f, {
|
|
200
|
+
value: ie,
|
|
201
201
|
label: "Access Token",
|
|
202
202
|
title: "Bind this to the signed-in visitor's token. A value typed here is saved in the page and served to\n every visitor — put anything secret behind a connector instead.",
|
|
203
|
-
onChange:
|
|
203
|
+
onChange: Y("accessToken"),
|
|
204
204
|
size: "xs"
|
|
205
205
|
}),
|
|
206
|
-
/* @__PURE__ */
|
|
207
|
-
value:
|
|
206
|
+
/* @__PURE__ */ l(p, {
|
|
207
|
+
value: S,
|
|
208
208
|
label: "Include Credentials",
|
|
209
|
-
onChange:
|
|
209
|
+
onChange: Y("credentials"),
|
|
210
210
|
size: "xs",
|
|
211
211
|
children: [
|
|
212
|
-
/* @__PURE__ */
|
|
212
|
+
/* @__PURE__ */ c("option", {
|
|
213
213
|
value: "include",
|
|
214
214
|
children: "Include"
|
|
215
215
|
}),
|
|
216
|
-
/* @__PURE__ */
|
|
216
|
+
/* @__PURE__ */ c("option", {
|
|
217
217
|
value: "omit",
|
|
218
218
|
children: "Omit"
|
|
219
219
|
}),
|
|
220
|
-
/* @__PURE__ */
|
|
220
|
+
/* @__PURE__ */ c("option", {
|
|
221
221
|
value: "same-origin",
|
|
222
222
|
children: "Same Origin"
|
|
223
223
|
})
|
|
224
224
|
]
|
|
225
225
|
}),
|
|
226
|
-
/* @__PURE__ */
|
|
226
|
+
/* @__PURE__ */ c(m, {
|
|
227
|
+
checked: N,
|
|
228
|
+
size: "sm",
|
|
229
|
+
label: "Cache responses",
|
|
230
|
+
onChange: he
|
|
231
|
+
}),
|
|
232
|
+
N && /* @__PURE__ */ l(s, { children: [
|
|
233
|
+
/* @__PURE__ */ c(f, {
|
|
234
|
+
value: String(P),
|
|
235
|
+
label: "Fresh for (s)",
|
|
236
|
+
title: "How long an answer is reused without asking again — here and by every provider requesting the\n same thing. Past it, the answer stays on screen while a fresh one is fetched. 0 asks on every mount.",
|
|
237
|
+
onChange: Y("staleTime"),
|
|
238
|
+
size: "xs"
|
|
239
|
+
}),
|
|
240
|
+
/* @__PURE__ */ c(f, {
|
|
241
|
+
value: String(F),
|
|
242
|
+
label: "Keep unused for (s)",
|
|
243
|
+
title: "How long an answer nobody is showing is kept, so coming back to it within that time paints at once.",
|
|
244
|
+
onChange: Y("gcTime"),
|
|
245
|
+
size: "xs"
|
|
246
|
+
}),
|
|
247
|
+
/* @__PURE__ */ c("div", {
|
|
248
|
+
className: "rounded-sm border border-gray-300 p-2 text-xs text-gray-500 dark:border-zinc-600 dark:text-zinc-400",
|
|
249
|
+
children: "A completed server action refreshes every cached request, in case it changed what they read. On its step, “Refresh cached requests” can name only the containers it affects, or none for an action that only reads. A webhook step can do the same."
|
|
250
|
+
})
|
|
251
|
+
] }),
|
|
252
|
+
/* @__PURE__ */ c(m, {
|
|
227
253
|
checked: M,
|
|
228
254
|
size: "sm",
|
|
229
255
|
label: "Render children while loading",
|
|
230
|
-
onChange:
|
|
256
|
+
onChange: me
|
|
231
257
|
})
|
|
232
258
|
] }),
|
|
233
|
-
/* @__PURE__ */
|
|
234
|
-
checked:
|
|
259
|
+
/* @__PURE__ */ c(m, {
|
|
260
|
+
checked: H,
|
|
235
261
|
size: "sm",
|
|
236
262
|
label: "Advanced Settings",
|
|
237
|
-
onChange:
|
|
263
|
+
onChange: ue
|
|
238
264
|
}),
|
|
239
|
-
|
|
240
|
-
/* @__PURE__ */
|
|
241
|
-
value: Object.entries(
|
|
265
|
+
H && /* @__PURE__ */ l(s, { children: [
|
|
266
|
+
/* @__PURE__ */ c(re, {
|
|
267
|
+
value: Object.entries(v),
|
|
242
268
|
label: "Headers",
|
|
243
|
-
onChange:
|
|
269
|
+
onChange: de,
|
|
244
270
|
size: "xs"
|
|
245
271
|
}),
|
|
246
|
-
/* @__PURE__ */
|
|
272
|
+
/* @__PURE__ */ l("div", {
|
|
247
273
|
className: "flex flex-col",
|
|
248
|
-
children: [/* @__PURE__ */
|
|
274
|
+
children: [/* @__PURE__ */ c("label", { children: "When to perform query request" }), /* @__PURE__ */ c(u, {
|
|
249
275
|
direction: "vertical",
|
|
250
276
|
className: "w-full",
|
|
251
277
|
size: "xs",
|
|
252
|
-
query:
|
|
253
|
-
onChange:
|
|
278
|
+
query: y,
|
|
279
|
+
onChange: se,
|
|
254
280
|
showBranches: !0
|
|
255
281
|
})]
|
|
256
282
|
}),
|
|
257
|
-
/* @__PURE__ */
|
|
258
|
-
value:
|
|
283
|
+
/* @__PURE__ */ l(p, {
|
|
284
|
+
value: b,
|
|
259
285
|
label: "Container Tag",
|
|
260
|
-
onChange:
|
|
286
|
+
onChange: ce,
|
|
261
287
|
size: "xs",
|
|
262
288
|
children: [
|
|
263
|
-
/* @__PURE__ */
|
|
289
|
+
/* @__PURE__ */ c("option", {
|
|
264
290
|
value: "",
|
|
265
291
|
children: "None"
|
|
266
292
|
}),
|
|
267
|
-
/* @__PURE__ */
|
|
293
|
+
/* @__PURE__ */ c("option", {
|
|
268
294
|
value: "div",
|
|
269
295
|
children: "Div"
|
|
270
296
|
}),
|
|
271
|
-
/* @__PURE__ */
|
|
297
|
+
/* @__PURE__ */ c("option", {
|
|
272
298
|
value: "header",
|
|
273
299
|
children: "Header"
|
|
274
300
|
}),
|
|
275
|
-
/* @__PURE__ */
|
|
301
|
+
/* @__PURE__ */ c("option", {
|
|
276
302
|
value: "footer",
|
|
277
303
|
children: "Footer"
|
|
278
304
|
}),
|
|
279
|
-
/* @__PURE__ */
|
|
305
|
+
/* @__PURE__ */ c("option", {
|
|
280
306
|
value: "nav",
|
|
281
307
|
children: "Nav"
|
|
282
308
|
}),
|
|
283
|
-
/* @__PURE__ */
|
|
309
|
+
/* @__PURE__ */ c("option", {
|
|
284
310
|
value: "main",
|
|
285
311
|
children: "Main"
|
|
286
312
|
}),
|
|
287
|
-
/* @__PURE__ */
|
|
313
|
+
/* @__PURE__ */ c("option", {
|
|
288
314
|
value: "section",
|
|
289
315
|
children: "Section"
|
|
290
316
|
}),
|
|
291
|
-
/* @__PURE__ */
|
|
317
|
+
/* @__PURE__ */ c("option", {
|
|
292
318
|
value: "article",
|
|
293
319
|
children: "Article"
|
|
294
320
|
}),
|
|
295
|
-
/* @__PURE__ */
|
|
321
|
+
/* @__PURE__ */ c("option", {
|
|
296
322
|
value: "aside",
|
|
297
323
|
children: "Aside"
|
|
298
324
|
}),
|
|
299
|
-
/* @__PURE__ */
|
|
325
|
+
/* @__PURE__ */ c("option", {
|
|
300
326
|
value: "address",
|
|
301
327
|
children: "Address"
|
|
302
328
|
}),
|
|
303
|
-
/* @__PURE__ */
|
|
329
|
+
/* @__PURE__ */ c("option", {
|
|
304
330
|
value: "figure",
|
|
305
331
|
children: "Figure"
|
|
306
332
|
})
|
|
307
333
|
]
|
|
308
334
|
}),
|
|
309
|
-
/* @__PURE__ */
|
|
310
|
-
/* @__PURE__ */
|
|
335
|
+
/* @__PURE__ */ c("div", { className: "my-2 h-px w-full border border-gray-300 bg-gray-300" }),
|
|
336
|
+
/* @__PURE__ */ l("div", {
|
|
311
337
|
className: "flex min-h-50 grow flex-col",
|
|
312
|
-
children: [/* @__PURE__ */
|
|
313
|
-
value:
|
|
314
|
-
theme:
|
|
338
|
+
children: [/* @__PURE__ */ c("label", { children: "Mock Data (Build Mode)" }), /* @__PURE__ */ c(d, {
|
|
339
|
+
value: x,
|
|
340
|
+
theme: L,
|
|
315
341
|
mode: "json",
|
|
316
342
|
lineWrapping: !0,
|
|
317
|
-
onChange:
|
|
343
|
+
onChange: le
|
|
318
344
|
})]
|
|
319
345
|
})
|
|
320
346
|
] })
|
|
@@ -29,6 +29,9 @@ declare const declaration: {
|
|
|
29
29
|
readonly pagination: "none";
|
|
30
30
|
readonly pageParam: "page";
|
|
31
31
|
readonly renderWhileLoading: false;
|
|
32
|
+
readonly cache: false;
|
|
33
|
+
readonly staleTime: 30;
|
|
34
|
+
readonly gcTime: 300;
|
|
32
35
|
};
|
|
33
36
|
readonly definition: {
|
|
34
37
|
readonly label: "Api Container";
|
|
@@ -18,12 +18,15 @@ var t = e()({
|
|
|
18
18
|
filters: [],
|
|
19
19
|
pagination: "none",
|
|
20
20
|
pageParam: "page",
|
|
21
|
-
renderWhileLoading: !1
|
|
21
|
+
renderWhileLoading: !1,
|
|
22
|
+
cache: !1,
|
|
23
|
+
staleTime: 30,
|
|
24
|
+
gcTime: 300
|
|
22
25
|
},
|
|
23
26
|
definition: {
|
|
24
27
|
label: "Api Container",
|
|
25
28
|
type: "apiContainer",
|
|
26
|
-
description: "Fetches data from a backend HTTP API (its `query`/`method`/`credentials`) and exposes the response as a data source ITS DESCENDANTS bind to (source `apiContainer_<id>.data`; only elements inside it can consume it). This is how you get backend data into the frontend. Its `mockData` prop is builder-only sample data — the published runtime fetches the real `query`, so always set a real query for production.",
|
|
29
|
+
description: "Fetches data from a backend HTTP API (its `query`/`method`/`credentials`) and exposes the response as a data source ITS DESCENDANTS bind to (source `apiContainer_<id>.data`; only elements inside it can consume it). This is how you get backend data into the frontend. Its `mockData` prop is builder-only sample data — the published runtime fetches the real `query`, so always set a real query for production. With `cache: true` a browser request is kept for `staleTime` seconds (default 30) and shared with every provider asking the same thing; it is off unless set. A flow refreshes it with `performQuery` or the global `invalidateQueries` step.",
|
|
27
30
|
items: [],
|
|
28
31
|
bindings: {},
|
|
29
32
|
styleSelectors: { base: "" },
|
|
@@ -1,13 +1,31 @@
|
|
|
1
|
+
export type ApiResponse = {
|
|
2
|
+
status: number;
|
|
3
|
+
data: unknown;
|
|
4
|
+
};
|
|
1
5
|
export type UseApiProps = {
|
|
2
6
|
url?: string;
|
|
3
7
|
method?: 'get' | 'post' | 'put' | 'delete' | 'patch';
|
|
8
|
+
/** Answers instead of the network — what the builder renders with while the page is being edited. */
|
|
4
9
|
mock?: Record<string, unknown> | string;
|
|
5
|
-
params?: Record<string, string | Blob>;
|
|
6
10
|
customHeaders?: Record<string, string>;
|
|
7
11
|
enabled?: boolean;
|
|
8
12
|
credentials?: RequestCredentials;
|
|
13
|
+
/**
|
|
14
|
+
* Keep answers in the page's query cache and share them with every provider asking the same thing. Off, each
|
|
15
|
+
* provider asks for itself on every mount and forgets the answer when it unmounts — the behaviour a page gets
|
|
16
|
+
* unless its author opted in.
|
|
17
|
+
*/
|
|
18
|
+
cache?: boolean;
|
|
19
|
+
/** With `cache`: how long an answer is served without asking again, in seconds. `0` asks on every mount. */
|
|
20
|
+
staleTime?: number | string;
|
|
21
|
+
/** With `cache`: how long an answer nobody renders is kept, in seconds. */
|
|
22
|
+
gcTime?: number | string;
|
|
23
|
+
/** What an invalidation can name this request by — an api container gives its own id. */
|
|
24
|
+
tags?: readonly string[];
|
|
9
25
|
};
|
|
10
|
-
declare const
|
|
26
|
+
export declare const DEFAULT_STALE_TIME = 30;
|
|
27
|
+
export declare const DEFAULT_GC_TIME = 300;
|
|
28
|
+
declare const useApi: ({ url, method, mock, customHeaders, enabled, credentials, cache, staleTime, gcTime, tags }: UseApiProps) => {
|
|
11
29
|
/**
|
|
12
30
|
* Nothing has been answered yet, so there is nothing truthful to render.
|
|
13
31
|
*
|
|
@@ -19,12 +37,9 @@ declare const useApi: ({ url, method, mock, params, customHeaders, enabled, cred
|
|
|
19
37
|
isLoading: boolean;
|
|
20
38
|
/** A request is in flight, first or not. What a spinner binds to. */
|
|
21
39
|
isFetching: boolean;
|
|
22
|
-
data:
|
|
23
|
-
status: number;
|
|
24
|
-
data: unknown;
|
|
25
|
-
} | undefined;
|
|
40
|
+
data: ApiResponse | undefined;
|
|
26
41
|
refetch: () => void;
|
|
27
|
-
isSuccess: boolean
|
|
28
|
-
isError: boolean
|
|
42
|
+
isSuccess: boolean;
|
|
43
|
+
isError: boolean;
|
|
29
44
|
};
|
|
30
45
|
export default useApi;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import { useCallback as e,
|
|
1
|
+
import { useCallback as e, useId as t, useMemo as n } from "react";
|
|
2
2
|
import { emptyObject as r } from "@plitzi/sdk-shared/helpers/utils";
|
|
3
3
|
import { authFailureFromResponse as i, reportAuthFailure as a } from "@plitzi/sdk-shared/auth";
|
|
4
|
+
import { requestKey as o, useQuery as s } from "@plitzi/sdk-shared/queries";
|
|
4
5
|
//#region src/elements/provider/ApiContainer/hooks/useApi.ts
|
|
5
|
-
var
|
|
6
|
-
if (
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
var c = 30, l = 300, u = (e) => !!e && e !== "{}" && e !== r, d = (e) => {
|
|
7
|
+
if (typeof e != "string") return {
|
|
8
|
+
status: 200,
|
|
9
|
+
data: e
|
|
10
|
+
};
|
|
11
|
+
try {
|
|
12
|
+
return {
|
|
11
13
|
status: 200,
|
|
12
|
-
data:
|
|
14
|
+
data: JSON.parse(e)
|
|
13
15
|
};
|
|
14
16
|
} catch (e) {
|
|
15
17
|
return {
|
|
@@ -17,32 +19,21 @@ var o = async ({ url: e = "", method: t = "get", credentials: n = "same-origin",
|
|
|
17
19
|
data: e.message
|
|
18
20
|
};
|
|
19
21
|
}
|
|
20
|
-
|
|
21
|
-
if (
|
|
22
|
-
l.append(e, s[e]);
|
|
23
|
-
}), !e) return {
|
|
22
|
+
}, f = async (e, t, n, r) => {
|
|
23
|
+
if (!e) return {
|
|
24
24
|
status: 400,
|
|
25
25
|
data: "URL is required"
|
|
26
26
|
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
let u = new FormData();
|
|
34
|
-
Object.entries(o).forEach(([e, t]) => {
|
|
35
|
-
u.append(e, t);
|
|
36
|
-
});
|
|
37
|
-
let d = {
|
|
27
|
+
let o = new Headers(r);
|
|
28
|
+
o.has("Content-Type") || o.set("Content-Type", "application/json");
|
|
29
|
+
let s = {
|
|
38
30
|
method: t,
|
|
39
31
|
credentials: n,
|
|
40
|
-
headers:
|
|
41
|
-
body: u
|
|
32
|
+
headers: o
|
|
42
33
|
};
|
|
43
|
-
|
|
34
|
+
t !== "get" && (s.body = "{}");
|
|
44
35
|
try {
|
|
45
|
-
let t = await fetch(e,
|
|
36
|
+
let t = await fetch(e, s), n = await t.json(), r = i(t.status, n);
|
|
46
37
|
return r && a({
|
|
47
38
|
reason: r,
|
|
48
39
|
url: e
|
|
@@ -56,44 +47,52 @@ var o = async ({ url: e = "", method: t = "get", credentials: n = "same-origin",
|
|
|
56
47
|
data: e.message
|
|
57
48
|
};
|
|
58
49
|
}
|
|
59
|
-
},
|
|
60
|
-
let
|
|
61
|
-
|
|
62
|
-
|
|
50
|
+
}, p = (e) => e.status < 400, m = (e, t) => {
|
|
51
|
+
let n = typeof e == "number" ? e : Number(e);
|
|
52
|
+
return (Number.isFinite(n) && n >= 0 ? n : t) * 1e3;
|
|
53
|
+
}, h = ({ url: i = "", method: a = "get", mock: c, customHeaders: l = r, enabled: h = !0, credentials: g = "same-origin", cache: _ = !1, staleTime: v = 30, gcTime: y = 300, tags: b }) => {
|
|
54
|
+
let x = u(c), S = t(), C = n(() => {
|
|
55
|
+
if (x || !i) return;
|
|
56
|
+
let e = o({
|
|
63
57
|
method: a,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
status: 500,
|
|
70
|
-
data: e.message
|
|
71
|
-
})).finally(() => p(!1)));
|
|
58
|
+
url: i,
|
|
59
|
+
credentials: g,
|
|
60
|
+
headers: l
|
|
61
|
+
});
|
|
62
|
+
return _ ? e : `${e}#${S}`;
|
|
72
63
|
}, [
|
|
73
|
-
|
|
64
|
+
x,
|
|
74
65
|
i,
|
|
75
66
|
a,
|
|
76
|
-
|
|
77
|
-
s,
|
|
67
|
+
g,
|
|
78
68
|
l,
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
g();
|
|
83
|
-
}, [
|
|
84
|
-
u,
|
|
85
|
-
c,
|
|
86
|
-
s,
|
|
69
|
+
_,
|
|
70
|
+
S
|
|
71
|
+
]), w = e(() => f(i, a, g, l), [
|
|
87
72
|
i,
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
73
|
+
a,
|
|
74
|
+
g,
|
|
75
|
+
l
|
|
76
|
+
]), T = s({
|
|
77
|
+
key: C,
|
|
78
|
+
meta: {
|
|
79
|
+
url: i,
|
|
80
|
+
tags: b
|
|
81
|
+
},
|
|
82
|
+
fetcher: w,
|
|
83
|
+
enabled: h,
|
|
84
|
+
staleTime: _ ? m(v, 30) : 0,
|
|
85
|
+
gcTime: _ ? m(y, 300) : 0,
|
|
86
|
+
isCacheable: p
|
|
87
|
+
}), E = n(() => x ? d(c) : void 0, [x, c]), D = h && E ? E : T.data, O = !E && T.isFetching;
|
|
88
|
+
return {
|
|
89
|
+
isLoading: O && D === void 0,
|
|
90
|
+
isFetching: O,
|
|
91
|
+
data: D,
|
|
92
|
+
refetch: T.refetch,
|
|
93
|
+
isSuccess: !O && !!D && D.status < 400,
|
|
94
|
+
isError: !O && !!D && D.status >= 400
|
|
96
95
|
};
|
|
97
96
|
};
|
|
98
97
|
//#endregion
|
|
99
|
-
export {
|
|
98
|
+
export { l as DEFAULT_GC_TIME, c as DEFAULT_STALE_TIME, h as default };
|
|
@@ -1,34 +1,35 @@
|
|
|
1
1
|
import { useCallback as e } from "react";
|
|
2
2
|
import { authFailureFromResponse as t, reportAuthFailure as n } from "@plitzi/sdk-shared/auth";
|
|
3
|
+
import { invalidateQueries as r } from "@plitzi/sdk-shared/queries";
|
|
3
4
|
//#region src/elements/provider/ApiContainer/hooks/useProviderWrite.ts
|
|
4
|
-
var
|
|
5
|
-
let { action:
|
|
6
|
-
if (!
|
|
7
|
-
let
|
|
5
|
+
var i = ({ elementId: i, enabled: a, actionPath: o = "/_action", onDone: s }) => ({ writeRecord: e(async (e = {}) => {
|
|
6
|
+
let { action: c, recordId: l, ...u } = e;
|
|
7
|
+
if (!a || typeof c != "string" || !c) return;
|
|
8
|
+
let d = await fetch(o, {
|
|
8
9
|
method: "POST",
|
|
9
10
|
headers: { "Content-Type": "application/json" },
|
|
10
11
|
credentials: "same-origin",
|
|
11
12
|
body: JSON.stringify({
|
|
12
|
-
elementId:
|
|
13
|
-
action:
|
|
14
|
-
recordId:
|
|
15
|
-
values:
|
|
13
|
+
elementId: i,
|
|
14
|
+
action: c,
|
|
15
|
+
recordId: l,
|
|
16
|
+
values: u
|
|
16
17
|
})
|
|
17
18
|
});
|
|
18
|
-
if (!
|
|
19
|
-
let e = t(
|
|
19
|
+
if (!d.ok) {
|
|
20
|
+
let e = t(d.status, await d.json().catch(() => void 0));
|
|
20
21
|
throw e && n({
|
|
21
22
|
reason: e,
|
|
22
|
-
url:
|
|
23
|
-
}), Error(`Write failed with status ${
|
|
23
|
+
url: o
|
|
24
|
+
}), Error(`Write failed with status ${d.status}`);
|
|
24
25
|
}
|
|
25
|
-
let
|
|
26
|
-
return await
|
|
26
|
+
let f = await d.json();
|
|
27
|
+
return r(), await s?.(), f.record;
|
|
27
28
|
}, [
|
|
28
|
-
|
|
29
|
-
r,
|
|
29
|
+
o,
|
|
30
30
|
i,
|
|
31
|
-
|
|
31
|
+
a,
|
|
32
|
+
s
|
|
32
33
|
]) });
|
|
33
34
|
//#endregion
|
|
34
|
-
export {
|
|
35
|
+
export { i as default };
|
|
@@ -20,6 +20,9 @@ declare const ApiContainer: {
|
|
|
20
20
|
readonly pagination: "none";
|
|
21
21
|
readonly pageParam: "page";
|
|
22
22
|
readonly renderWhileLoading: false;
|
|
23
|
+
readonly cache: false;
|
|
24
|
+
readonly staleTime: 30;
|
|
25
|
+
readonly gcTime: 300;
|
|
23
26
|
};
|
|
24
27
|
readonly definition: {
|
|
25
28
|
readonly label: "Api Container";
|
package/dist/index.d.ts
CHANGED
|
@@ -3145,6 +3145,9 @@ export declare const defaultElements: {
|
|
|
3145
3145
|
readonly pagination: "none";
|
|
3146
3146
|
readonly pageParam: "page";
|
|
3147
3147
|
readonly renderWhileLoading: false;
|
|
3148
|
+
readonly cache: false;
|
|
3149
|
+
readonly staleTime: 30;
|
|
3150
|
+
readonly gcTime: 300;
|
|
3148
3151
|
};
|
|
3149
3152
|
readonly definition: {
|
|
3150
3153
|
readonly label: "Api Container";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plitzi/sdk-elements",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"license": "AGPL-3.0",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -984,15 +984,15 @@
|
|
|
984
984
|
"type": "module",
|
|
985
985
|
"sideEffects": false,
|
|
986
986
|
"dependencies": {
|
|
987
|
-
"@plitzi/nexus": "^1.
|
|
987
|
+
"@plitzi/nexus": "^1.2.0",
|
|
988
988
|
"@plitzi/plitzi-ui": "^1.6.21",
|
|
989
|
-
"@plitzi/sdk-auth": "0.
|
|
990
|
-
"@plitzi/sdk-dev-tools": "0.
|
|
991
|
-
"@plitzi/sdk-event-bridge": "0.
|
|
992
|
-
"@plitzi/sdk-interactions": "0.
|
|
993
|
-
"@plitzi/sdk-navigation": "0.
|
|
994
|
-
"@plitzi/sdk-schema": "0.
|
|
995
|
-
"@plitzi/sdk-shared": "0.
|
|
989
|
+
"@plitzi/sdk-auth": "0.36.0",
|
|
990
|
+
"@plitzi/sdk-dev-tools": "0.36.0",
|
|
991
|
+
"@plitzi/sdk-event-bridge": "0.36.0",
|
|
992
|
+
"@plitzi/sdk-interactions": "0.36.0",
|
|
993
|
+
"@plitzi/sdk-navigation": "0.36.0",
|
|
994
|
+
"@plitzi/sdk-schema": "0.36.0",
|
|
995
|
+
"@plitzi/sdk-shared": "0.36.0",
|
|
996
996
|
"clsx": "^2.1.1",
|
|
997
997
|
"immer": "^11.1.18"
|
|
998
998
|
},
|