@duke333/builder-ui 0.1.4 → 0.2.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/README.md +20 -32
- package/dist/{BuilderAdminPages-Buy2nvjs.d.ts → BuilderAdminPages-C-jaMLOa.d.ts} +6 -0
- package/dist/{RuntimeEntryDialog-DAO74GFp.d.ts → RuntimeEntryDialog-Bw741XbS.d.ts} +12 -5
- package/dist/admin/index.d.ts +2 -2
- package/dist/admin/index.js +30 -3
- package/dist/admin/index.js.map +1 -1
- package/dist/api/index.d.ts +5 -2
- package/dist/api/index.js +9 -1
- package/dist/api/index.js.map +1 -1
- package/dist/components/index.d.ts +5 -3
- package/dist/components/index.js +53 -25
- package/dist/components/index.js.map +1 -1
- package/dist/index.d.ts +2215 -10
- package/dist/index.js +1919 -1145
- package/dist/index.js.map +1 -1
- package/dist/integration/index.d.ts +3 -1
- package/dist/integration/index.js +45 -5
- package/dist/integration/index.js.map +1 -1
- package/dist/runtime/index.d.ts +3 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/styles.css +405 -0
- package/dist/styles.css.map +1 -0
- package/dist/styles.d.ts +2 -0
- package/package.json +10 -2
package/dist/index.js
CHANGED
|
@@ -1,138 +1,1257 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return (fields ?? []).join("\n");
|
|
16
|
-
}
|
|
17
|
-
function builderEditorTextToSearchFields(value) {
|
|
18
|
-
const fields = (value ?? "").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
19
|
-
return fields.length > 0 ? fields : void 0;
|
|
20
|
-
}
|
|
21
|
-
function getBuilderEditorTriggerRoute(config) {
|
|
22
|
-
const route = config.route ?? config.path ?? config.url;
|
|
23
|
-
return typeof route === "string" ? route : "";
|
|
24
|
-
}
|
|
25
|
-
function valuesFromTriggers(triggers) {
|
|
26
|
-
return triggers.filter((trigger) => trigger.action === "callApi" || trigger.action === "webhook").map((trigger) => ({
|
|
27
|
-
event: trigger.event,
|
|
28
|
-
route: getBuilderEditorTriggerRoute(trigger.config),
|
|
29
|
-
enabled: trigger.enabled,
|
|
30
|
-
blocking: trigger.blocking
|
|
31
|
-
})).filter((trigger) => trigger.route);
|
|
32
|
-
}
|
|
33
|
-
function valuesFromFieldTriggers(triggers) {
|
|
34
|
-
return (triggers ?? []).map((trigger) => ({
|
|
35
|
-
event: trigger.event,
|
|
36
|
-
action: trigger.action,
|
|
37
|
-
enabled: trigger.enabled,
|
|
38
|
-
debounceMs: trigger.debounceMs
|
|
39
|
-
}));
|
|
1
|
+
// src/ready/BuilderProvider.tsx
|
|
2
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
3
|
+
import {
|
|
4
|
+
createContext,
|
|
5
|
+
useCallback,
|
|
6
|
+
useContext,
|
|
7
|
+
useMemo,
|
|
8
|
+
useRef,
|
|
9
|
+
useState
|
|
10
|
+
} from "react";
|
|
11
|
+
|
|
12
|
+
// src/api/createBuilderApiClient.ts
|
|
13
|
+
function queryParams(query) {
|
|
14
|
+
return { ...query };
|
|
40
15
|
}
|
|
41
|
-
function
|
|
42
|
-
|
|
43
|
-
|
|
16
|
+
function fieldOptionsQueryParams(query) {
|
|
17
|
+
const flatQuery = { search: query.search };
|
|
18
|
+
for (const [key, value] of Object.entries(query.depends ?? {})) {
|
|
19
|
+
flatQuery[`depends.${key}`] = value;
|
|
20
|
+
}
|
|
21
|
+
return flatQuery;
|
|
44
22
|
}
|
|
45
|
-
function
|
|
46
|
-
|
|
47
|
-
|
|
23
|
+
function createBuilderApiClient(rootTransport, options = {}) {
|
|
24
|
+
const basePath = options.apiBasePath?.trim().replace(/\/+$/g, "") ?? "";
|
|
25
|
+
const path = (value) => `${basePath}${value}`;
|
|
26
|
+
const transport = {
|
|
27
|
+
get: (value, requestOptions) => rootTransport.get(path(value), requestOptions),
|
|
28
|
+
post: (value, body, requestOptions) => rootTransport.post(path(value), body, requestOptions),
|
|
29
|
+
patch: (value, body, requestOptions) => rootTransport.patch(path(value), body, requestOptions),
|
|
30
|
+
delete: (value, requestOptions) => rootTransport.delete(path(value), requestOptions)
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
listBuilderForms: (query) => transport.get("/builder/forms", {
|
|
34
|
+
query: queryParams(query)
|
|
35
|
+
}),
|
|
36
|
+
listBuilderDbTables: () => transport.get("/builder/datasources/tables"),
|
|
37
|
+
listBuilderFormOptions: () => transport.get("/builder/forms/options"),
|
|
38
|
+
getBuilderForm: (id) => transport.get(`/builder/forms/${encodeURIComponent(id)}`),
|
|
39
|
+
createBuilderForm: (input) => transport.post("/builder/forms", input),
|
|
40
|
+
updateBuilderForm: (id, input) => transport.patch(`/builder/forms/${encodeURIComponent(id)}`, input),
|
|
41
|
+
replicateBuilderForm: (id, input) => transport.post(`/builder/forms/${encodeURIComponent(id)}/replicate`, input),
|
|
42
|
+
deleteBuilderForm: (id) => transport.delete(`/builder/forms/${encodeURIComponent(id)}`),
|
|
43
|
+
listBuilderLists: (query) => transport.get("/builder/lists", {
|
|
44
|
+
query: queryParams(query)
|
|
45
|
+
}),
|
|
46
|
+
listBuilderListOptions: () => transport.get("/builder/lists/options"),
|
|
47
|
+
getBuilderList: (id) => transport.get(`/builder/lists/${encodeURIComponent(id)}`),
|
|
48
|
+
createBuilderList: (input) => transport.post("/builder/lists", input),
|
|
49
|
+
updateBuilderList: (id, input) => transport.patch(`/builder/lists/${encodeURIComponent(id)}`, input),
|
|
50
|
+
replicateBuilderList: (id, input) => transport.post(`/builder/lists/${encodeURIComponent(id)}/replicate`, input),
|
|
51
|
+
deleteBuilderList: (id) => transport.delete(`/builder/lists/${encodeURIComponent(id)}`),
|
|
52
|
+
listBuilderViews: (query) => transport.get("/builder/views", {
|
|
53
|
+
query: queryParams(query)
|
|
54
|
+
}),
|
|
55
|
+
getBuilderView: (id) => transport.get(`/builder/views/${encodeURIComponent(id)}`),
|
|
56
|
+
createBuilderView: (input) => transport.post("/builder/views", input),
|
|
57
|
+
updateBuilderView: (id, input) => transport.patch(`/builder/views/${encodeURIComponent(id)}`, input),
|
|
58
|
+
replicateBuilderView: (id, input) => transport.post(`/builder/views/${encodeURIComponent(id)}/replicate`, input),
|
|
59
|
+
deleteBuilderView: (id) => transport.delete(`/builder/views/${encodeURIComponent(id)}`),
|
|
60
|
+
getRuntimeBuilderForm: (id) => transport.get(`/builder/runtime/forms/${encodeURIComponent(id)}`),
|
|
61
|
+
createRuntimeBuilderFormEntry: (formId, input) => transport.post(
|
|
62
|
+
`/builder/runtime/forms/${encodeURIComponent(formId)}/entries`,
|
|
63
|
+
input
|
|
64
|
+
),
|
|
65
|
+
listRuntimeBuilderFormFieldOptions: (formId, fieldKey, query) => transport.get(
|
|
66
|
+
`/builder/runtime/forms/${encodeURIComponent(formId)}/fields/${encodeURIComponent(fieldKey)}/options`,
|
|
67
|
+
{ query: fieldOptionsQueryParams(query) }
|
|
68
|
+
),
|
|
69
|
+
runRuntimeBuilderFormFieldTrigger: (formId, fieldKey, event, input) => transport.post(
|
|
70
|
+
`/builder/runtime/forms/${encodeURIComponent(formId)}/fields/${encodeURIComponent(fieldKey)}/triggers/${encodeURIComponent(event)}`,
|
|
71
|
+
input
|
|
72
|
+
),
|
|
73
|
+
getRuntimeBuilderList: (id) => transport.get(`/builder/runtime/lists/${encodeURIComponent(id)}`),
|
|
74
|
+
listRuntimeBuilderListEntries: (listId, query) => transport.get(
|
|
75
|
+
`/builder/runtime/lists/${encodeURIComponent(listId)}/entries`,
|
|
76
|
+
{ query: queryParams(query) }
|
|
77
|
+
),
|
|
78
|
+
getRuntimeBuilderView: (id) => transport.get(`/builder/runtime/views/${encodeURIComponent(id)}`),
|
|
79
|
+
runRuntimeBuilderViewFieldTrigger: (viewId, fieldKey, event, input) => transport.post(
|
|
80
|
+
`/builder/runtime/views/${encodeURIComponent(viewId)}/fields/${encodeURIComponent(fieldKey)}/triggers/${encodeURIComponent(event)}`,
|
|
81
|
+
input
|
|
82
|
+
),
|
|
83
|
+
listBuilderViewEntries: (viewId, query) => transport.get(
|
|
84
|
+
`/builder/runtime/views/${encodeURIComponent(viewId)}/entries`,
|
|
85
|
+
{ query: queryParams(query) }
|
|
86
|
+
),
|
|
87
|
+
createBuilderViewEntry: (viewId, input) => transport.post(
|
|
88
|
+
`/builder/runtime/views/${encodeURIComponent(viewId)}/entries`,
|
|
89
|
+
input
|
|
90
|
+
),
|
|
91
|
+
createCompositeBuilderViewEntry: (viewId, input) => transport.post(
|
|
92
|
+
`/builder/runtime/views/${encodeURIComponent(viewId)}/composite-entries`,
|
|
93
|
+
input
|
|
94
|
+
),
|
|
95
|
+
updateCompositeBuilderViewEntry: (viewId, id, input) => transport.patch(
|
|
96
|
+
`/builder/runtime/views/${encodeURIComponent(viewId)}/composite-entries/${encodeURIComponent(id)}`,
|
|
97
|
+
input
|
|
98
|
+
),
|
|
99
|
+
updateBuilderViewEntry: (viewId, id, input) => transport.patch(
|
|
100
|
+
`/builder/runtime/views/${encodeURIComponent(viewId)}/entries/${encodeURIComponent(id)}`,
|
|
101
|
+
input
|
|
102
|
+
),
|
|
103
|
+
deleteBuilderViewEntry: (viewId, id) => transport.delete(
|
|
104
|
+
`/builder/runtime/views/${encodeURIComponent(viewId)}/entries/${encodeURIComponent(id)}`
|
|
105
|
+
)
|
|
106
|
+
};
|
|
48
107
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
108
|
+
|
|
109
|
+
// src/hooks/createBuilderHooks.ts
|
|
110
|
+
import { keepPreviousData, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
111
|
+
function createBuilderKeys() {
|
|
112
|
+
const builderKeys = {
|
|
113
|
+
forms: ["builder", "forms"],
|
|
114
|
+
dbTables: () => ["builder", "datasources", "tables"],
|
|
115
|
+
formList: (query) => [...builderKeys.forms, "list", query],
|
|
116
|
+
form: (id) => [...builderKeys.forms, "detail", id],
|
|
117
|
+
formOptions: () => [...builderKeys.forms, "options"],
|
|
118
|
+
lists: ["builder", "lists"],
|
|
119
|
+
listList: (query) => [...builderKeys.lists, "list", query],
|
|
120
|
+
list: (id) => [...builderKeys.lists, "detail", id],
|
|
121
|
+
listOptions: () => [...builderKeys.lists, "options"],
|
|
122
|
+
views: ["builder", "views"],
|
|
123
|
+
viewList: (query) => [...builderKeys.views, "list", query],
|
|
124
|
+
view: (id) => [...builderKeys.views, "detail", id],
|
|
125
|
+
runtimeForm: (id) => ["builder", "runtime", "form", id],
|
|
126
|
+
runtimeFieldOptions: (formId, fieldKey, query) => [...builderKeys.runtimeForm(formId), "fields", fieldKey, "options", query],
|
|
127
|
+
runtimeFormEntries: (id) => [...builderKeys.runtimeForm(id), "entries"],
|
|
128
|
+
runtimeList: (id) => ["builder", "runtime", "list", id],
|
|
129
|
+
runtimeListEntries: (id, query) => [...builderKeys.runtimeList(id), "entries", query],
|
|
130
|
+
runtimeView: (id) => ["builder", "runtime", "view", id],
|
|
131
|
+
entries: (id, query) => [...builderKeys.runtimeView(id), "entries", query]
|
|
132
|
+
};
|
|
133
|
+
return builderKeys;
|
|
64
134
|
}
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
135
|
+
function createBuilderHooks(client) {
|
|
136
|
+
const builderKeys = createBuilderKeys();
|
|
137
|
+
function invalidateRuntimeViewEntries(queryClient, viewId) {
|
|
138
|
+
return Promise.all([
|
|
139
|
+
queryClient.invalidateQueries({ queryKey: builderKeys.runtimeView(viewId) }),
|
|
140
|
+
queryClient.invalidateQueries({ queryKey: [...builderKeys.runtimeView(viewId), "entries"] })
|
|
141
|
+
]);
|
|
142
|
+
}
|
|
143
|
+
function useBuilderDbTables() {
|
|
144
|
+
return useQuery({ queryKey: builderKeys.dbTables(), queryFn: client.listBuilderDbTables });
|
|
145
|
+
}
|
|
146
|
+
function useBuilderForms(query) {
|
|
147
|
+
return useQuery({
|
|
148
|
+
queryKey: builderKeys.formList(query),
|
|
149
|
+
queryFn: () => client.listBuilderForms(query),
|
|
150
|
+
placeholderData: keepPreviousData
|
|
81
151
|
});
|
|
82
|
-
return {
|
|
83
|
-
id: group.id || `group${index + 1}`,
|
|
84
|
-
title: group.title || `Group ${index + 1}`,
|
|
85
|
-
columns,
|
|
86
|
-
fields: groupFields
|
|
87
|
-
};
|
|
88
|
-
}).filter((group) => group.fields.length > 0 || group.title.trim());
|
|
89
|
-
const missingFields = layoutItems.filter((item) => !usedKeys.has(item.key));
|
|
90
|
-
if (normalized.length === 0) {
|
|
91
|
-
return builderFormEditorDefaultLayoutGroups(fields, subforms);
|
|
92
152
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
columns: 12,
|
|
98
|
-
fields: missingFields
|
|
153
|
+
function useBuilderFormOptions() {
|
|
154
|
+
return useQuery({
|
|
155
|
+
queryKey: builderKeys.formOptions(),
|
|
156
|
+
queryFn: client.listBuilderFormOptions
|
|
99
157
|
});
|
|
100
158
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
159
|
+
function useBuilderForm(id) {
|
|
160
|
+
return useQuery({
|
|
161
|
+
queryKey: builderKeys.form(id ?? ""),
|
|
162
|
+
queryFn: () => client.getBuilderForm(id ?? ""),
|
|
163
|
+
enabled: Boolean(id)
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
function useSaveBuilderForm() {
|
|
167
|
+
const queryClient = useQueryClient();
|
|
168
|
+
return useMutation({
|
|
169
|
+
mutationFn: ({ id, input }) => id ? client.updateBuilderForm(id, input) : client.createBuilderForm(input),
|
|
170
|
+
onSuccess: (form) => {
|
|
171
|
+
queryClient.invalidateQueries({ queryKey: builderKeys.forms });
|
|
172
|
+
queryClient.invalidateQueries({ queryKey: builderKeys.form(form.id) });
|
|
173
|
+
queryClient.invalidateQueries({ queryKey: builderKeys.runtimeForm(form.id) });
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
function useReplicateBuilderForm() {
|
|
178
|
+
const queryClient = useQueryClient();
|
|
179
|
+
return useMutation({
|
|
180
|
+
mutationFn: ({ id, input }) => client.replicateBuilderForm(id, input),
|
|
181
|
+
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.forms })
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function useDeleteBuilderForm() {
|
|
185
|
+
const queryClient = useQueryClient();
|
|
186
|
+
return useMutation({
|
|
187
|
+
mutationFn: client.deleteBuilderForm,
|
|
188
|
+
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.forms })
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
function useBuilderLists(query) {
|
|
192
|
+
return useQuery({
|
|
193
|
+
queryKey: builderKeys.listList(query),
|
|
194
|
+
queryFn: () => client.listBuilderLists(query),
|
|
195
|
+
placeholderData: keepPreviousData
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
function useBuilderListOptions() {
|
|
199
|
+
return useQuery({
|
|
200
|
+
queryKey: builderKeys.listOptions(),
|
|
201
|
+
queryFn: client.listBuilderListOptions
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function useBuilderList(id) {
|
|
205
|
+
return useQuery({
|
|
206
|
+
queryKey: builderKeys.list(id ?? ""),
|
|
207
|
+
queryFn: () => client.getBuilderList(id ?? ""),
|
|
208
|
+
enabled: Boolean(id)
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
function useSaveBuilderList() {
|
|
212
|
+
const queryClient = useQueryClient();
|
|
213
|
+
return useMutation({
|
|
214
|
+
mutationFn: ({ id, input }) => id ? client.updateBuilderList(id, input) : client.createBuilderList(input),
|
|
215
|
+
onSuccess: (list) => {
|
|
216
|
+
queryClient.invalidateQueries({ queryKey: builderKeys.lists });
|
|
217
|
+
queryClient.invalidateQueries({ queryKey: builderKeys.list(list.id) });
|
|
218
|
+
queryClient.invalidateQueries({ queryKey: builderKeys.runtimeList(list.id) });
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
function useReplicateBuilderList() {
|
|
223
|
+
const queryClient = useQueryClient();
|
|
224
|
+
return useMutation({
|
|
225
|
+
mutationFn: ({ id, input }) => client.replicateBuilderList(id, input),
|
|
226
|
+
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.lists })
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function useDeleteBuilderList() {
|
|
230
|
+
const queryClient = useQueryClient();
|
|
231
|
+
return useMutation({
|
|
232
|
+
mutationFn: client.deleteBuilderList,
|
|
233
|
+
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.lists })
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
function useBuilderViews(query) {
|
|
237
|
+
return useQuery({
|
|
238
|
+
queryKey: builderKeys.viewList(query),
|
|
239
|
+
queryFn: () => client.listBuilderViews(query),
|
|
240
|
+
placeholderData: keepPreviousData
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
function useBuilderView(id) {
|
|
244
|
+
return useQuery({
|
|
245
|
+
queryKey: builderKeys.view(id ?? ""),
|
|
246
|
+
queryFn: () => client.getBuilderView(id ?? ""),
|
|
247
|
+
enabled: Boolean(id)
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
function useSaveBuilderView() {
|
|
251
|
+
const queryClient = useQueryClient();
|
|
252
|
+
return useMutation({
|
|
253
|
+
mutationFn: ({ id, input }) => id ? client.updateBuilderView(id, input) : client.createBuilderView(input),
|
|
254
|
+
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.views })
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
function useReplicateBuilderView() {
|
|
258
|
+
const queryClient = useQueryClient();
|
|
259
|
+
return useMutation({
|
|
260
|
+
mutationFn: ({ id, input }) => client.replicateBuilderView(id, input),
|
|
261
|
+
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.views })
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
function useDeleteBuilderView() {
|
|
265
|
+
const queryClient = useQueryClient();
|
|
266
|
+
return useMutation({
|
|
267
|
+
mutationFn: client.deleteBuilderView,
|
|
268
|
+
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.views })
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
function useRuntimeBuilderForm(id) {
|
|
272
|
+
return useQuery({
|
|
273
|
+
queryKey: builderKeys.runtimeForm(id),
|
|
274
|
+
queryFn: () => client.getRuntimeBuilderForm(id)
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
function useRuntimeBuilderFormFieldOptions(formId, fieldKey, query, enabled = true) {
|
|
278
|
+
return useQuery({
|
|
279
|
+
queryKey: builderKeys.runtimeFieldOptions(formId ?? "", fieldKey, query),
|
|
280
|
+
queryFn: () => client.listRuntimeBuilderFormFieldOptions(formId ?? "", fieldKey, query),
|
|
281
|
+
enabled: Boolean(formId) && enabled
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
function useRunRuntimeBuilderFieldTrigger() {
|
|
285
|
+
return useMutation({
|
|
286
|
+
mutationFn: (args) => {
|
|
287
|
+
if (args.viewId) {
|
|
288
|
+
return client.runRuntimeBuilderViewFieldTrigger(
|
|
289
|
+
args.viewId,
|
|
290
|
+
args.fieldKey,
|
|
291
|
+
args.event,
|
|
292
|
+
args.input
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
if (args.formId) {
|
|
296
|
+
return client.runRuntimeBuilderFormFieldTrigger(
|
|
297
|
+
args.formId,
|
|
298
|
+
args.fieldKey,
|
|
299
|
+
args.event,
|
|
300
|
+
args.input
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
throw new Error("formId \u044D\u0441\u0432\u044D\u043B viewId \u0448\u0430\u0430\u0440\u0434\u043B\u0430\u0433\u0430\u0442\u0430\u0439");
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
function useRuntimeBuilderList(id) {
|
|
308
|
+
return useQuery({
|
|
309
|
+
queryKey: builderKeys.runtimeList(id),
|
|
310
|
+
queryFn: () => client.getRuntimeBuilderList(id)
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
function useRuntimeBuilderListEntries(id, query) {
|
|
314
|
+
return useQuery({
|
|
315
|
+
queryKey: builderKeys.runtimeListEntries(id, query),
|
|
316
|
+
queryFn: () => client.listRuntimeBuilderListEntries(id, query),
|
|
317
|
+
placeholderData: keepPreviousData
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
function useSaveRuntimeBuilderFormEntry(formId) {
|
|
321
|
+
const queryClient = useQueryClient();
|
|
322
|
+
return useMutation({
|
|
323
|
+
mutationFn: (input) => client.createRuntimeBuilderFormEntry(formId, input),
|
|
324
|
+
onSuccess: () => {
|
|
325
|
+
queryClient.invalidateQueries({ queryKey: builderKeys.runtimeFormEntries(formId) });
|
|
326
|
+
queryClient.invalidateQueries({ queryKey: builderKeys.runtimeForm(formId) });
|
|
327
|
+
queryClient.invalidateQueries({ queryKey: ["builder", "runtime", "list"] });
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
function useRuntimeBuilderView(id, enabled = true) {
|
|
332
|
+
return useQuery({
|
|
333
|
+
queryKey: builderKeys.runtimeView(id),
|
|
334
|
+
queryFn: () => client.getRuntimeBuilderView(id),
|
|
335
|
+
enabled: Boolean(id) && enabled
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
function useBuilderViewEntries(id, query, enabled = true) {
|
|
339
|
+
return useQuery({
|
|
340
|
+
queryKey: builderKeys.entries(id, query),
|
|
341
|
+
queryFn: () => client.listBuilderViewEntries(id, query),
|
|
342
|
+
placeholderData: keepPreviousData,
|
|
343
|
+
enabled: Boolean(id) && enabled
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
function useSaveBuilderViewEntry(viewId) {
|
|
347
|
+
const queryClient = useQueryClient();
|
|
348
|
+
return useMutation({
|
|
349
|
+
mutationFn: ({ id, input }) => id ? client.updateBuilderViewEntry(viewId, id, input) : client.createBuilderViewEntry(
|
|
350
|
+
viewId,
|
|
351
|
+
input
|
|
352
|
+
),
|
|
353
|
+
onSuccess: () => invalidateRuntimeViewEntries(queryClient, viewId)
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
function useCreateCompositeBuilderViewEntry(viewId) {
|
|
357
|
+
const queryClient = useQueryClient();
|
|
358
|
+
return useMutation({
|
|
359
|
+
mutationFn: (input) => client.createCompositeBuilderViewEntry(viewId, input),
|
|
360
|
+
onSuccess: () => invalidateRuntimeViewEntries(queryClient, viewId)
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
function useUpdateCompositeBuilderViewEntry(viewId) {
|
|
364
|
+
const queryClient = useQueryClient();
|
|
365
|
+
return useMutation({
|
|
366
|
+
mutationFn: ({
|
|
367
|
+
id,
|
|
368
|
+
input
|
|
369
|
+
}) => client.updateCompositeBuilderViewEntry(viewId, id, input),
|
|
370
|
+
onSuccess: () => invalidateRuntimeViewEntries(queryClient, viewId)
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
function useDeleteBuilderViewEntry(id) {
|
|
374
|
+
const queryClient = useQueryClient();
|
|
375
|
+
return useMutation({
|
|
376
|
+
mutationFn: (entryId) => client.deleteBuilderViewEntry(id, entryId),
|
|
377
|
+
onSuccess: () => invalidateRuntimeViewEntries(queryClient, id)
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
return {
|
|
381
|
+
builderKeys,
|
|
382
|
+
useBuilderDbTables,
|
|
383
|
+
useBuilderForm,
|
|
384
|
+
useBuilderFormOptions,
|
|
385
|
+
useBuilderForms,
|
|
386
|
+
useBuilderList,
|
|
387
|
+
useBuilderListOptions,
|
|
388
|
+
useBuilderLists,
|
|
389
|
+
useBuilderViewEntries,
|
|
390
|
+
useBuilderView,
|
|
391
|
+
useBuilderViews,
|
|
392
|
+
useDeleteBuilderForm,
|
|
393
|
+
useDeleteBuilderList,
|
|
394
|
+
useDeleteBuilderView,
|
|
395
|
+
useDeleteBuilderViewEntry,
|
|
396
|
+
useCreateCompositeBuilderViewEntry,
|
|
397
|
+
useReplicateBuilderForm,
|
|
398
|
+
useReplicateBuilderList,
|
|
399
|
+
useReplicateBuilderView,
|
|
400
|
+
useRuntimeBuilderForm,
|
|
401
|
+
useRuntimeBuilderFormFieldOptions,
|
|
402
|
+
useRuntimeBuilderList,
|
|
403
|
+
useRuntimeBuilderListEntries,
|
|
404
|
+
useRuntimeBuilderView,
|
|
405
|
+
useRunRuntimeBuilderFieldTrigger,
|
|
406
|
+
useSaveBuilderForm,
|
|
407
|
+
useSaveBuilderList,
|
|
408
|
+
useSaveBuilderView,
|
|
409
|
+
useSaveBuilderViewEntry,
|
|
410
|
+
useSaveRuntimeBuilderFormEntry,
|
|
411
|
+
useUpdateCompositeBuilderViewEntry
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// src/ready/BuilderProvider.tsx
|
|
416
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
417
|
+
function createBuilderClient({ transport, apiBasePath }) {
|
|
418
|
+
return createBuilderApiClient(transport, { apiBasePath });
|
|
419
|
+
}
|
|
420
|
+
var BuilderContext = createContext(null);
|
|
421
|
+
function BuilderProvider({
|
|
422
|
+
children,
|
|
423
|
+
client: configuredClient,
|
|
424
|
+
transport,
|
|
425
|
+
apiBasePath,
|
|
426
|
+
queryClient,
|
|
427
|
+
onNotify
|
|
428
|
+
}) {
|
|
429
|
+
if (!configuredClient && !transport) {
|
|
430
|
+
throw new Error("BuilderProvider-\u0434 client \u044D\u0441\u0432\u044D\u043B transport \u04E9\u0433\u043D\u04E9 \u04AF\u04AF.");
|
|
431
|
+
}
|
|
432
|
+
const internalClient = useMemo(
|
|
433
|
+
() => configuredClient ?? createBuilderClient({ transport, apiBasePath }),
|
|
434
|
+
[apiBasePath, configuredClient, transport]
|
|
435
|
+
);
|
|
436
|
+
const hooks = useMemo(() => createBuilderHooks(internalClient), [internalClient]);
|
|
437
|
+
const [notifications, setNotifications] = useState([]);
|
|
438
|
+
const notificationId = useRef(0);
|
|
439
|
+
const notify = useCallback((notification) => {
|
|
440
|
+
const id = ++notificationId.current;
|
|
441
|
+
setNotifications((current) => [...current.slice(-2), { ...notification, id }]);
|
|
442
|
+
onNotify?.(notification);
|
|
443
|
+
}, [onNotify]);
|
|
444
|
+
const internalQueryClient = useRef(null);
|
|
445
|
+
if (!internalQueryClient.current) internalQueryClient.current = queryClient ?? new QueryClient();
|
|
446
|
+
const value = useMemo(
|
|
447
|
+
() => ({ client: internalClient, hooks, notify }),
|
|
448
|
+
[hooks, internalClient, notify]
|
|
449
|
+
);
|
|
450
|
+
return /* @__PURE__ */ jsx(QueryClientProvider, { client: internalQueryClient.current, children: /* @__PURE__ */ jsxs(BuilderContext.Provider, { value, children: [
|
|
451
|
+
children,
|
|
452
|
+
/* @__PURE__ */ jsx("div", { className: "builder-notifications", "aria-live": "polite", "aria-atomic": "true", children: notifications.map((notification) => /* @__PURE__ */ jsxs("div", { className: `builder-notification builder-notification--${notification.type}`, children: [
|
|
453
|
+
/* @__PURE__ */ jsx("span", { children: notification.message }),
|
|
454
|
+
/* @__PURE__ */ jsx("button", { type: "button", "aria-label": "\u041C\u044D\u0434\u044D\u0433\u0434\u044D\u043B \u0445\u0430\u0430\u0445", onClick: () => setNotifications((current) => current.filter((item) => item.id !== notification.id)), children: "\xD7" })
|
|
455
|
+
] }, notification.id)) })
|
|
456
|
+
] }) });
|
|
457
|
+
}
|
|
458
|
+
function useBuilderRuntime() {
|
|
459
|
+
const context = useContext(BuilderContext);
|
|
460
|
+
if (!context) throw new Error("Builder component-\u0438\u0439\u0433 BuilderProvider \u0434\u043E\u0442\u043E\u0440 render \u0445\u0438\u0439\u043D\u044D \u04AF\u04AF.");
|
|
461
|
+
return context;
|
|
462
|
+
}
|
|
463
|
+
function builderErrorMessage(error, fallback) {
|
|
464
|
+
if (error instanceof Error && error.message.trim()) return error.message;
|
|
465
|
+
return fallback;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// src/ready/BuilderRuntimeComponents.tsx
|
|
469
|
+
import { useMemo as useMemo4, useState as useState4 } from "react";
|
|
470
|
+
import { FormProvider as FormProvider2, useForm as useForm2 } from "react-hook-form";
|
|
471
|
+
|
|
472
|
+
// src/runtime/runtimeUtils.ts
|
|
473
|
+
function emptyFieldValue(field) {
|
|
474
|
+
return field.type === "checkbox" ? false : "";
|
|
475
|
+
}
|
|
476
|
+
function createBuilderFormDefaultValues(schema) {
|
|
477
|
+
const values = {};
|
|
478
|
+
for (const field of schema?.fields ?? []) {
|
|
479
|
+
values[field.key] = emptyFieldValue(field);
|
|
480
|
+
}
|
|
481
|
+
return { values };
|
|
482
|
+
}
|
|
483
|
+
function createBuilderEntryDefaultValues(view, editing) {
|
|
484
|
+
const values = {};
|
|
485
|
+
for (const field of view.form?.schema.fields ?? []) {
|
|
486
|
+
const existing = editing?.values[field.key];
|
|
487
|
+
values[field.key] = existing === void 0 ? emptyFieldValue(field) : existing;
|
|
488
|
+
}
|
|
489
|
+
return { values, version: editing?.version ?? 0 };
|
|
490
|
+
}
|
|
491
|
+
function formatBuilderRuntimeValue(value, locale = "mn-MN") {
|
|
492
|
+
if (value === null || value === void 0 || value === "") return "\u2014";
|
|
493
|
+
if (typeof value === "boolean") return value ? "\u0422\u0438\u0439\u043C" : "\u04AE\u0433\u04AF\u0439";
|
|
494
|
+
if (typeof value === "number") return new Intl.NumberFormat(locale).format(value);
|
|
495
|
+
return String(value);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// src/ready/ReadyFields.tsx
|
|
499
|
+
import { useRef as useRef2 } from "react";
|
|
500
|
+
import { useFormContext, useWatch } from "react-hook-form";
|
|
501
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
502
|
+
function inputType(field) {
|
|
503
|
+
if (field.type === "date") return "date";
|
|
504
|
+
if (field.type === "number" || field.type === "money") return "number";
|
|
505
|
+
return "text";
|
|
506
|
+
}
|
|
507
|
+
function ReadyField({ field, formId, viewId }) {
|
|
508
|
+
const { hooks, notify } = useBuilderRuntime();
|
|
509
|
+
const form = useFormContext();
|
|
510
|
+
const values = useWatch({ control: form.control, name: "values" }) ?? {};
|
|
511
|
+
const timer = useRef2(null);
|
|
512
|
+
const source = field.optionsSource;
|
|
513
|
+
const dependencyValue = source?.filterBy ? values[source.filterBy.valueFromField] : void 0;
|
|
514
|
+
const depends = source?.filterBy && dependencyValue != null ? { [source.filterBy.valueFromField]: String(dependencyValue) } : void 0;
|
|
515
|
+
const optionsQuery = hooks.useRuntimeBuilderFormFieldOptions(
|
|
516
|
+
formId,
|
|
517
|
+
field.key,
|
|
518
|
+
{ depends },
|
|
519
|
+
Boolean(source)
|
|
520
|
+
);
|
|
521
|
+
const trigger = hooks.useRunRuntimeBuilderFieldTrigger();
|
|
522
|
+
const name = `values.${field.key}`;
|
|
523
|
+
if (field.hidden) return null;
|
|
524
|
+
const runTrigger = (event, value) => {
|
|
525
|
+
const definition = field.triggers.find((item) => item.enabled && item.event === event);
|
|
526
|
+
if (!definition) return;
|
|
527
|
+
const execute = async () => {
|
|
528
|
+
try {
|
|
529
|
+
const response = await trigger.mutateAsync({
|
|
530
|
+
formId,
|
|
531
|
+
viewId,
|
|
532
|
+
fieldKey: field.key,
|
|
533
|
+
event,
|
|
534
|
+
input: { value, values: form.getValues("values") }
|
|
535
|
+
});
|
|
536
|
+
for (const [key, patchedValue] of Object.entries(response.valuesPatch)) {
|
|
537
|
+
form.setValue(`values.${key}`, patchedValue, { shouldDirty: true, shouldValidate: true });
|
|
538
|
+
}
|
|
539
|
+
for (const [key, message] of Object.entries(response.fieldErrors)) {
|
|
540
|
+
form.setError(`values.${key}`, { message });
|
|
541
|
+
}
|
|
542
|
+
if (response.toast?.message) notify(response.toast);
|
|
543
|
+
} catch (error2) {
|
|
544
|
+
notify({ type: "error", message: builderErrorMessage(error2, "Field action \u0430\u0436\u0438\u043B\u043B\u0430\u0441\u0430\u043D\u0433\u04AF\u0439") });
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
if (event === "onChange" && definition.debounceMs > 0) {
|
|
548
|
+
if (timer.current) clearTimeout(timer.current);
|
|
549
|
+
timer.current = setTimeout(() => void execute(), definition.debounceMs);
|
|
550
|
+
} else {
|
|
551
|
+
void execute();
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
const registration = form.register(name, {
|
|
555
|
+
required: field.required ? `${field.label} \u0448\u0430\u0430\u0440\u0434\u043B\u0430\u0433\u0430\u0442\u0430\u0439` : false,
|
|
556
|
+
setValueAs: field.type === "number" || field.type === "money" ? (value) => value === "" ? "" : Number(value) : void 0,
|
|
557
|
+
onChange: (event) => runTrigger("onChange", event.target.type === "checkbox" ? event.target.checked : event.target.value),
|
|
558
|
+
onBlur: (event) => runTrigger("onBlur", event.target.value)
|
|
559
|
+
});
|
|
560
|
+
const error = form.formState.errors.values?.[field.key];
|
|
561
|
+
const options = source ? optionsQuery.data ?? [] : field.options ?? [];
|
|
562
|
+
return /* @__PURE__ */ jsxs2("label", { className: "builder-field", children: [
|
|
563
|
+
/* @__PURE__ */ jsxs2("span", { className: "builder-field__label", children: [
|
|
564
|
+
field.label,
|
|
565
|
+
field.required ? /* @__PURE__ */ jsx2("span", { "aria-hidden": "true", children: " *" }) : null
|
|
566
|
+
] }),
|
|
567
|
+
field.type === "textarea" ? /* @__PURE__ */ jsx2("textarea", { className: "builder-input builder-textarea", placeholder: field.placeholder, disabled: field.disabled, ...registration }) : field.type === "select" ? /* @__PURE__ */ jsxs2("select", { className: "builder-input", disabled: field.disabled || optionsQuery.isPending, ...registration, children: [
|
|
568
|
+
/* @__PURE__ */ jsx2("option", { value: "", children: field.placeholder ?? "\u0421\u043E\u043D\u0433\u043E\u0445" }),
|
|
569
|
+
options.map((option) => /* @__PURE__ */ jsx2("option", { value: option.value, children: option.label }, option.value))
|
|
570
|
+
] }) : field.type === "checkbox" ? /* @__PURE__ */ jsx2("input", { className: "builder-checkbox", type: "checkbox", disabled: field.disabled, ...registration }) : /* @__PURE__ */ jsx2("input", { className: "builder-input", type: inputType(field), placeholder: field.placeholder, disabled: field.disabled, ...registration }),
|
|
571
|
+
field.description ? /* @__PURE__ */ jsx2("small", { className: "builder-field__description", children: field.description }) : null,
|
|
572
|
+
typeof error?.message === "string" ? /* @__PURE__ */ jsx2("small", { className: "builder-field__error", children: error.message }) : null
|
|
573
|
+
] });
|
|
574
|
+
}
|
|
575
|
+
function ReadyFields({ formId, viewId, schema, extraItems = [] }) {
|
|
576
|
+
const fields = new Map(schema.fields.map((field) => [field.key, field]));
|
|
577
|
+
const rendered = /* @__PURE__ */ new Set();
|
|
578
|
+
return /* @__PURE__ */ jsxs2("div", { className: "builder-form-fields", children: [
|
|
579
|
+
schema.layout?.groups.map((group) => /* @__PURE__ */ jsxs2("fieldset", { className: "builder-fieldset", children: [
|
|
580
|
+
group.title ? /* @__PURE__ */ jsx2("legend", { children: group.title }) : null,
|
|
581
|
+
/* @__PURE__ */ jsx2("div", { className: "builder-form-grid", children: group.fields.map((item) => {
|
|
582
|
+
const field = fields.get(item.key);
|
|
583
|
+
if (!field) return null;
|
|
584
|
+
rendered.add(field.key);
|
|
585
|
+
return /* @__PURE__ */ jsx2("div", { style: { gridColumn: `span ${item.span}` }, children: /* @__PURE__ */ jsx2(ReadyField, { field, formId, viewId }) }, field.key);
|
|
586
|
+
}) })
|
|
587
|
+
] }, group.id)),
|
|
588
|
+
/* @__PURE__ */ jsx2("div", { className: "builder-form-grid", children: schema.fields.filter((field) => !rendered.has(field.key)).map((field) => /* @__PURE__ */ jsx2("div", { style: { gridColumn: "span 12" }, children: /* @__PURE__ */ jsx2(ReadyField, { field, formId, viewId }) }, field.key)) }),
|
|
589
|
+
extraItems.map((item) => /* @__PURE__ */ jsx2("div", { children: item.render() }, item.key))
|
|
590
|
+
] });
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// src/ready/ReadyOverlay.tsx
|
|
594
|
+
import { useEffect, useId, useRef as useRef3 } from "react";
|
|
595
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
596
|
+
function ReadyOverlay({
|
|
597
|
+
open,
|
|
598
|
+
presentation = "dialog",
|
|
599
|
+
title,
|
|
600
|
+
description,
|
|
601
|
+
onClose,
|
|
602
|
+
children
|
|
603
|
+
}) {
|
|
604
|
+
const panelRef = useRef3(null);
|
|
605
|
+
const onCloseRef = useRef3(onClose);
|
|
606
|
+
onCloseRef.current = onClose;
|
|
607
|
+
const titleId = useId();
|
|
608
|
+
useEffect(() => {
|
|
609
|
+
if (!open) return;
|
|
610
|
+
const previous = document.activeElement;
|
|
611
|
+
panelRef.current?.focus();
|
|
612
|
+
const onKeyDown = (event) => {
|
|
613
|
+
if (event.key === "Escape") onCloseRef.current();
|
|
614
|
+
if (event.key === "Tab") {
|
|
615
|
+
const focusable = Array.from(
|
|
616
|
+
panelRef.current?.querySelectorAll(
|
|
617
|
+
"button:not([disabled]),a[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex='-1'])"
|
|
618
|
+
) ?? []
|
|
619
|
+
);
|
|
620
|
+
const first = focusable[0];
|
|
621
|
+
const last = focusable.at(-1);
|
|
622
|
+
if (event.shiftKey && document.activeElement === first && last) {
|
|
623
|
+
event.preventDefault();
|
|
624
|
+
last.focus();
|
|
625
|
+
} else if (!event.shiftKey && document.activeElement === last && first) {
|
|
626
|
+
event.preventDefault();
|
|
627
|
+
first.focus();
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
document.addEventListener("keydown", onKeyDown);
|
|
632
|
+
const overflow = document.body.style.overflow;
|
|
633
|
+
document.body.style.overflow = "hidden";
|
|
634
|
+
return () => {
|
|
635
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
636
|
+
document.body.style.overflow = overflow;
|
|
637
|
+
previous?.focus();
|
|
638
|
+
};
|
|
639
|
+
}, [open]);
|
|
640
|
+
if (!open) return null;
|
|
641
|
+
return /* @__PURE__ */ jsx3("div", { className: "builder-overlay", role: "presentation", onMouseDown: (event) => event.target === event.currentTarget && onClose(), children: /* @__PURE__ */ jsxs3(
|
|
642
|
+
"div",
|
|
643
|
+
{
|
|
644
|
+
ref: panelRef,
|
|
645
|
+
className: `builder-overlay__panel builder-overlay__panel--${presentation}`,
|
|
646
|
+
role: "dialog",
|
|
647
|
+
"aria-modal": "true",
|
|
648
|
+
"aria-labelledby": titleId,
|
|
649
|
+
tabIndex: -1,
|
|
650
|
+
children: [
|
|
651
|
+
/* @__PURE__ */ jsxs3("header", { className: "builder-overlay__header", children: [
|
|
652
|
+
/* @__PURE__ */ jsxs3("div", { children: [
|
|
653
|
+
/* @__PURE__ */ jsx3("h2", { id: titleId, className: "builder-title", children: title }),
|
|
654
|
+
description ? /* @__PURE__ */ jsx3("p", { className: "builder-description", children: description }) : null
|
|
655
|
+
] }),
|
|
656
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "builder-icon-button", "aria-label": "\u0425\u0430\u0430\u0445", onClick: onClose, children: "\xD7" })
|
|
657
|
+
] }),
|
|
658
|
+
/* @__PURE__ */ jsx3("div", { className: "builder-overlay__body", children })
|
|
659
|
+
]
|
|
660
|
+
}
|
|
661
|
+
) });
|
|
662
|
+
}
|
|
663
|
+
function ReadyConfirmDialog({
|
|
664
|
+
open,
|
|
665
|
+
title,
|
|
666
|
+
description,
|
|
667
|
+
confirmLabel = "\u0423\u0441\u0442\u0433\u0430\u0445",
|
|
668
|
+
isPending,
|
|
669
|
+
onClose,
|
|
670
|
+
onConfirm
|
|
671
|
+
}) {
|
|
672
|
+
return /* @__PURE__ */ jsx3(ReadyOverlay, { open, title, description, onClose, children: /* @__PURE__ */ jsxs3("div", { className: "builder-actions", children: [
|
|
673
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "builder-button builder-button--ghost", onClick: onClose, children: "\u0411\u043E\u043B\u0438\u0445" }),
|
|
674
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "builder-button builder-button--danger", disabled: isPending, onClick: onConfirm, children: isPending ? "\u0422\u04AF\u0440 \u0445\u04AF\u043B\u044D\u044D\u043D\u044D \u04AF\u04AF\u2026" : confirmLabel })
|
|
675
|
+
] }) });
|
|
676
|
+
}
|
|
677
|
+
function ReadyErrorState({ title, description }) {
|
|
678
|
+
return /* @__PURE__ */ jsxs3("div", { className: "builder-state builder-state--error", role: "alert", children: [
|
|
679
|
+
/* @__PURE__ */ jsx3("strong", { children: title }),
|
|
680
|
+
/* @__PURE__ */ jsx3("span", { children: description })
|
|
681
|
+
] });
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// src/ready/ReadySubform.tsx
|
|
685
|
+
import { useEffect as useEffect2, useMemo as useMemo3, useRef as useRef4, useState as useState3 } from "react";
|
|
686
|
+
import { FormProvider, useForm } from "react-hook-form";
|
|
687
|
+
|
|
688
|
+
// src/ready/ReadyTable.tsx
|
|
689
|
+
import { useMemo as useMemo2, useState as useState2 } from "react";
|
|
690
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
691
|
+
function useReadyTableState({ pageSize = 20 } = {}) {
|
|
692
|
+
const [page, setPage] = useState2(1);
|
|
693
|
+
const [search, setSearchValue] = useState2("");
|
|
694
|
+
const [sort, setSort] = useState2();
|
|
695
|
+
return {
|
|
696
|
+
query: { page, pageSize, search: search || void 0, sort },
|
|
697
|
+
page,
|
|
698
|
+
pageSize,
|
|
699
|
+
search,
|
|
700
|
+
sort,
|
|
701
|
+
setPage,
|
|
702
|
+
setSearch(searchValue) {
|
|
703
|
+
setSearchValue(searchValue);
|
|
704
|
+
setPage(1);
|
|
705
|
+
},
|
|
706
|
+
toggleSort(key) {
|
|
707
|
+
setSort((current) => current === key ? `-${key}` : key);
|
|
708
|
+
setPage(1);
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
function useReadyTable(args) {
|
|
713
|
+
const [selectedIds, setSelectedIds] = useState2([]);
|
|
714
|
+
return useMemo2(
|
|
715
|
+
() => ({
|
|
716
|
+
...args,
|
|
717
|
+
selectedIds,
|
|
718
|
+
toggleSelected(id) {
|
|
719
|
+
setSelectedIds(
|
|
720
|
+
(current) => current.includes(id) ? current.filter((value) => value !== id) : [...current, id]
|
|
721
|
+
);
|
|
722
|
+
},
|
|
723
|
+
clearSelection() {
|
|
724
|
+
setSelectedIds([]);
|
|
725
|
+
}
|
|
726
|
+
}),
|
|
727
|
+
[args.columns, args.data, args.rowCount, args.state, selectedIds]
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
function cellValue(entry, column) {
|
|
731
|
+
if (column.render) return column.render(entry);
|
|
732
|
+
return formatBuilderRuntimeValue(entry.values[column.key]);
|
|
733
|
+
}
|
|
734
|
+
function ReadyDataGrid({
|
|
735
|
+
title,
|
|
736
|
+
description,
|
|
737
|
+
controller,
|
|
738
|
+
isLoading,
|
|
739
|
+
searchPlaceholder = "\u0425\u0430\u0439\u0445...",
|
|
740
|
+
emptyTitle = "\u041C\u044D\u0434\u044D\u044D\u043B\u044D\u043B \u0430\u043B\u0433\u0430",
|
|
741
|
+
emptyDescription,
|
|
742
|
+
onRowClick,
|
|
743
|
+
toolbarExtra,
|
|
744
|
+
selectable = false
|
|
745
|
+
}) {
|
|
746
|
+
const totalPages = Math.max(1, Math.ceil(controller.rowCount / controller.state.pageSize));
|
|
747
|
+
return /* @__PURE__ */ jsxs4("section", { className: "builder-card builder-grid", "aria-busy": isLoading || void 0, children: [
|
|
748
|
+
/* @__PURE__ */ jsxs4("header", { className: "builder-grid__header", children: [
|
|
749
|
+
/* @__PURE__ */ jsxs4("div", { children: [
|
|
750
|
+
title ? /* @__PURE__ */ jsx4("h2", { className: "builder-title", children: title }) : null,
|
|
751
|
+
description ? /* @__PURE__ */ jsx4("p", { className: "builder-description", children: description }) : null
|
|
752
|
+
] }),
|
|
753
|
+
/* @__PURE__ */ jsxs4("div", { className: "builder-grid__toolbar", children: [
|
|
754
|
+
/* @__PURE__ */ jsx4(
|
|
755
|
+
"input",
|
|
756
|
+
{
|
|
757
|
+
className: "builder-input builder-grid__search",
|
|
758
|
+
type: "search",
|
|
759
|
+
value: controller.state.search,
|
|
760
|
+
placeholder: searchPlaceholder,
|
|
761
|
+
"aria-label": searchPlaceholder,
|
|
762
|
+
onChange: (event) => controller.state.setSearch(event.target.value)
|
|
763
|
+
}
|
|
764
|
+
),
|
|
765
|
+
toolbarExtra
|
|
766
|
+
] })
|
|
767
|
+
] }),
|
|
768
|
+
/* @__PURE__ */ jsxs4("div", { className: "builder-table-wrap", children: [
|
|
769
|
+
/* @__PURE__ */ jsxs4("table", { className: "builder-table", children: [
|
|
770
|
+
/* @__PURE__ */ jsx4("thead", { children: /* @__PURE__ */ jsxs4("tr", { children: [
|
|
771
|
+
selectable ? /* @__PURE__ */ jsx4("th", { "aria-label": "\u0421\u043E\u043D\u0433\u043E\u043B\u0442" }) : null,
|
|
772
|
+
controller.columns.map((column) => /* @__PURE__ */ jsx4("th", { className: `builder-align-${column.align}`, children: column.sortable ? /* @__PURE__ */ jsx4("button", { type: "button", className: "builder-sort", onClick: () => controller.state.toggleSort(column.key), children: column.label }) : column.label }, column.key))
|
|
773
|
+
] }) }),
|
|
774
|
+
/* @__PURE__ */ jsx4("tbody", { children: controller.data.map((entry) => /* @__PURE__ */ jsxs4(
|
|
775
|
+
"tr",
|
|
776
|
+
{
|
|
777
|
+
className: onRowClick ? "builder-row-clickable" : void 0,
|
|
778
|
+
onClick: (event) => onRowClick?.(entry, event),
|
|
779
|
+
children: [
|
|
780
|
+
selectable ? /* @__PURE__ */ jsx4("td", { children: /* @__PURE__ */ jsx4(
|
|
781
|
+
"input",
|
|
782
|
+
{
|
|
783
|
+
type: "checkbox",
|
|
784
|
+
checked: controller.selectedIds.includes(entry.id),
|
|
785
|
+
"aria-label": "\u041C\u04E9\u0440 \u0441\u043E\u043D\u0433\u043E\u0445",
|
|
786
|
+
onClick: (event) => event.stopPropagation(),
|
|
787
|
+
onChange: () => controller.toggleSelected(entry.id)
|
|
788
|
+
}
|
|
789
|
+
) }) : null,
|
|
790
|
+
controller.columns.map((column) => /* @__PURE__ */ jsx4("td", { className: `builder-align-${column.align}`, children: cellValue(entry, column) }, column.key))
|
|
791
|
+
]
|
|
792
|
+
},
|
|
793
|
+
entry.id
|
|
794
|
+
)) })
|
|
795
|
+
] }),
|
|
796
|
+
isLoading ? /* @__PURE__ */ jsx4("div", { className: "builder-state", children: "\u0423\u043D\u0448\u0438\u0436 \u0431\u0430\u0439\u043D\u0430\u2026" }) : null,
|
|
797
|
+
!isLoading && controller.data.length === 0 ? /* @__PURE__ */ jsxs4("div", { className: "builder-state", children: [
|
|
798
|
+
/* @__PURE__ */ jsx4("strong", { children: emptyTitle }),
|
|
799
|
+
emptyDescription ? /* @__PURE__ */ jsx4("span", { children: emptyDescription }) : null
|
|
800
|
+
] }) : null
|
|
801
|
+
] }),
|
|
802
|
+
/* @__PURE__ */ jsxs4("footer", { className: "builder-pagination", children: [
|
|
803
|
+
/* @__PURE__ */ jsxs4("span", { children: [
|
|
804
|
+
controller.rowCount,
|
|
805
|
+
" \u043C\u04E9\u0440"
|
|
806
|
+
] }),
|
|
807
|
+
/* @__PURE__ */ jsxs4("div", { children: [
|
|
808
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "builder-button builder-button--ghost", disabled: controller.state.page <= 1, onClick: () => controller.state.setPage(controller.state.page - 1), children: "\u04E8\u043C\u043D\u04E9\u0445" }),
|
|
809
|
+
/* @__PURE__ */ jsxs4("span", { children: [
|
|
810
|
+
controller.state.page,
|
|
811
|
+
" / ",
|
|
812
|
+
totalPages
|
|
813
|
+
] }),
|
|
814
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "builder-button builder-button--ghost", disabled: controller.state.page >= totalPages, onClick: () => controller.state.setPage(controller.state.page + 1), children: "\u0414\u0430\u0440\u0430\u0430\u0445" })
|
|
815
|
+
] })
|
|
816
|
+
] })
|
|
817
|
+
] });
|
|
818
|
+
}
|
|
819
|
+
function readyColumns(columns) {
|
|
820
|
+
return columns.map((column) => ({ ...column }));
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// src/ready/ReadySubform.tsx
|
|
824
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
825
|
+
function linkedValue(entry, field) {
|
|
826
|
+
if (!entry) return void 0;
|
|
827
|
+
const value = field === "id" ? entry.id : entry.values[field];
|
|
828
|
+
return typeof value === "string" || typeof value === "number" ? String(value) : void 0;
|
|
829
|
+
}
|
|
830
|
+
function dataKey(viewId, tableName) {
|
|
831
|
+
return tableName?.trim() || viewId;
|
|
832
|
+
}
|
|
833
|
+
function makeDraftEntry(viewId, values, editing) {
|
|
834
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
835
|
+
return {
|
|
836
|
+
id: editing?.id ?? (globalThis.crypto?.randomUUID?.() ?? `draft-${Date.now()}`),
|
|
837
|
+
viewId,
|
|
838
|
+
values: editing ? values.values : { ...values.values, _draftNew: true },
|
|
839
|
+
version: editing?.version ?? 0,
|
|
840
|
+
createdAt: editing?.createdAt ?? now,
|
|
841
|
+
updatedAt: now
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
function ReadySubform({ subform, parentEntry, rows, onRowsChange }) {
|
|
845
|
+
const { hooks, notify } = useBuilderRuntime();
|
|
846
|
+
const [open, setOpen] = useState3(false);
|
|
847
|
+
const [editing, setEditing] = useState3(null);
|
|
848
|
+
const initialized = useRef4(false);
|
|
849
|
+
const parentValue = linkedValue(parentEntry, subform.parentField);
|
|
850
|
+
const viewQuery = hooks.useRuntimeBuilderView(subform.viewId, Boolean(subform.viewId));
|
|
851
|
+
const tableState = useReadyTableState({ pageSize: 100 });
|
|
852
|
+
const filterQuery = useMemo3(
|
|
853
|
+
() => ({ ...tableState.query, filterField: subform.childField, filterValue: parentValue ?? "" }),
|
|
854
|
+
[parentValue, subform.childField, tableState.query]
|
|
855
|
+
);
|
|
856
|
+
const entriesQuery = hooks.useBuilderViewEntries(subform.viewId, filterQuery, Boolean(parentValue));
|
|
857
|
+
const view = viewQuery.data;
|
|
858
|
+
const source = view?.list?.source?.type === "dbTable" ? view.list.source.tableName : void 0;
|
|
859
|
+
useEffect2(() => {
|
|
860
|
+
if (initialized.current || !view || !entriesQuery.data || !parentValue) return;
|
|
861
|
+
initialized.current = true;
|
|
862
|
+
onRowsChange({ key: subform.key, dataKey: dataKey(view.id, source), rows: entriesQuery.data.items });
|
|
863
|
+
}, [entriesQuery.data, onRowsChange, parentValue, source, subform.key, view]);
|
|
864
|
+
const visibleRows = rows.filter((row) => row.values._delete !== true);
|
|
865
|
+
const removeRow = (row) => {
|
|
866
|
+
initialized.current = true;
|
|
867
|
+
const nextRows = row.values._draftNew === true ? rows.filter((item) => item.id !== row.id) : rows.map((item) => item.id === row.id ? { ...item, values: { ...item.values, _delete: true } } : item);
|
|
868
|
+
onRowsChange({ key: subform.key, dataKey: dataKey(view?.id ?? subform.viewId, source), rows: nextRows });
|
|
869
|
+
notify({ type: "info", message: "Subform \u043C\u04E9\u0440 \u0443\u0441\u0442\u0433\u0430\u0445\u0430\u0430\u0440 \u0442\u044D\u043C\u0434\u044D\u0433\u043B\u044D\u0433\u0434\u043B\u044D\u044D" });
|
|
870
|
+
};
|
|
871
|
+
const columns = useMemo3(() => [
|
|
872
|
+
...readyColumns(view?.list?.schema.columns ?? []),
|
|
873
|
+
{
|
|
874
|
+
key: "_actions",
|
|
875
|
+
label: "\u04AE\u0439\u043B\u0434\u044D\u043B",
|
|
876
|
+
sortable: false,
|
|
877
|
+
align: "right",
|
|
878
|
+
render: (row) => /* @__PURE__ */ jsx5("button", { type: "button", className: "builder-link builder-link--danger", onClick: (event) => {
|
|
879
|
+
event.stopPropagation();
|
|
880
|
+
removeRow(row);
|
|
881
|
+
}, children: "\u0423\u0441\u0442\u0433\u0430\u0445" })
|
|
882
|
+
}
|
|
883
|
+
], [rows, source, subform.key, subform.viewId, view]);
|
|
884
|
+
const table = useReadyTable({
|
|
885
|
+
columns,
|
|
886
|
+
data: visibleRows,
|
|
887
|
+
rowCount: visibleRows.length,
|
|
888
|
+
state: tableState,
|
|
889
|
+
getRowId: (row) => row.id
|
|
890
|
+
});
|
|
891
|
+
const form = useForm({
|
|
892
|
+
defaultValues: createBuilderEntryDefaultValues(view ?? {}, editing),
|
|
893
|
+
values: open ? createBuilderEntryDefaultValues(view ?? {}, editing) : void 0
|
|
894
|
+
});
|
|
895
|
+
const close = () => {
|
|
896
|
+
setOpen(false);
|
|
897
|
+
setEditing(null);
|
|
898
|
+
};
|
|
899
|
+
const save = form.handleSubmit((values) => {
|
|
900
|
+
if (!view) return;
|
|
901
|
+
if (parentValue) values.values[subform.childField] = parentValue;
|
|
902
|
+
const next = makeDraftEntry(view.id, values, editing);
|
|
903
|
+
initialized.current = true;
|
|
904
|
+
onRowsChange({
|
|
905
|
+
key: subform.key,
|
|
906
|
+
dataKey: dataKey(view.id, source),
|
|
907
|
+
rows: editing ? rows.map((row) => row.id === editing.id ? next : row) : [...rows, next]
|
|
908
|
+
});
|
|
909
|
+
close();
|
|
910
|
+
});
|
|
911
|
+
if (viewQuery.isError) {
|
|
912
|
+
return /* @__PURE__ */ jsx5("div", { className: "builder-state builder-state--error", children: builderErrorMessage(viewQuery.error, `${subform.label} \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439`) });
|
|
913
|
+
}
|
|
914
|
+
return /* @__PURE__ */ jsxs5("section", { className: "builder-subform", children: [
|
|
915
|
+
/* @__PURE__ */ jsxs5("div", { className: "builder-subform__header", children: [
|
|
916
|
+
/* @__PURE__ */ jsx5("strong", { children: subform.label }),
|
|
917
|
+
/* @__PURE__ */ jsxs5("button", { type: "button", className: "builder-button builder-button--secondary", disabled: !view?.form, onClick: () => {
|
|
918
|
+
setEditing(null);
|
|
919
|
+
setOpen(true);
|
|
920
|
+
}, children: [
|
|
921
|
+
"+ ",
|
|
922
|
+
subform.buttonLabel ?? "\u041D\u044D\u043C\u044D\u0445"
|
|
923
|
+
] })
|
|
924
|
+
] }),
|
|
925
|
+
visibleRows.length > 0 || Boolean(parentValue) && entriesQuery.isPending ? /* @__PURE__ */ jsx5(
|
|
926
|
+
ReadyDataGrid,
|
|
927
|
+
{
|
|
928
|
+
controller: table,
|
|
929
|
+
isLoading: Boolean(parentValue) && entriesQuery.isPending,
|
|
930
|
+
onRowClick: (row) => {
|
|
931
|
+
setEditing(row);
|
|
932
|
+
setOpen(true);
|
|
933
|
+
},
|
|
934
|
+
emptyTitle: "\u041C\u04E9\u0440 \u0430\u043B\u0433\u0430"
|
|
935
|
+
}
|
|
936
|
+
) : null,
|
|
937
|
+
view?.form ? /* @__PURE__ */ jsx5(ReadyOverlay, { open, presentation: subform.presentation, title: subform.label, description: view.title, onClose: close, children: /* @__PURE__ */ jsx5(FormProvider, { ...form, children: /* @__PURE__ */ jsxs5("form", { className: "builder-form", onSubmit: save, noValidate: true, children: [
|
|
938
|
+
/* @__PURE__ */ jsx5(ReadyFields, { formId: view.form.id, viewId: view.id, schema: view.form.schema }),
|
|
939
|
+
/* @__PURE__ */ jsxs5("div", { className: "builder-actions", children: [
|
|
940
|
+
/* @__PURE__ */ jsx5("button", { type: "button", className: "builder-button builder-button--ghost", onClick: close, children: "\u0411\u043E\u043B\u0438\u0445" }),
|
|
941
|
+
/* @__PURE__ */ jsx5("button", { type: "submit", className: "builder-button builder-button--primary", children: "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445" })
|
|
942
|
+
] })
|
|
943
|
+
] }) }) }) : null
|
|
944
|
+
] });
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
// src/ready/BuilderRuntimeComponents.tsx
|
|
948
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
949
|
+
function BuilderForm({ formId }) {
|
|
950
|
+
const { hooks, notify } = useBuilderRuntime();
|
|
951
|
+
const query = hooks.useRuntimeBuilderForm(formId);
|
|
952
|
+
const save = hooks.useSaveRuntimeBuilderFormEntry(formId);
|
|
953
|
+
const defaults = useMemo4(() => createBuilderFormDefaultValues(query.data?.schema), [query.data]);
|
|
954
|
+
const form = useForm2({ defaultValues: defaults, values: query.data ? defaults : void 0 });
|
|
955
|
+
if (query.isError) return /* @__PURE__ */ jsx6(ReadyErrorState, { title: "Form \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439", description: builderErrorMessage(query.error, `\xAB${formId}\xBB form \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439`) });
|
|
956
|
+
if (!query.data) return /* @__PURE__ */ jsx6("div", { className: "builder-state", children: "Form \u0443\u043D\u0448\u0438\u0436 \u0431\u0430\u0439\u043D\u0430\u2026" });
|
|
957
|
+
const submit = form.handleSubmit(async (input) => {
|
|
958
|
+
try {
|
|
959
|
+
await save.mutateAsync(input);
|
|
960
|
+
form.reset(defaults);
|
|
961
|
+
notify({ type: "success", message: "Form \u0445\u0430\u0434\u0433\u0430\u043B\u0430\u0433\u0434\u043B\u0430\u0430" });
|
|
962
|
+
} catch (error) {
|
|
963
|
+
notify({ type: "error", message: builderErrorMessage(error, "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445\u0430\u0434 \u0430\u043B\u0434\u0430\u0430 \u0433\u0430\u0440\u043B\u0430\u0430") });
|
|
964
|
+
}
|
|
965
|
+
});
|
|
966
|
+
return /* @__PURE__ */ jsxs6("section", { className: "builder-card", children: [
|
|
967
|
+
/* @__PURE__ */ jsx6("h2", { className: "builder-title", children: query.data.title }),
|
|
968
|
+
query.data.description ? /* @__PURE__ */ jsx6("p", { className: "builder-description", children: query.data.description }) : null,
|
|
969
|
+
/* @__PURE__ */ jsx6(FormProvider2, { ...form, children: /* @__PURE__ */ jsxs6("form", { className: "builder-form", onSubmit: submit, noValidate: true, children: [
|
|
970
|
+
/* @__PURE__ */ jsx6(ReadyFields, { formId, schema: query.data.schema }),
|
|
971
|
+
/* @__PURE__ */ jsx6("div", { className: "builder-actions", children: /* @__PURE__ */ jsx6("button", { className: "builder-button builder-button--primary", type: "submit", disabled: save.isPending, children: save.isPending ? "\u0425\u0430\u0434\u0433\u0430\u043B\u0436 \u0431\u0430\u0439\u043D\u0430\u2026" : "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445" }) })
|
|
972
|
+
] }) })
|
|
973
|
+
] });
|
|
974
|
+
}
|
|
975
|
+
function BuilderGrid({ listId }) {
|
|
976
|
+
const { hooks } = useBuilderRuntime();
|
|
977
|
+
const listQuery = hooks.useRuntimeBuilderList(listId);
|
|
978
|
+
const state = useReadyTableState();
|
|
979
|
+
const entriesQuery = hooks.useRuntimeBuilderListEntries(listId, state.query);
|
|
980
|
+
const table = useReadyTable({
|
|
981
|
+
columns: readyColumns(listQuery.data?.schema.columns ?? []),
|
|
982
|
+
data: entriesQuery.data?.items ?? [],
|
|
983
|
+
rowCount: entriesQuery.data?.total ?? 0,
|
|
984
|
+
state,
|
|
985
|
+
getRowId: (row) => row.id
|
|
986
|
+
});
|
|
987
|
+
if (listQuery.isError) return /* @__PURE__ */ jsx6(ReadyErrorState, { title: "Grid \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439", description: builderErrorMessage(listQuery.error, `\xAB${listId}\xBB list \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439`) });
|
|
988
|
+
return /* @__PURE__ */ jsx6(ReadyDataGrid, { title: listQuery.data?.title ?? "Grid", description: listQuery.data?.description, controller: table, isLoading: listQuery.isPending || entriesQuery.isPending });
|
|
989
|
+
}
|
|
990
|
+
function dbTableName(view) {
|
|
991
|
+
if (view.list?.source?.type === "dbTable") return view.list.source.tableName;
|
|
992
|
+
if (view.form?.source?.type === "dbTable") return view.form.source.tableName;
|
|
993
|
+
return void 0;
|
|
994
|
+
}
|
|
995
|
+
function childPayload(row, includeIdentity) {
|
|
996
|
+
const values = Object.fromEntries(Object.entries(row.values).filter(([key]) => key === "_delete" || !key.startsWith("_")));
|
|
997
|
+
return includeIdentity && row.values._draftNew !== true ? { id: row.id, version: row.version, ...values } : values;
|
|
998
|
+
}
|
|
999
|
+
function BuilderEntryEditor({ view, editing, open, onClose }) {
|
|
1000
|
+
const { hooks, notify } = useBuilderRuntime();
|
|
1001
|
+
const [subforms, setSubforms] = useState4({});
|
|
1002
|
+
const save = hooks.useSaveBuilderViewEntry(view.id);
|
|
1003
|
+
const createComposite = hooks.useCreateCompositeBuilderViewEntry(view.id);
|
|
1004
|
+
const updateComposite = hooks.useUpdateCompositeBuilderViewEntry(view.id);
|
|
1005
|
+
const defaults = useMemo4(() => createBuilderEntryDefaultValues(view, editing), [editing, view]);
|
|
1006
|
+
const form = useForm2({ defaultValues: defaults, values: open ? defaults : void 0 });
|
|
1007
|
+
const close = () => {
|
|
1008
|
+
setSubforms({});
|
|
1009
|
+
onClose();
|
|
1010
|
+
};
|
|
1011
|
+
const submit = form.handleSubmit(async (input) => {
|
|
1012
|
+
try {
|
|
1013
|
+
const mainKey = dbTableName(view);
|
|
1014
|
+
const hasSubformRows = Object.values(subforms).some((item) => item.rows.length > 0);
|
|
1015
|
+
if (hasSubformRows && mainKey) {
|
|
1016
|
+
const children = Object.fromEntries(Object.values(subforms).map((item) => [item.dataKey, item.rows.map((row) => childPayload(row, Boolean(editing)))]));
|
|
1017
|
+
if (editing) {
|
|
1018
|
+
await updateComposite.mutateAsync({ id: editing.id, input: { data: { [mainKey]: { id: editing.id, version: input.version, ...input.values }, ...children } } });
|
|
1019
|
+
} else {
|
|
1020
|
+
await createComposite.mutateAsync({ data: { [mainKey]: input.values, ...children } });
|
|
1021
|
+
}
|
|
1022
|
+
} else {
|
|
1023
|
+
await save.mutateAsync({ id: editing?.id, input });
|
|
1024
|
+
}
|
|
1025
|
+
notify({ type: "success", message: editing ? "\u041C\u04E9\u0440 \u0445\u0430\u0434\u0433\u0430\u043B\u0430\u0433\u0434\u043B\u0430\u0430" : "\u041C\u04E9\u0440 \u043D\u044D\u043C\u044D\u0433\u0434\u043B\u044D\u044D" });
|
|
1026
|
+
close();
|
|
1027
|
+
} catch (error) {
|
|
1028
|
+
notify({ type: "error", message: builderErrorMessage(error, "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445\u0430\u0434 \u0430\u043B\u0434\u0430\u0430 \u0433\u0430\u0440\u043B\u0430\u0430") });
|
|
1029
|
+
}
|
|
1030
|
+
});
|
|
1031
|
+
const saving = save.isPending || createComposite.isPending || updateComposite.isPending;
|
|
1032
|
+
const updateRows = ({ key, dataKey: dataKey2, rows }) => setSubforms((current) => ({ ...current, [key]: { dataKey: dataKey2, rows } }));
|
|
1033
|
+
return /* @__PURE__ */ jsx6(ReadyOverlay, { open, presentation: view.form?.schema.presentation, title: editing ? "\u041C\u04E9\u0440 \u0437\u0430\u0441\u0430\u0445" : "\u041C\u04E9\u0440 \u043D\u044D\u043C\u044D\u0445", description: view.title, onClose: close, children: view.form ? /* @__PURE__ */ jsx6(FormProvider2, { ...form, children: /* @__PURE__ */ jsxs6("form", { className: "builder-form", onSubmit: submit, noValidate: true, children: [
|
|
1034
|
+
/* @__PURE__ */ jsx6(ReadyFields, { formId: view.form.id, viewId: view.id, schema: view.form.schema }),
|
|
1035
|
+
view.form.schema.subforms.map((subform) => /* @__PURE__ */ jsx6(ReadySubform, { subform, parentEntry: editing, rows: subforms[subform.key]?.rows ?? [], onRowsChange: updateRows }, subform.key)),
|
|
1036
|
+
/* @__PURE__ */ jsxs6("div", { className: "builder-actions builder-actions--sticky", children: [
|
|
1037
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "builder-button builder-button--ghost", onClick: close, children: "\u0411\u043E\u043B\u0438\u0445" }),
|
|
1038
|
+
/* @__PURE__ */ jsx6("button", { type: "submit", className: "builder-button builder-button--primary", disabled: saving, children: saving ? "\u0425\u0430\u0434\u0433\u0430\u043B\u0436 \u0431\u0430\u0439\u043D\u0430\u2026" : "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445" })
|
|
1039
|
+
] })
|
|
1040
|
+
] }) }) : /* @__PURE__ */ jsx6(ReadyErrorState, { title: "Form \u0445\u043E\u043B\u0431\u043E\u043E\u0433\u04AF\u0439", description: "\u042D\u043D\u044D view-\u0434 form \u0442\u043E\u0445\u0438\u0440\u0443\u0443\u043B\u0430\u0430\u0433\u04AF\u0439 \u0431\u0430\u0439\u043D\u0430." }) });
|
|
1041
|
+
}
|
|
1042
|
+
function BuilderView({ viewId }) {
|
|
1043
|
+
const { hooks, notify } = useBuilderRuntime();
|
|
1044
|
+
const [editing, setEditing] = useState4(null);
|
|
1045
|
+
const [editorOpen, setEditorOpen] = useState4(false);
|
|
1046
|
+
const [pendingDelete, setPendingDelete] = useState4(null);
|
|
1047
|
+
const viewQuery = hooks.useRuntimeBuilderView(viewId);
|
|
1048
|
+
const state = useReadyTableState();
|
|
1049
|
+
const entriesQuery = hooks.useBuilderViewEntries(viewId, state.query);
|
|
1050
|
+
const remove = hooks.useDeleteBuilderViewEntry(viewId);
|
|
1051
|
+
const view = viewQuery.data;
|
|
1052
|
+
const columns = useMemo4(() => {
|
|
1053
|
+
const result = readyColumns(view?.list?.schema.columns ?? []);
|
|
1054
|
+
if (!view) return result;
|
|
1055
|
+
result.push({
|
|
1056
|
+
key: "_actions",
|
|
1057
|
+
label: "\u04AE\u0439\u043B\u0434\u044D\u043B",
|
|
1058
|
+
sortable: false,
|
|
1059
|
+
align: "right",
|
|
1060
|
+
render: (entry) => /* @__PURE__ */ jsxs6("div", { className: "builder-row-actions", "data-builder-row-action": true, children: [
|
|
1061
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "builder-button builder-button--ghost", onClick: (event) => {
|
|
1062
|
+
event.stopPropagation();
|
|
1063
|
+
setEditing(entry);
|
|
1064
|
+
setEditorOpen(true);
|
|
1065
|
+
}, children: "\u0417\u0430\u0441\u0430\u0445" }),
|
|
1066
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "builder-button builder-button--danger", onClick: (event) => {
|
|
1067
|
+
event.stopPropagation();
|
|
1068
|
+
setPendingDelete(entry);
|
|
1069
|
+
}, children: "\u0423\u0441\u0442\u0433\u0430\u0445" })
|
|
1070
|
+
] })
|
|
1071
|
+
});
|
|
1072
|
+
return result;
|
|
1073
|
+
}, [view]);
|
|
1074
|
+
const table = useReadyTable({ columns, data: entriesQuery.data?.items ?? [], rowCount: entriesQuery.data?.total ?? 0, state, getRowId: (row) => row.id });
|
|
1075
|
+
if (viewQuery.isError) return /* @__PURE__ */ jsx6(ReadyErrorState, { title: "View \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439", description: builderErrorMessage(viewQuery.error, `\xAB${viewId}\xBB view \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439`) });
|
|
1076
|
+
return /* @__PURE__ */ jsxs6("div", { className: "builder-runtime", children: [
|
|
1077
|
+
/* @__PURE__ */ jsx6(
|
|
1078
|
+
ReadyDataGrid,
|
|
1079
|
+
{
|
|
1080
|
+
title: view?.title ?? "View",
|
|
1081
|
+
description: view?.description,
|
|
1082
|
+
controller: table,
|
|
1083
|
+
isLoading: viewQuery.isPending || entriesQuery.isPending,
|
|
1084
|
+
onRowClick: (entry) => {
|
|
1085
|
+
setEditing(entry);
|
|
1086
|
+
setEditorOpen(true);
|
|
1087
|
+
},
|
|
1088
|
+
toolbarExtra: /* @__PURE__ */ jsx6("button", { type: "button", className: "builder-button builder-button--primary", disabled: !view?.form, onClick: () => {
|
|
1089
|
+
setEditing(null);
|
|
1090
|
+
setEditorOpen(true);
|
|
1091
|
+
}, children: "+ \u041D\u044D\u043C\u044D\u0445" })
|
|
1092
|
+
}
|
|
1093
|
+
),
|
|
1094
|
+
view ? /* @__PURE__ */ jsx6(BuilderEntryEditor, { view, editing, open: editorOpen, onClose: () => setEditorOpen(false) }) : null,
|
|
1095
|
+
/* @__PURE__ */ jsx6(
|
|
1096
|
+
ReadyConfirmDialog,
|
|
1097
|
+
{
|
|
1098
|
+
open: Boolean(pendingDelete),
|
|
1099
|
+
title: "\u041C\u04E9\u0440 \u0443\u0441\u0442\u0433\u0430\u0445 \u0443\u0443?",
|
|
1100
|
+
description: "\u042D\u043D\u044D \u04AF\u0439\u043B\u0434\u043B\u0438\u0439\u0433 \u0431\u0443\u0446\u0430\u0430\u0445 \u0431\u043E\u043B\u043E\u043C\u0436\u0433\u04AF\u0439.",
|
|
1101
|
+
isPending: remove.isPending,
|
|
1102
|
+
onClose: () => setPendingDelete(null),
|
|
1103
|
+
onConfirm: () => {
|
|
1104
|
+
if (!pendingDelete) return;
|
|
1105
|
+
remove.mutate(pendingDelete.id, {
|
|
1106
|
+
onSuccess: () => {
|
|
1107
|
+
setPendingDelete(null);
|
|
1108
|
+
notify({ type: "success", message: "\u041C\u04E9\u0440 \u0443\u0441\u0442\u0433\u0430\u0433\u0434\u043B\u0430\u0430" });
|
|
1109
|
+
},
|
|
1110
|
+
onError: (error) => notify({ type: "error", message: builderErrorMessage(error, "\u0423\u0441\u0442\u0433\u0430\u0445\u0430\u0434 \u0430\u043B\u0434\u0430\u0430 \u0433\u0430\u0440\u043B\u0430\u0430") })
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
)
|
|
1115
|
+
] });
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
// src/admin/editorState.ts
|
|
1119
|
+
var BUILDER_EDITOR_NONE_VALUE = "__none";
|
|
1120
|
+
function builderEditorOptionsToText(options) {
|
|
1121
|
+
return (options ?? []).map((option) => `${option.label}:${option.value}`).join("\n");
|
|
1122
|
+
}
|
|
1123
|
+
function builderEditorTextToOptions(value) {
|
|
1124
|
+
const rows = (value ?? "").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
1125
|
+
if (rows.length === 0) return void 0;
|
|
1126
|
+
return rows.map((line) => {
|
|
1127
|
+
const [label, ...rest] = line.split(":");
|
|
1128
|
+
return { label: label.trim(), value: rest.join(":").trim() || label.trim() };
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
function builderEditorSearchFieldsToText(fields) {
|
|
1132
|
+
return (fields ?? []).join("\n");
|
|
1133
|
+
}
|
|
1134
|
+
function builderEditorTextToSearchFields(value) {
|
|
1135
|
+
const fields = (value ?? "").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
1136
|
+
return fields.length > 0 ? fields : void 0;
|
|
1137
|
+
}
|
|
1138
|
+
function getBuilderEditorTriggerRoute(config) {
|
|
1139
|
+
const route = config.route ?? config.path ?? config.url;
|
|
1140
|
+
return typeof route === "string" ? route : "";
|
|
1141
|
+
}
|
|
1142
|
+
function valuesFromTriggers(triggers) {
|
|
1143
|
+
return triggers.filter((trigger) => trigger.action === "callApi" || trigger.action === "webhook").map((trigger) => ({
|
|
1144
|
+
event: trigger.event,
|
|
1145
|
+
route: getBuilderEditorTriggerRoute(trigger.config),
|
|
1146
|
+
enabled: trigger.enabled,
|
|
1147
|
+
blocking: trigger.blocking
|
|
1148
|
+
})).filter((trigger) => trigger.route);
|
|
1149
|
+
}
|
|
1150
|
+
function valuesFromFieldTriggers(triggers) {
|
|
1151
|
+
return (triggers ?? []).map((trigger) => ({
|
|
1152
|
+
event: trigger.event,
|
|
1153
|
+
action: trigger.action,
|
|
1154
|
+
enabled: trigger.enabled,
|
|
1155
|
+
debounceMs: trigger.debounceMs
|
|
1156
|
+
}));
|
|
1157
|
+
}
|
|
1158
|
+
function clampLayoutSpan(span, columns) {
|
|
1159
|
+
if (!span || Number.isNaN(span)) return columns;
|
|
1160
|
+
return Math.max(1, Math.min(columns, Math.trunc(span)));
|
|
1161
|
+
}
|
|
1162
|
+
function builderFormEditorDefaultSpan(field) {
|
|
1163
|
+
if (field.type === "textarea" || field.type === "checkbox") return 12;
|
|
1164
|
+
return 6;
|
|
1165
|
+
}
|
|
1166
|
+
function builderFormEditorDefaultLayoutGroups(fields, subforms = []) {
|
|
1167
|
+
return [
|
|
1168
|
+
{
|
|
1169
|
+
id: "main",
|
|
1170
|
+
title: "\u04AE\u043D\u0434\u0441\u044D\u043D",
|
|
1171
|
+
columns: 12,
|
|
1172
|
+
fields: [
|
|
1173
|
+
...fields.map((field) => ({
|
|
1174
|
+
key: field.key,
|
|
1175
|
+
span: builderFormEditorDefaultSpan(field)
|
|
1176
|
+
})),
|
|
1177
|
+
...subforms.map((subform) => ({ key: subform.key, span: 12 }))
|
|
1178
|
+
]
|
|
1179
|
+
}
|
|
1180
|
+
];
|
|
1181
|
+
}
|
|
1182
|
+
function normalizeBuilderFormEditorLayoutGroups(groups, fields, subforms = []) {
|
|
1183
|
+
if (fields.length === 0 && subforms.length === 0) return [];
|
|
1184
|
+
const layoutItems = [
|
|
1185
|
+
...fields.map((field) => ({
|
|
1186
|
+
key: field.key,
|
|
1187
|
+
span: builderFormEditorDefaultSpan(field)
|
|
1188
|
+
})),
|
|
1189
|
+
...subforms.map((subform) => ({ key: subform.key, span: 12 }))
|
|
1190
|
+
];
|
|
1191
|
+
const itemKeys = new Set(layoutItems.map((item) => item.key));
|
|
1192
|
+
const usedKeys = /* @__PURE__ */ new Set();
|
|
1193
|
+
const normalized = (groups ?? []).map((group, index) => {
|
|
1194
|
+
const columns = group.columns === 6 || group.columns === 8 ? group.columns : 12;
|
|
1195
|
+
const groupFields = (group.fields ?? []).filter((field) => itemKeys.has(field.key) && !usedKeys.has(field.key)).map((field) => {
|
|
1196
|
+
usedKeys.add(field.key);
|
|
1197
|
+
return { key: field.key, span: clampLayoutSpan(field.span, columns) };
|
|
1198
|
+
});
|
|
1199
|
+
return {
|
|
1200
|
+
id: group.id || `group${index + 1}`,
|
|
1201
|
+
title: group.title || `Group ${index + 1}`,
|
|
1202
|
+
columns,
|
|
1203
|
+
fields: groupFields
|
|
1204
|
+
};
|
|
1205
|
+
}).filter((group) => group.fields.length > 0 || group.title.trim());
|
|
1206
|
+
const missingFields = layoutItems.filter((item) => !usedKeys.has(item.key));
|
|
1207
|
+
if (normalized.length === 0) {
|
|
1208
|
+
return builderFormEditorDefaultLayoutGroups(fields, subforms);
|
|
1209
|
+
}
|
|
1210
|
+
if (missingFields.length > 0) {
|
|
1211
|
+
normalized.push({
|
|
1212
|
+
id: "ungrouped",
|
|
1213
|
+
title: "\u0411\u0443\u0441\u0430\u0434",
|
|
1214
|
+
columns: 12,
|
|
1215
|
+
fields: missingFields
|
|
1216
|
+
});
|
|
1217
|
+
}
|
|
1218
|
+
return normalized;
|
|
1219
|
+
}
|
|
1220
|
+
function builderFormEditorValuesFromEntity(form, emptyValues) {
|
|
1221
|
+
if (!form) return emptyValues;
|
|
1222
|
+
const source = form.source;
|
|
1223
|
+
const fields = form.schema.fields.map((field) => ({
|
|
1224
|
+
key: field.key,
|
|
1225
|
+
label: field.label,
|
|
1226
|
+
type: field.type,
|
|
1227
|
+
required: field.required,
|
|
1228
|
+
hidden: field.hidden ?? false,
|
|
1229
|
+
disabled: field.disabled ?? false,
|
|
1230
|
+
placeholder: field.placeholder ?? "",
|
|
1231
|
+
optionsText: builderEditorOptionsToText(field.options),
|
|
1232
|
+
optionsMode: field.optionsSource?.type === "dbTable" ? "table" : "static",
|
|
1233
|
+
optionsTable: field.optionsSource?.type === "dbTable" ? field.optionsSource.tableName : BUILDER_EDITOR_NONE_VALUE,
|
|
1234
|
+
optionsValueField: field.optionsSource?.type === "dbTable" ? field.optionsSource.valueField : BUILDER_EDITOR_NONE_VALUE,
|
|
1235
|
+
optionsLabelField: field.optionsSource?.type === "dbTable" ? field.optionsSource.labelField : BUILDER_EDITOR_NONE_VALUE,
|
|
1236
|
+
optionsSearchFieldsText: field.optionsSource?.type === "dbTable" ? builderEditorSearchFieldsToText(field.optionsSource.searchFields) : "",
|
|
1237
|
+
optionsDependsOn: field.optionsSource?.type === "dbTable" ? field.optionsSource.filterBy?.valueFromField ?? "" : "",
|
|
1238
|
+
optionsFilterField: field.optionsSource?.type === "dbTable" ? field.optionsSource.filterBy?.field ?? "" : "",
|
|
1239
|
+
triggers: valuesFromFieldTriggers(field.triggers)
|
|
1240
|
+
}));
|
|
1241
|
+
const subforms = (form.schema.subforms ?? []).map((subform) => ({
|
|
1242
|
+
key: subform.key,
|
|
1243
|
+
label: subform.label,
|
|
1244
|
+
viewId: subform.viewId,
|
|
1245
|
+
parentField: subform.parentField,
|
|
1246
|
+
childField: subform.childField,
|
|
1247
|
+
buttonLabel: subform.buttonLabel ?? "",
|
|
1248
|
+
icon: subform.icon ?? "",
|
|
1249
|
+
presentation: subform.presentation ?? "dialog"
|
|
1250
|
+
}));
|
|
133
1251
|
return {
|
|
134
1252
|
title: form.title,
|
|
135
1253
|
description: form.description ?? "",
|
|
1254
|
+
presentation: form.schema.presentation ?? "dialog",
|
|
136
1255
|
sourceType: source?.type ?? "none",
|
|
137
1256
|
sourceTable: source?.type === "dbTable" ? source.tableName : BUILDER_EDITOR_NONE_VALUE,
|
|
138
1257
|
apiBasePath: source?.type === "apiEndpoint" ? source.basePath : "",
|
|
@@ -214,6 +1333,7 @@ function builderFormEditorInputFromValues(values) {
|
|
|
214
1333
|
description: values.description || null,
|
|
215
1334
|
source,
|
|
216
1335
|
schema: {
|
|
1336
|
+
presentation: values.presentation ?? "dialog",
|
|
217
1337
|
fields: values.fields.map((field) => ({
|
|
218
1338
|
key: field.key,
|
|
219
1339
|
label: field.label,
|
|
@@ -258,7 +1378,8 @@ function builderFormEditorInputFromValues(values) {
|
|
|
258
1378
|
parentField: subform.parentField,
|
|
259
1379
|
childField: subform.childField,
|
|
260
1380
|
buttonLabel: subform.buttonLabel?.trim() || void 0,
|
|
261
|
-
icon: subform.icon?.trim() || void 0
|
|
1381
|
+
icon: subform.icon?.trim() || void 0,
|
|
1382
|
+
presentation: subform.presentation ?? "dialog"
|
|
262
1383
|
}))
|
|
263
1384
|
},
|
|
264
1385
|
triggers: values.triggers.map((trigger) => ({
|
|
@@ -302,7 +1423,7 @@ function builderViewEditorInputFromValues(values, parseTriggers) {
|
|
|
302
1423
|
}
|
|
303
1424
|
|
|
304
1425
|
// src/admin/BuilderDefaultEditorBodies.tsx
|
|
305
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1426
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
306
1427
|
var styles = {
|
|
307
1428
|
page: {
|
|
308
1429
|
display: "grid",
|
|
@@ -423,7 +1544,7 @@ var styles = {
|
|
|
423
1544
|
}
|
|
424
1545
|
};
|
|
425
1546
|
function optionItems(options) {
|
|
426
|
-
return options.map((option) => /* @__PURE__ */
|
|
1547
|
+
return options.map((option) => /* @__PURE__ */ jsx7("option", { value: option.value, children: option.label }, option.value));
|
|
427
1548
|
}
|
|
428
1549
|
function createBuilderDefaultFormEditorBody(options) {
|
|
429
1550
|
return function BuilderDefaultFormEditorBody({
|
|
@@ -441,48 +1562,55 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
441
1562
|
isSaving,
|
|
442
1563
|
importFieldsFromTable
|
|
443
1564
|
}) {
|
|
444
|
-
return /* @__PURE__ */
|
|
445
|
-
/* @__PURE__ */
|
|
446
|
-
/* @__PURE__ */
|
|
447
|
-
/* @__PURE__ */
|
|
448
|
-
/* @__PURE__ */
|
|
1565
|
+
return /* @__PURE__ */ jsxs7("div", { style: styles.page, children: [
|
|
1566
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.header, children: [
|
|
1567
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1568
|
+
/* @__PURE__ */ jsx7("h1", { style: styles.title, children: formId ? "Edit Dynamic Form" : "New Dynamic Form" }),
|
|
1569
|
+
/* @__PURE__ */ jsx7("p", { style: styles.description, children: "Configure fields, source mapping, layout, and triggers." })
|
|
449
1570
|
] }),
|
|
450
|
-
/* @__PURE__ */
|
|
451
|
-
/* @__PURE__ */
|
|
452
|
-
/* @__PURE__ */
|
|
1571
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.actions, children: [
|
|
1572
|
+
/* @__PURE__ */ jsx7("a", { href: options.backHref, style: styles.button, children: "Cancel" }),
|
|
1573
|
+
/* @__PURE__ */ jsx7("button", { type: "submit", disabled: isSaving, style: styles.primaryButton, children: isSaving ? "Saving..." : "Save" })
|
|
453
1574
|
] })
|
|
454
1575
|
] }),
|
|
455
|
-
/* @__PURE__ */
|
|
456
|
-
/* @__PURE__ */
|
|
457
|
-
/* @__PURE__ */
|
|
458
|
-
/* @__PURE__ */
|
|
459
|
-
/* @__PURE__ */
|
|
460
|
-
/* @__PURE__ */
|
|
1576
|
+
/* @__PURE__ */ jsxs7("section", { style: styles.section, children: [
|
|
1577
|
+
/* @__PURE__ */ jsx7("div", { style: styles.sectionHeader, children: /* @__PURE__ */ jsx7("h2", { style: styles.sectionTitle, children: "Details" }) }),
|
|
1578
|
+
/* @__PURE__ */ jsxs7("div", { style: { ...styles.grid, ...styles.twoColumn }, children: [
|
|
1579
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1580
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Title" }),
|
|
1581
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register("title", { required: true }) })
|
|
461
1582
|
] }),
|
|
462
|
-
/* @__PURE__ */
|
|
463
|
-
/* @__PURE__ */
|
|
464
|
-
/* @__PURE__ */
|
|
1583
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1584
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Description" }),
|
|
1585
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register("description") })
|
|
465
1586
|
] }),
|
|
466
|
-
/* @__PURE__ */
|
|
467
|
-
/* @__PURE__ */
|
|
468
|
-
/* @__PURE__ */
|
|
469
|
-
/* @__PURE__ */
|
|
470
|
-
/* @__PURE__ */
|
|
471
|
-
/* @__PURE__ */ jsx("option", { value: "apiEndpoint", children: "API endpoint" })
|
|
1587
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1588
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Presentation" }),
|
|
1589
|
+
/* @__PURE__ */ jsxs7("select", { style: styles.input, ...form.register("presentation"), children: [
|
|
1590
|
+
/* @__PURE__ */ jsx7("option", { value: "dialog", children: "Dialog" }),
|
|
1591
|
+
/* @__PURE__ */ jsx7("option", { value: "drawer", children: "Drawer" })
|
|
472
1592
|
] })
|
|
473
1593
|
] }),
|
|
474
|
-
|
|
475
|
-
/* @__PURE__ */
|
|
476
|
-
/* @__PURE__ */
|
|
477
|
-
/* @__PURE__ */
|
|
478
|
-
|
|
1594
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1595
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Datasource" }),
|
|
1596
|
+
/* @__PURE__ */ jsxs7("select", { style: styles.input, ...form.register("sourceType"), children: [
|
|
1597
|
+
/* @__PURE__ */ jsx7("option", { value: "none", children: "None" }),
|
|
1598
|
+
/* @__PURE__ */ jsx7("option", { value: "dbTable", children: "DB table" }),
|
|
1599
|
+
/* @__PURE__ */ jsx7("option", { value: "apiEndpoint", children: "API endpoint" })
|
|
1600
|
+
] })
|
|
1601
|
+
] }),
|
|
1602
|
+
sourceType === "dbTable" ? /* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1603
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Table" }),
|
|
1604
|
+
/* @__PURE__ */ jsxs7("select", { style: styles.input, ...form.register("sourceTable"), children: [
|
|
1605
|
+
/* @__PURE__ */ jsx7("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
|
|
1606
|
+
tables.map((table) => /* @__PURE__ */ jsx7("option", { value: table.name, children: table.label ?? table.name }, table.name))
|
|
479
1607
|
] })
|
|
480
1608
|
] }) : null,
|
|
481
|
-
sourceType === "apiEndpoint" ? /* @__PURE__ */
|
|
482
|
-
/* @__PURE__ */
|
|
483
|
-
/* @__PURE__ */
|
|
1609
|
+
sourceType === "apiEndpoint" ? /* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1610
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "API base path" }),
|
|
1611
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register("apiBasePath") })
|
|
484
1612
|
] }) : null,
|
|
485
|
-
sourceType === "dbTable" ? /* @__PURE__ */
|
|
1613
|
+
sourceType === "dbTable" ? /* @__PURE__ */ jsx7("div", { style: { ...styles.field, justifyContent: "end" }, children: /* @__PURE__ */ jsx7(
|
|
486
1614
|
"button",
|
|
487
1615
|
{
|
|
488
1616
|
type: "button",
|
|
@@ -494,13 +1622,13 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
494
1622
|
) }) : null
|
|
495
1623
|
] })
|
|
496
1624
|
] }),
|
|
497
|
-
/* @__PURE__ */
|
|
498
|
-
/* @__PURE__ */
|
|
499
|
-
/* @__PURE__ */
|
|
500
|
-
/* @__PURE__ */
|
|
501
|
-
/* @__PURE__ */
|
|
1625
|
+
/* @__PURE__ */ jsxs7("section", { style: styles.section, children: [
|
|
1626
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.sectionHeader, children: [
|
|
1627
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1628
|
+
/* @__PURE__ */ jsx7("h2", { style: styles.sectionTitle, children: "Fields" }),
|
|
1629
|
+
/* @__PURE__ */ jsx7("p", { style: styles.description, children: "Runtime form inputs." })
|
|
502
1630
|
] }),
|
|
503
|
-
/* @__PURE__ */
|
|
1631
|
+
/* @__PURE__ */ jsx7(
|
|
504
1632
|
"button",
|
|
505
1633
|
{
|
|
506
1634
|
type: "button",
|
|
@@ -518,18 +1646,18 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
518
1646
|
}
|
|
519
1647
|
)
|
|
520
1648
|
] }),
|
|
521
|
-
fieldArray.fields.map((field, index) => /* @__PURE__ */
|
|
522
|
-
/* @__PURE__ */
|
|
523
|
-
/* @__PURE__ */
|
|
524
|
-
/* @__PURE__ */
|
|
1649
|
+
fieldArray.fields.map((field, index) => /* @__PURE__ */ jsxs7("div", { style: styles.row, children: [
|
|
1650
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1651
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Key" }),
|
|
1652
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`fields.${index}.key`) })
|
|
525
1653
|
] }),
|
|
526
|
-
/* @__PURE__ */
|
|
527
|
-
/* @__PURE__ */
|
|
528
|
-
/* @__PURE__ */
|
|
1654
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1655
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Label" }),
|
|
1656
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`fields.${index}.label`) })
|
|
529
1657
|
] }),
|
|
530
|
-
/* @__PURE__ */
|
|
531
|
-
/* @__PURE__ */
|
|
532
|
-
/* @__PURE__ */
|
|
1658
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1659
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Type" }),
|
|
1660
|
+
/* @__PURE__ */ jsx7(
|
|
533
1661
|
"select",
|
|
534
1662
|
{
|
|
535
1663
|
style: styles.input,
|
|
@@ -538,27 +1666,27 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
538
1666
|
}
|
|
539
1667
|
)
|
|
540
1668
|
] }),
|
|
541
|
-
/* @__PURE__ */
|
|
542
|
-
/* @__PURE__ */
|
|
1669
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.checkboxField, children: [
|
|
1670
|
+
/* @__PURE__ */ jsx7("input", { type: "checkbox", ...form.register(`fields.${index}.required`) }),
|
|
543
1671
|
"Required"
|
|
544
1672
|
] }),
|
|
545
|
-
/* @__PURE__ */
|
|
546
|
-
/* @__PURE__ */
|
|
1673
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.checkboxField, children: [
|
|
1674
|
+
/* @__PURE__ */ jsx7("input", { type: "checkbox", ...form.register(`fields.${index}.hidden`) }),
|
|
547
1675
|
"Hidden"
|
|
548
1676
|
] }),
|
|
549
|
-
/* @__PURE__ */
|
|
550
|
-
/* @__PURE__ */
|
|
1677
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.checkboxField, children: [
|
|
1678
|
+
/* @__PURE__ */ jsx7("input", { type: "checkbox", ...form.register(`fields.${index}.disabled`) }),
|
|
551
1679
|
"Disabled"
|
|
552
1680
|
] }),
|
|
553
|
-
/* @__PURE__ */
|
|
554
|
-
/* @__PURE__ */
|
|
555
|
-
/* @__PURE__ */
|
|
1681
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1682
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Placeholder" }),
|
|
1683
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`fields.${index}.placeholder`) })
|
|
556
1684
|
] }),
|
|
557
|
-
/* @__PURE__ */
|
|
558
|
-
/* @__PURE__ */
|
|
559
|
-
/* @__PURE__ */
|
|
1685
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1686
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Static options" }),
|
|
1687
|
+
/* @__PURE__ */ jsx7("textarea", { style: styles.textarea, ...form.register(`fields.${index}.optionsText`) })
|
|
560
1688
|
] }),
|
|
561
|
-
/* @__PURE__ */
|
|
1689
|
+
/* @__PURE__ */ jsx7("div", { style: styles.actions, children: /* @__PURE__ */ jsx7(
|
|
562
1690
|
"button",
|
|
563
1691
|
{
|
|
564
1692
|
type: "button",
|
|
@@ -570,13 +1698,13 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
570
1698
|
) })
|
|
571
1699
|
] }, field.id))
|
|
572
1700
|
] }),
|
|
573
|
-
/* @__PURE__ */
|
|
574
|
-
/* @__PURE__ */
|
|
575
|
-
/* @__PURE__ */
|
|
576
|
-
/* @__PURE__ */
|
|
577
|
-
/* @__PURE__ */
|
|
1701
|
+
/* @__PURE__ */ jsxs7("section", { style: styles.section, children: [
|
|
1702
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.sectionHeader, children: [
|
|
1703
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1704
|
+
/* @__PURE__ */ jsx7("h2", { style: styles.sectionTitle, children: "Layout" }),
|
|
1705
|
+
/* @__PURE__ */ jsx7("p", { style: styles.description, children: "Default layout can be regenerated from current fields." })
|
|
578
1706
|
] }),
|
|
579
|
-
/* @__PURE__ */
|
|
1707
|
+
/* @__PURE__ */ jsx7(
|
|
580
1708
|
"button",
|
|
581
1709
|
{
|
|
582
1710
|
type: "button",
|
|
@@ -588,14 +1716,14 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
588
1716
|
}
|
|
589
1717
|
)
|
|
590
1718
|
] }),
|
|
591
|
-
form.watch("layoutGroups").map((group, groupIndex) => /* @__PURE__ */
|
|
592
|
-
/* @__PURE__ */
|
|
593
|
-
/* @__PURE__ */
|
|
594
|
-
/* @__PURE__ */
|
|
1719
|
+
form.watch("layoutGroups").map((group, groupIndex) => /* @__PURE__ */ jsxs7("div", { style: styles.row, children: [
|
|
1720
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1721
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Group title" }),
|
|
1722
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`layoutGroups.${groupIndex}.title`) })
|
|
595
1723
|
] }),
|
|
596
|
-
/* @__PURE__ */
|
|
597
|
-
/* @__PURE__ */
|
|
598
|
-
/* @__PURE__ */
|
|
1724
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1725
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Columns" }),
|
|
1726
|
+
/* @__PURE__ */ jsxs7(
|
|
599
1727
|
"select",
|
|
600
1728
|
{
|
|
601
1729
|
style: styles.input,
|
|
@@ -606,16 +1734,16 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
606
1734
|
{ shouldDirty: true }
|
|
607
1735
|
),
|
|
608
1736
|
children: [
|
|
609
|
-
/* @__PURE__ */
|
|
610
|
-
/* @__PURE__ */
|
|
611
|
-
/* @__PURE__ */
|
|
1737
|
+
/* @__PURE__ */ jsx7("option", { value: 6, children: "6" }),
|
|
1738
|
+
/* @__PURE__ */ jsx7("option", { value: 8, children: "8" }),
|
|
1739
|
+
/* @__PURE__ */ jsx7("option", { value: 12, children: "12" })
|
|
612
1740
|
]
|
|
613
1741
|
}
|
|
614
1742
|
)
|
|
615
1743
|
] }),
|
|
616
|
-
/* @__PURE__ */
|
|
617
|
-
/* @__PURE__ */
|
|
618
|
-
/* @__PURE__ */
|
|
1744
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1745
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Fields" }),
|
|
1746
|
+
/* @__PURE__ */ jsx7(
|
|
619
1747
|
"input",
|
|
620
1748
|
{
|
|
621
1749
|
style: styles.input,
|
|
@@ -626,13 +1754,13 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
626
1754
|
] })
|
|
627
1755
|
] }, group.id))
|
|
628
1756
|
] }),
|
|
629
|
-
/* @__PURE__ */
|
|
630
|
-
/* @__PURE__ */
|
|
631
|
-
/* @__PURE__ */
|
|
632
|
-
/* @__PURE__ */
|
|
633
|
-
/* @__PURE__ */
|
|
1757
|
+
/* @__PURE__ */ jsxs7("section", { style: styles.section, children: [
|
|
1758
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.sectionHeader, children: [
|
|
1759
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1760
|
+
/* @__PURE__ */ jsx7("h2", { style: styles.sectionTitle, children: "Subforms" }),
|
|
1761
|
+
/* @__PURE__ */ jsx7("p", { style: styles.description, children: "Optional nested runtime view bindings." })
|
|
634
1762
|
] }),
|
|
635
|
-
/* @__PURE__ */
|
|
1763
|
+
/* @__PURE__ */ jsx7(
|
|
636
1764
|
"button",
|
|
637
1765
|
{
|
|
638
1766
|
type: "button",
|
|
@@ -644,48 +1772,63 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
644
1772
|
parentField: "id",
|
|
645
1773
|
childField: "parentId",
|
|
646
1774
|
buttonLabel: "",
|
|
647
|
-
icon: ""
|
|
1775
|
+
icon: "",
|
|
1776
|
+
presentation: "dialog"
|
|
648
1777
|
}),
|
|
649
1778
|
children: "Add subform"
|
|
650
1779
|
}
|
|
651
1780
|
)
|
|
652
1781
|
] }),
|
|
653
|
-
subformArray.fields.map((subform, index) => /* @__PURE__ */
|
|
654
|
-
/* @__PURE__ */
|
|
655
|
-
/* @__PURE__ */
|
|
656
|
-
/* @__PURE__ */
|
|
1782
|
+
subformArray.fields.map((subform, index) => /* @__PURE__ */ jsxs7("div", { style: styles.row, children: [
|
|
1783
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1784
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Key" }),
|
|
1785
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`subforms.${index}.key`) })
|
|
657
1786
|
] }),
|
|
658
|
-
/* @__PURE__ */
|
|
659
|
-
/* @__PURE__ */
|
|
660
|
-
/* @__PURE__ */
|
|
1787
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1788
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Label" }),
|
|
1789
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`subforms.${index}.label`) })
|
|
661
1790
|
] }),
|
|
662
|
-
/* @__PURE__ */
|
|
663
|
-
/* @__PURE__ */
|
|
664
|
-
/* @__PURE__ */
|
|
1791
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1792
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "View ID" }),
|
|
1793
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`subforms.${index}.viewId`) })
|
|
665
1794
|
] }),
|
|
666
|
-
/* @__PURE__ */
|
|
667
|
-
/* @__PURE__ */
|
|
668
|
-
/* @__PURE__ */
|
|
1795
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1796
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Parent field" }),
|
|
1797
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`subforms.${index}.parentField`) })
|
|
669
1798
|
] }),
|
|
670
|
-
/* @__PURE__ */
|
|
671
|
-
/* @__PURE__ */
|
|
672
|
-
/* @__PURE__ */
|
|
1799
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1800
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Child field" }),
|
|
1801
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`subforms.${index}.childField`) })
|
|
1802
|
+
] }),
|
|
1803
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1804
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Presentation" }),
|
|
1805
|
+
/* @__PURE__ */ jsxs7(
|
|
1806
|
+
"select",
|
|
1807
|
+
{
|
|
1808
|
+
style: styles.input,
|
|
1809
|
+
...form.register(`subforms.${index}.presentation`),
|
|
1810
|
+
children: [
|
|
1811
|
+
/* @__PURE__ */ jsx7("option", { value: "dialog", children: "Dialog" }),
|
|
1812
|
+
/* @__PURE__ */ jsx7("option", { value: "drawer", children: "Drawer" })
|
|
1813
|
+
]
|
|
1814
|
+
}
|
|
1815
|
+
)
|
|
673
1816
|
] }),
|
|
674
|
-
/* @__PURE__ */
|
|
1817
|
+
/* @__PURE__ */ jsx7("button", { type: "button", style: styles.button, onClick: () => subformArray.remove(index), children: "Remove" })
|
|
675
1818
|
] }, subform.id))
|
|
676
1819
|
] }),
|
|
677
|
-
/* @__PURE__ */
|
|
678
|
-
/* @__PURE__ */
|
|
679
|
-
/* @__PURE__ */
|
|
680
|
-
/* @__PURE__ */
|
|
681
|
-
/* @__PURE__ */
|
|
1820
|
+
/* @__PURE__ */ jsxs7("section", { style: styles.section, children: [
|
|
1821
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.sectionHeader, children: [
|
|
1822
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1823
|
+
/* @__PURE__ */ jsx7("h2", { style: styles.sectionTitle, children: "Form Triggers" }),
|
|
1824
|
+
/* @__PURE__ */ jsx7("p", { style: styles.description, children: "Optional API callbacks for lifecycle events." })
|
|
682
1825
|
] }),
|
|
683
|
-
/* @__PURE__ */
|
|
1826
|
+
/* @__PURE__ */ jsx7("button", { type: "button", style: styles.button, onClick: () => triggerArray.append(emptyTrigger), children: "Add trigger" })
|
|
684
1827
|
] }),
|
|
685
|
-
triggerArray.fields.map((trigger, index) => /* @__PURE__ */
|
|
686
|
-
/* @__PURE__ */
|
|
687
|
-
/* @__PURE__ */
|
|
688
|
-
/* @__PURE__ */
|
|
1828
|
+
triggerArray.fields.map((trigger, index) => /* @__PURE__ */ jsxs7("div", { style: styles.row, children: [
|
|
1829
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1830
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Event" }),
|
|
1831
|
+
/* @__PURE__ */ jsx7(
|
|
689
1832
|
"select",
|
|
690
1833
|
{
|
|
691
1834
|
style: styles.input,
|
|
@@ -696,19 +1839,19 @@ function createBuilderDefaultFormEditorBody(options) {
|
|
|
696
1839
|
}
|
|
697
1840
|
)
|
|
698
1841
|
] }),
|
|
699
|
-
/* @__PURE__ */
|
|
700
|
-
/* @__PURE__ */
|
|
701
|
-
/* @__PURE__ */
|
|
1842
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1843
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Route" }),
|
|
1844
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`triggers.${index}.route`) })
|
|
702
1845
|
] }),
|
|
703
|
-
/* @__PURE__ */
|
|
704
|
-
/* @__PURE__ */
|
|
1846
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.checkboxField, children: [
|
|
1847
|
+
/* @__PURE__ */ jsx7("input", { type: "checkbox", ...form.register(`triggers.${index}.enabled`) }),
|
|
705
1848
|
"Enabled"
|
|
706
1849
|
] }),
|
|
707
|
-
/* @__PURE__ */
|
|
708
|
-
/* @__PURE__ */
|
|
1850
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.checkboxField, children: [
|
|
1851
|
+
/* @__PURE__ */ jsx7("input", { type: "checkbox", ...form.register(`triggers.${index}.blocking`) }),
|
|
709
1852
|
"Blocking"
|
|
710
1853
|
] }),
|
|
711
|
-
/* @__PURE__ */
|
|
1854
|
+
/* @__PURE__ */ jsx7("button", { type: "button", style: styles.button, onClick: () => triggerArray.remove(index), children: "Remove" })
|
|
712
1855
|
] }, trigger.id))
|
|
713
1856
|
] })
|
|
714
1857
|
] });
|
|
@@ -728,48 +1871,48 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
728
1871
|
isSaving,
|
|
729
1872
|
importColumnsFromTable
|
|
730
1873
|
}) {
|
|
731
|
-
return /* @__PURE__ */
|
|
732
|
-
/* @__PURE__ */
|
|
733
|
-
/* @__PURE__ */
|
|
734
|
-
/* @__PURE__ */
|
|
735
|
-
/* @__PURE__ */
|
|
1874
|
+
return /* @__PURE__ */ jsxs7("div", { style: styles.page, children: [
|
|
1875
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.header, children: [
|
|
1876
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1877
|
+
/* @__PURE__ */ jsx7("h1", { style: styles.title, children: listId ? "Edit Dynamic List" : "New Dynamic List" }),
|
|
1878
|
+
/* @__PURE__ */ jsx7("p", { style: styles.description, children: "Configure list columns, source mapping, and triggers." })
|
|
736
1879
|
] }),
|
|
737
|
-
/* @__PURE__ */
|
|
738
|
-
/* @__PURE__ */
|
|
739
|
-
/* @__PURE__ */
|
|
1880
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.actions, children: [
|
|
1881
|
+
/* @__PURE__ */ jsx7("a", { href: options.backHref, style: styles.button, children: "Cancel" }),
|
|
1882
|
+
/* @__PURE__ */ jsx7("button", { type: "submit", disabled: isSaving, style: styles.primaryButton, children: isSaving ? "Saving..." : "Save" })
|
|
740
1883
|
] })
|
|
741
1884
|
] }),
|
|
742
|
-
/* @__PURE__ */
|
|
743
|
-
/* @__PURE__ */
|
|
744
|
-
/* @__PURE__ */
|
|
745
|
-
/* @__PURE__ */
|
|
746
|
-
/* @__PURE__ */
|
|
747
|
-
/* @__PURE__ */
|
|
1885
|
+
/* @__PURE__ */ jsxs7("section", { style: styles.section, children: [
|
|
1886
|
+
/* @__PURE__ */ jsx7("div", { style: styles.sectionHeader, children: /* @__PURE__ */ jsx7("h2", { style: styles.sectionTitle, children: "Details" }) }),
|
|
1887
|
+
/* @__PURE__ */ jsxs7("div", { style: { ...styles.grid, ...styles.twoColumn }, children: [
|
|
1888
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1889
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Title" }),
|
|
1890
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register("title", { required: true }) })
|
|
748
1891
|
] }),
|
|
749
|
-
/* @__PURE__ */
|
|
750
|
-
/* @__PURE__ */
|
|
751
|
-
/* @__PURE__ */
|
|
1892
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1893
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Description" }),
|
|
1894
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register("description") })
|
|
752
1895
|
] }),
|
|
753
|
-
/* @__PURE__ */
|
|
754
|
-
/* @__PURE__ */
|
|
755
|
-
/* @__PURE__ */
|
|
756
|
-
/* @__PURE__ */
|
|
757
|
-
/* @__PURE__ */
|
|
758
|
-
/* @__PURE__ */
|
|
1896
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1897
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Datasource" }),
|
|
1898
|
+
/* @__PURE__ */ jsxs7("select", { style: styles.input, ...form.register("sourceType"), children: [
|
|
1899
|
+
/* @__PURE__ */ jsx7("option", { value: "none", children: "None" }),
|
|
1900
|
+
/* @__PURE__ */ jsx7("option", { value: "dbTable", children: "DB table" }),
|
|
1901
|
+
/* @__PURE__ */ jsx7("option", { value: "apiEndpoint", children: "API endpoint" })
|
|
759
1902
|
] })
|
|
760
1903
|
] }),
|
|
761
|
-
sourceType === "dbTable" ? /* @__PURE__ */
|
|
762
|
-
/* @__PURE__ */
|
|
763
|
-
/* @__PURE__ */
|
|
764
|
-
/* @__PURE__ */
|
|
765
|
-
tables.map((table) => /* @__PURE__ */
|
|
1904
|
+
sourceType === "dbTable" ? /* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1905
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Table" }),
|
|
1906
|
+
/* @__PURE__ */ jsxs7("select", { style: styles.input, ...form.register("sourceTable"), children: [
|
|
1907
|
+
/* @__PURE__ */ jsx7("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "Select table" }),
|
|
1908
|
+
tables.map((table) => /* @__PURE__ */ jsx7("option", { value: table.name, children: table.label ?? table.name }, table.name))
|
|
766
1909
|
] })
|
|
767
1910
|
] }) : null,
|
|
768
|
-
sourceType === "apiEndpoint" ? /* @__PURE__ */
|
|
769
|
-
/* @__PURE__ */
|
|
770
|
-
/* @__PURE__ */
|
|
1911
|
+
sourceType === "apiEndpoint" ? /* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1912
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "API base path" }),
|
|
1913
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register("apiBasePath") })
|
|
771
1914
|
] }) : null,
|
|
772
|
-
sourceType === "dbTable" ? /* @__PURE__ */
|
|
1915
|
+
sourceType === "dbTable" ? /* @__PURE__ */ jsx7("div", { style: { ...styles.field, justifyContent: "end" }, children: /* @__PURE__ */ jsx7(
|
|
773
1916
|
"button",
|
|
774
1917
|
{
|
|
775
1918
|
type: "button",
|
|
@@ -781,13 +1924,13 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
781
1924
|
) }) : null
|
|
782
1925
|
] })
|
|
783
1926
|
] }),
|
|
784
|
-
/* @__PURE__ */
|
|
785
|
-
/* @__PURE__ */
|
|
786
|
-
/* @__PURE__ */
|
|
787
|
-
/* @__PURE__ */
|
|
788
|
-
/* @__PURE__ */
|
|
1927
|
+
/* @__PURE__ */ jsxs7("section", { style: styles.section, children: [
|
|
1928
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.sectionHeader, children: [
|
|
1929
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1930
|
+
/* @__PURE__ */ jsx7("h2", { style: styles.sectionTitle, children: "Columns" }),
|
|
1931
|
+
/* @__PURE__ */ jsx7("p", { style: styles.description, children: "Runtime list columns." })
|
|
789
1932
|
] }),
|
|
790
|
-
/* @__PURE__ */
|
|
1933
|
+
/* @__PURE__ */ jsx7(
|
|
791
1934
|
"button",
|
|
792
1935
|
{
|
|
793
1936
|
type: "button",
|
|
@@ -801,27 +1944,27 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
801
1944
|
}
|
|
802
1945
|
)
|
|
803
1946
|
] }),
|
|
804
|
-
columnArray.fields.map((column, index) => /* @__PURE__ */
|
|
805
|
-
/* @__PURE__ */
|
|
806
|
-
/* @__PURE__ */
|
|
807
|
-
/* @__PURE__ */
|
|
1947
|
+
columnArray.fields.map((column, index) => /* @__PURE__ */ jsxs7("div", { style: styles.row, children: [
|
|
1948
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1949
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Key" }),
|
|
1950
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`columns.${index}.key`) })
|
|
808
1951
|
] }),
|
|
809
|
-
/* @__PURE__ */
|
|
810
|
-
/* @__PURE__ */
|
|
811
|
-
/* @__PURE__ */
|
|
1952
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1953
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Label" }),
|
|
1954
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`columns.${index}.label`) })
|
|
812
1955
|
] }),
|
|
813
|
-
/* @__PURE__ */
|
|
814
|
-
/* @__PURE__ */
|
|
815
|
-
/* @__PURE__ */
|
|
816
|
-
/* @__PURE__ */
|
|
817
|
-
/* @__PURE__ */
|
|
1956
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1957
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Align" }),
|
|
1958
|
+
/* @__PURE__ */ jsxs7("select", { style: styles.input, ...form.register(`columns.${index}.align`), children: [
|
|
1959
|
+
/* @__PURE__ */ jsx7("option", { value: "left", children: "Left" }),
|
|
1960
|
+
/* @__PURE__ */ jsx7("option", { value: "right", children: "Right" })
|
|
818
1961
|
] })
|
|
819
1962
|
] }),
|
|
820
|
-
/* @__PURE__ */
|
|
821
|
-
/* @__PURE__ */
|
|
1963
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.checkboxField, children: [
|
|
1964
|
+
/* @__PURE__ */ jsx7("input", { type: "checkbox", ...form.register(`columns.${index}.sortable`) }),
|
|
822
1965
|
"Sortable"
|
|
823
1966
|
] }),
|
|
824
|
-
/* @__PURE__ */
|
|
1967
|
+
/* @__PURE__ */ jsx7(
|
|
825
1968
|
"button",
|
|
826
1969
|
{
|
|
827
1970
|
type: "button",
|
|
@@ -833,18 +1976,18 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
833
1976
|
)
|
|
834
1977
|
] }, column.id))
|
|
835
1978
|
] }),
|
|
836
|
-
/* @__PURE__ */
|
|
837
|
-
/* @__PURE__ */
|
|
838
|
-
/* @__PURE__ */
|
|
839
|
-
/* @__PURE__ */
|
|
840
|
-
/* @__PURE__ */
|
|
1979
|
+
/* @__PURE__ */ jsxs7("section", { style: styles.section, children: [
|
|
1980
|
+
/* @__PURE__ */ jsxs7("div", { style: styles.sectionHeader, children: [
|
|
1981
|
+
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1982
|
+
/* @__PURE__ */ jsx7("h2", { style: styles.sectionTitle, children: "List Triggers" }),
|
|
1983
|
+
/* @__PURE__ */ jsx7("p", { style: styles.description, children: "Optional API callbacks for list lifecycle events." })
|
|
841
1984
|
] }),
|
|
842
|
-
/* @__PURE__ */
|
|
1985
|
+
/* @__PURE__ */ jsx7("button", { type: "button", style: styles.button, onClick: () => triggerArray.append(emptyTrigger), children: "Add trigger" })
|
|
843
1986
|
] }),
|
|
844
|
-
triggerArray.fields.map((trigger, index) => /* @__PURE__ */
|
|
845
|
-
/* @__PURE__ */
|
|
846
|
-
/* @__PURE__ */
|
|
847
|
-
/* @__PURE__ */
|
|
1987
|
+
triggerArray.fields.map((trigger, index) => /* @__PURE__ */ jsxs7("div", { style: styles.row, children: [
|
|
1988
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
1989
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Event" }),
|
|
1990
|
+
/* @__PURE__ */ jsx7(
|
|
848
1991
|
"select",
|
|
849
1992
|
{
|
|
850
1993
|
style: styles.input,
|
|
@@ -855,19 +1998,19 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
855
1998
|
}
|
|
856
1999
|
)
|
|
857
2000
|
] }),
|
|
858
|
-
/* @__PURE__ */
|
|
859
|
-
/* @__PURE__ */
|
|
860
|
-
/* @__PURE__ */
|
|
2001
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.field, children: [
|
|
2002
|
+
/* @__PURE__ */ jsx7("span", { style: styles.label, children: "Route" }),
|
|
2003
|
+
/* @__PURE__ */ jsx7("input", { style: styles.input, ...form.register(`triggers.${index}.route`) })
|
|
861
2004
|
] }),
|
|
862
|
-
/* @__PURE__ */
|
|
863
|
-
/* @__PURE__ */
|
|
2005
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.checkboxField, children: [
|
|
2006
|
+
/* @__PURE__ */ jsx7("input", { type: "checkbox", ...form.register(`triggers.${index}.enabled`) }),
|
|
864
2007
|
"Enabled"
|
|
865
2008
|
] }),
|
|
866
|
-
/* @__PURE__ */
|
|
867
|
-
/* @__PURE__ */
|
|
2009
|
+
/* @__PURE__ */ jsxs7("label", { style: styles.checkboxField, children: [
|
|
2010
|
+
/* @__PURE__ */ jsx7("input", { type: "checkbox", ...form.register(`triggers.${index}.blocking`) }),
|
|
868
2011
|
"Blocking"
|
|
869
2012
|
] }),
|
|
870
|
-
/* @__PURE__ */
|
|
2013
|
+
/* @__PURE__ */ jsx7("button", { type: "button", style: styles.button, onClick: () => triggerArray.remove(index), children: "Remove" })
|
|
871
2014
|
] }, trigger.id))
|
|
872
2015
|
] })
|
|
873
2016
|
] });
|
|
@@ -875,8 +2018,8 @@ function createBuilderDefaultListEditorBody(options) {
|
|
|
875
2018
|
}
|
|
876
2019
|
|
|
877
2020
|
// src/admin/BuilderDefaultEntityManager.tsx
|
|
878
|
-
import { useMemo, useState } from "react";
|
|
879
|
-
import { jsx as
|
|
2021
|
+
import { useMemo as useMemo5, useState as useState5 } from "react";
|
|
2022
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
880
2023
|
var styles2 = {
|
|
881
2024
|
page: {
|
|
882
2025
|
display: "grid",
|
|
@@ -972,12 +2115,12 @@ var styles2 = {
|
|
|
972
2115
|
};
|
|
973
2116
|
function createBuilderDefaultEntityManagerComponent(deps) {
|
|
974
2117
|
return function BuilderDefaultEntityManager() {
|
|
975
|
-
const [state, setState] =
|
|
2118
|
+
const [state, setState] = useState5({
|
|
976
2119
|
page: 1,
|
|
977
2120
|
pageSize: 20,
|
|
978
2121
|
search: ""
|
|
979
2122
|
});
|
|
980
|
-
const query = deps.hooks.useEntities(
|
|
2123
|
+
const query = deps.hooks.useEntities(useMemo5(() => deps.buildQuery(state), [state]));
|
|
981
2124
|
const remove = deps.hooks.useDelete();
|
|
982
2125
|
const replicate = deps.hooks.useReplicate();
|
|
983
2126
|
const items = query.data?.items ?? [];
|
|
@@ -993,16 +2136,16 @@ function createBuilderDefaultEntityManagerComponent(deps) {
|
|
|
993
2136
|
if (!window.confirm(deps.labels.deleteConfirm(entity))) return;
|
|
994
2137
|
await remove.mutateAsync(entity.id);
|
|
995
2138
|
};
|
|
996
|
-
return /* @__PURE__ */
|
|
997
|
-
/* @__PURE__ */
|
|
998
|
-
/* @__PURE__ */
|
|
999
|
-
/* @__PURE__ */
|
|
1000
|
-
/* @__PURE__ */
|
|
2139
|
+
return /* @__PURE__ */ jsxs8("section", { style: styles2.page, children: [
|
|
2140
|
+
/* @__PURE__ */ jsxs8("div", { style: styles2.header, children: [
|
|
2141
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
2142
|
+
/* @__PURE__ */ jsx8("h1", { style: styles2.title, children: deps.labels.title }),
|
|
2143
|
+
/* @__PURE__ */ jsx8("p", { style: styles2.description, children: deps.labels.description })
|
|
1001
2144
|
] }),
|
|
1002
|
-
deps.createHref ? /* @__PURE__ */
|
|
2145
|
+
deps.createHref ? /* @__PURE__ */ jsx8("a", { href: deps.createHref, style: styles2.primaryButton, children: deps.labels.addLabel }) : null
|
|
1003
2146
|
] }),
|
|
1004
|
-
/* @__PURE__ */
|
|
1005
|
-
/* @__PURE__ */
|
|
2147
|
+
/* @__PURE__ */ jsxs8("div", { style: styles2.card, children: [
|
|
2148
|
+
/* @__PURE__ */ jsx8("div", { style: styles2.toolbar, children: /* @__PURE__ */ jsx8(
|
|
1006
2149
|
"input",
|
|
1007
2150
|
{
|
|
1008
2151
|
style: styles2.input,
|
|
@@ -1011,21 +2154,21 @@ function createBuilderDefaultEntityManagerComponent(deps) {
|
|
|
1011
2154
|
onChange: (event) => setState((current) => ({ ...current, page: 1, search: event.target.value }))
|
|
1012
2155
|
}
|
|
1013
2156
|
) }),
|
|
1014
|
-
/* @__PURE__ */
|
|
1015
|
-
/* @__PURE__ */
|
|
1016
|
-
/* @__PURE__ */
|
|
1017
|
-
/* @__PURE__ */
|
|
1018
|
-
/* @__PURE__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
2157
|
+
/* @__PURE__ */ jsx8("div", { style: styles2.tableWrap, children: /* @__PURE__ */ jsxs8("table", { style: styles2.table, children: [
|
|
2158
|
+
/* @__PURE__ */ jsx8("thead", { children: /* @__PURE__ */ jsxs8("tr", { children: [
|
|
2159
|
+
/* @__PURE__ */ jsx8("th", { style: styles2.th, children: deps.labels.title }),
|
|
2160
|
+
/* @__PURE__ */ jsx8("th", { style: styles2.th, children: "Detail" }),
|
|
2161
|
+
/* @__PURE__ */ jsx8("th", { style: styles2.th, children: "Description" }),
|
|
2162
|
+
/* @__PURE__ */ jsx8("th", { style: { ...styles2.th, textAlign: "right" }, children: "Actions" })
|
|
1020
2163
|
] }) }),
|
|
1021
|
-
/* @__PURE__ */
|
|
1022
|
-
/* @__PURE__ */
|
|
1023
|
-
/* @__PURE__ */
|
|
1024
|
-
/* @__PURE__ */
|
|
1025
|
-
/* @__PURE__ */
|
|
1026
|
-
deps.runtimeHref ? /* @__PURE__ */
|
|
1027
|
-
/* @__PURE__ */
|
|
1028
|
-
/* @__PURE__ */
|
|
2164
|
+
/* @__PURE__ */ jsx8("tbody", { children: items.map((entity) => /* @__PURE__ */ jsxs8("tr", { children: [
|
|
2165
|
+
/* @__PURE__ */ jsx8("td", { style: styles2.td, children: /* @__PURE__ */ jsx8("a", { href: deps.editHref(entity), children: entity.title }) }),
|
|
2166
|
+
/* @__PURE__ */ jsx8("td", { style: styles2.td, children: deps.getDetail?.(entity) ?? "-" }),
|
|
2167
|
+
/* @__PURE__ */ jsx8("td", { style: styles2.td, children: entity.description || "-" }),
|
|
2168
|
+
/* @__PURE__ */ jsx8("td", { style: styles2.td, children: /* @__PURE__ */ jsxs8("div", { style: styles2.actions, children: [
|
|
2169
|
+
deps.runtimeHref ? /* @__PURE__ */ jsx8("a", { href: deps.runtimeHref(entity), style: styles2.button, children: deps.labels.runtimeLabel }) : null,
|
|
2170
|
+
/* @__PURE__ */ jsx8("a", { href: deps.editHref(entity), style: styles2.button, children: deps.labels.editLabel }),
|
|
2171
|
+
/* @__PURE__ */ jsx8(
|
|
1029
2172
|
"button",
|
|
1030
2173
|
{
|
|
1031
2174
|
type: "button",
|
|
@@ -1034,7 +2177,7 @@ function createBuilderDefaultEntityManagerComponent(deps) {
|
|
|
1034
2177
|
children: deps.labels.replicateLabel
|
|
1035
2178
|
}
|
|
1036
2179
|
),
|
|
1037
|
-
/* @__PURE__ */
|
|
2180
|
+
/* @__PURE__ */ jsx8(
|
|
1038
2181
|
"button",
|
|
1039
2182
|
{
|
|
1040
2183
|
type: "button",
|
|
@@ -1047,11 +2190,11 @@ function createBuilderDefaultEntityManagerComponent(deps) {
|
|
|
1047
2190
|
] }) })
|
|
1048
2191
|
] }, entity.id)) })
|
|
1049
2192
|
] }) }),
|
|
1050
|
-
query.isPending ? /* @__PURE__ */
|
|
1051
|
-
query.isError ? /* @__PURE__ */
|
|
1052
|
-
!query.isPending && !query.isError && items.length === 0 ? /* @__PURE__ */
|
|
1053
|
-
/* @__PURE__ */
|
|
1054
|
-
/* @__PURE__ */
|
|
2193
|
+
query.isPending ? /* @__PURE__ */ jsx8("div", { style: styles2.empty, children: "Loading..." }) : null,
|
|
2194
|
+
query.isError ? /* @__PURE__ */ jsx8("div", { style: styles2.empty, children: "Failed to load." }) : null,
|
|
2195
|
+
!query.isPending && !query.isError && items.length === 0 ? /* @__PURE__ */ jsxs8("div", { style: styles2.empty, children: [
|
|
2196
|
+
/* @__PURE__ */ jsx8("strong", { children: deps.labels.emptyTitle }),
|
|
2197
|
+
/* @__PURE__ */ jsx8("div", { children: deps.labels.emptyDescription })
|
|
1055
2198
|
] }) : null
|
|
1056
2199
|
] })
|
|
1057
2200
|
] });
|
|
@@ -1059,9 +2202,9 @@ function createBuilderDefaultEntityManagerComponent(deps) {
|
|
|
1059
2202
|
}
|
|
1060
2203
|
|
|
1061
2204
|
// src/admin/BuilderDefaultViewEditorPage.tsx
|
|
1062
|
-
import { useEffect } from "react";
|
|
1063
|
-
import { useForm } from "react-hook-form";
|
|
1064
|
-
import { Fragment, jsx as
|
|
2205
|
+
import { useEffect as useEffect3 } from "react";
|
|
2206
|
+
import { useForm as useForm3 } from "react-hook-form";
|
|
2207
|
+
import { Fragment, jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1065
2208
|
var styles3 = {
|
|
1066
2209
|
page: {
|
|
1067
2210
|
display: "grid",
|
|
@@ -1171,14 +2314,14 @@ function createBuilderDefaultViewEditorPage(options) {
|
|
|
1171
2314
|
const forms = options.hooks.useBuilderFormOptions();
|
|
1172
2315
|
const lists = options.hooks.useBuilderListOptions();
|
|
1173
2316
|
const save = options.hooks.useSaveBuilderView();
|
|
1174
|
-
const form =
|
|
2317
|
+
const form = useForm3({
|
|
1175
2318
|
defaultValues: {
|
|
1176
2319
|
...defaultEmptyValues,
|
|
1177
2320
|
permissionRead: defaultPermission,
|
|
1178
2321
|
permissionWrite: defaultPermission
|
|
1179
2322
|
}
|
|
1180
2323
|
});
|
|
1181
|
-
|
|
2324
|
+
useEffect3(() => {
|
|
1182
2325
|
if (viewId && !view.data) return;
|
|
1183
2326
|
form.reset(
|
|
1184
2327
|
builderViewEditorValuesFromEntity(
|
|
@@ -1209,64 +2352,64 @@ function createBuilderDefaultViewEditorPage(options) {
|
|
|
1209
2352
|
}
|
|
1210
2353
|
});
|
|
1211
2354
|
if (viewId && view.isPending) {
|
|
1212
|
-
return /* @__PURE__ */
|
|
2355
|
+
return /* @__PURE__ */ jsx9("div", { style: styles3.state, children: "Loading..." });
|
|
1213
2356
|
}
|
|
1214
2357
|
if (viewId && view.isError) {
|
|
1215
|
-
return /* @__PURE__ */
|
|
2358
|
+
return /* @__PURE__ */ jsx9("div", { style: styles3.state, children: "Failed to load view." });
|
|
1216
2359
|
}
|
|
1217
|
-
return /* @__PURE__ */
|
|
1218
|
-
/* @__PURE__ */
|
|
1219
|
-
/* @__PURE__ */
|
|
1220
|
-
/* @__PURE__ */
|
|
1221
|
-
/* @__PURE__ */
|
|
2360
|
+
return /* @__PURE__ */ jsxs9("form", { onSubmit, noValidate: true, style: styles3.page, children: [
|
|
2361
|
+
/* @__PURE__ */ jsxs9("div", { style: styles3.header, children: [
|
|
2362
|
+
/* @__PURE__ */ jsxs9("div", { children: [
|
|
2363
|
+
/* @__PURE__ */ jsx9("h1", { style: styles3.title, children: viewId ? "Edit Dynamic View" : "New Dynamic View" }),
|
|
2364
|
+
/* @__PURE__ */ jsx9("p", { style: styles3.description, children: "Connect a form and list into a runtime screen." })
|
|
1222
2365
|
] }),
|
|
1223
|
-
/* @__PURE__ */
|
|
1224
|
-
/* @__PURE__ */
|
|
1225
|
-
/* @__PURE__ */
|
|
2366
|
+
/* @__PURE__ */ jsxs9("div", { style: styles3.actions, children: [
|
|
2367
|
+
/* @__PURE__ */ jsx9("a", { href: options.backHref, style: styles3.button, children: "Cancel" }),
|
|
2368
|
+
/* @__PURE__ */ jsx9("button", { type: "submit", disabled: save.isPending, style: styles3.primaryButton, children: save.isPending ? "Saving..." : "Save" })
|
|
1226
2369
|
] })
|
|
1227
2370
|
] }),
|
|
1228
|
-
/* @__PURE__ */
|
|
1229
|
-
/* @__PURE__ */
|
|
1230
|
-
/* @__PURE__ */
|
|
1231
|
-
/* @__PURE__ */
|
|
2371
|
+
/* @__PURE__ */ jsx9("section", { style: styles3.section, children: /* @__PURE__ */ jsxs9("div", { style: styles3.grid, children: [
|
|
2372
|
+
/* @__PURE__ */ jsxs9("label", { style: styles3.field, children: [
|
|
2373
|
+
/* @__PURE__ */ jsx9("span", { style: styles3.label, children: "Title" }),
|
|
2374
|
+
/* @__PURE__ */ jsx9("input", { style: styles3.input, ...form.register("title", { required: true }) })
|
|
1232
2375
|
] }),
|
|
1233
|
-
/* @__PURE__ */
|
|
1234
|
-
/* @__PURE__ */
|
|
1235
|
-
/* @__PURE__ */
|
|
2376
|
+
/* @__PURE__ */ jsxs9("label", { style: styles3.field, children: [
|
|
2377
|
+
/* @__PURE__ */ jsx9("span", { style: styles3.label, children: "Description" }),
|
|
2378
|
+
/* @__PURE__ */ jsx9("input", { style: styles3.input, ...form.register("description") })
|
|
1236
2379
|
] }),
|
|
1237
|
-
/* @__PURE__ */
|
|
1238
|
-
/* @__PURE__ */
|
|
1239
|
-
/* @__PURE__ */
|
|
1240
|
-
/* @__PURE__ */
|
|
1241
|
-
(forms.data ?? []).map((item) => /* @__PURE__ */
|
|
2380
|
+
/* @__PURE__ */ jsxs9("label", { style: styles3.field, children: [
|
|
2381
|
+
/* @__PURE__ */ jsx9("span", { style: styles3.label, children: "Form" }),
|
|
2382
|
+
/* @__PURE__ */ jsxs9("select", { style: styles3.input, ...form.register("formId"), children: [
|
|
2383
|
+
/* @__PURE__ */ jsx9("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "No form" }),
|
|
2384
|
+
(forms.data ?? []).map((item) => /* @__PURE__ */ jsx9("option", { value: item.id, children: item.title }, item.id))
|
|
1242
2385
|
] })
|
|
1243
2386
|
] }),
|
|
1244
|
-
/* @__PURE__ */
|
|
1245
|
-
/* @__PURE__ */
|
|
1246
|
-
/* @__PURE__ */
|
|
1247
|
-
/* @__PURE__ */
|
|
1248
|
-
(lists.data ?? []).map((item) => /* @__PURE__ */
|
|
2387
|
+
/* @__PURE__ */ jsxs9("label", { style: styles3.field, children: [
|
|
2388
|
+
/* @__PURE__ */ jsx9("span", { style: styles3.label, children: "List" }),
|
|
2389
|
+
/* @__PURE__ */ jsxs9("select", { style: styles3.input, ...form.register("listId"), children: [
|
|
2390
|
+
/* @__PURE__ */ jsx9("option", { value: BUILDER_EDITOR_NONE_VALUE, children: "No list" }),
|
|
2391
|
+
(lists.data ?? []).map((item) => /* @__PURE__ */ jsx9("option", { value: item.id, children: item.title }, item.id))
|
|
1249
2392
|
] })
|
|
1250
2393
|
] }),
|
|
1251
|
-
showPermissions ? /* @__PURE__ */
|
|
1252
|
-
/* @__PURE__ */
|
|
1253
|
-
/* @__PURE__ */
|
|
1254
|
-
/* @__PURE__ */
|
|
1255
|
-
/* @__PURE__ */
|
|
1256
|
-
options.permissionOptions.map((permission) => /* @__PURE__ */
|
|
2394
|
+
showPermissions ? /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
2395
|
+
/* @__PURE__ */ jsxs9("label", { style: styles3.field, children: [
|
|
2396
|
+
/* @__PURE__ */ jsx9("span", { style: styles3.label, children: "Read permission" }),
|
|
2397
|
+
/* @__PURE__ */ jsxs9("select", { style: styles3.input, ...form.register("permissionRead"), children: [
|
|
2398
|
+
/* @__PURE__ */ jsx9("option", { value: "", children: "Authenticated users" }),
|
|
2399
|
+
options.permissionOptions.map((permission) => /* @__PURE__ */ jsx9("option", { value: permission.value, children: permission.label }, permission.value))
|
|
1257
2400
|
] })
|
|
1258
2401
|
] }),
|
|
1259
|
-
/* @__PURE__ */
|
|
1260
|
-
/* @__PURE__ */
|
|
1261
|
-
/* @__PURE__ */
|
|
1262
|
-
/* @__PURE__ */
|
|
1263
|
-
options.permissionOptions.map((permission) => /* @__PURE__ */
|
|
2402
|
+
/* @__PURE__ */ jsxs9("label", { style: styles3.field, children: [
|
|
2403
|
+
/* @__PURE__ */ jsx9("span", { style: styles3.label, children: "Write permission" }),
|
|
2404
|
+
/* @__PURE__ */ jsxs9("select", { style: styles3.input, ...form.register("permissionWrite"), children: [
|
|
2405
|
+
/* @__PURE__ */ jsx9("option", { value: "", children: "Authenticated users" }),
|
|
2406
|
+
options.permissionOptions.map((permission) => /* @__PURE__ */ jsx9("option", { value: permission.value, children: permission.label }, permission.value))
|
|
1264
2407
|
] })
|
|
1265
2408
|
] })
|
|
1266
2409
|
] }) : null,
|
|
1267
|
-
/* @__PURE__ */
|
|
1268
|
-
/* @__PURE__ */
|
|
1269
|
-
/* @__PURE__ */
|
|
2410
|
+
/* @__PURE__ */ jsxs9("label", { style: { ...styles3.field, gridColumn: "1 / -1" }, children: [
|
|
2411
|
+
/* @__PURE__ */ jsx9("span", { style: styles3.label, children: "Triggers JSON" }),
|
|
2412
|
+
/* @__PURE__ */ jsx9("textarea", { style: styles3.textarea, ...form.register("triggersText") })
|
|
1270
2413
|
] })
|
|
1271
2414
|
] }) })
|
|
1272
2415
|
] });
|
|
@@ -1274,32 +2417,32 @@ function createBuilderDefaultViewEditorPage(options) {
|
|
|
1274
2417
|
}
|
|
1275
2418
|
|
|
1276
2419
|
// src/admin/BuilderEditorPage.tsx
|
|
1277
|
-
import { useEffect as
|
|
2420
|
+
import { useEffect as useEffect4 } from "react";
|
|
1278
2421
|
import {
|
|
1279
|
-
FormProvider,
|
|
2422
|
+
FormProvider as FormProvider3,
|
|
1280
2423
|
useFieldArray,
|
|
1281
|
-
useForm as
|
|
1282
|
-
useWatch
|
|
2424
|
+
useForm as useForm4,
|
|
2425
|
+
useWatch as useWatch2
|
|
1283
2426
|
} from "react-hook-form";
|
|
1284
|
-
import { jsx as
|
|
2427
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1285
2428
|
function createBuilderFormEditorPageComponent(deps) {
|
|
1286
2429
|
return function BuilderFormEditorPage({ formId }) {
|
|
1287
2430
|
const Body = deps.Body;
|
|
1288
2431
|
const entityQuery = deps.hooks.useEntity(formId);
|
|
1289
2432
|
const tables = deps.hooks.useTables();
|
|
1290
2433
|
const save = deps.hooks.useSave();
|
|
1291
|
-
const form =
|
|
2434
|
+
const form = useForm4({
|
|
1292
2435
|
resolver: deps.resolver,
|
|
1293
2436
|
defaultValues: deps.emptyValues
|
|
1294
2437
|
});
|
|
1295
2438
|
const fieldArray = useFieldArray({ control: form.control, name: "fields" });
|
|
1296
2439
|
const subformArray = useFieldArray({ control: form.control, name: "subforms" });
|
|
1297
2440
|
const triggerArray = useFieldArray({ control: form.control, name: "triggers" });
|
|
1298
|
-
const fields =
|
|
1299
|
-
const subforms =
|
|
1300
|
-
const sourceType =
|
|
1301
|
-
const sourceTable =
|
|
1302
|
-
|
|
2441
|
+
const fields = useWatch2({ control: form.control, name: "fields" }) ?? [];
|
|
2442
|
+
const subforms = useWatch2({ control: form.control, name: "subforms" }) ?? [];
|
|
2443
|
+
const sourceType = useWatch2({ control: form.control, name: "sourceType" });
|
|
2444
|
+
const sourceTable = useWatch2({ control: form.control, name: "sourceTable" });
|
|
2445
|
+
useEffect4(() => {
|
|
1303
2446
|
if (formId && !entityQuery.data) return;
|
|
1304
2447
|
form.reset(builderFormEditorValuesFromEntity(entityQuery.data ?? null, deps.emptyValues));
|
|
1305
2448
|
}, [entityQuery.data, form, formId]);
|
|
@@ -1322,12 +2465,12 @@ function createBuilderFormEditorPageComponent(deps) {
|
|
|
1322
2465
|
}
|
|
1323
2466
|
});
|
|
1324
2467
|
if (formId && entityQuery.isPending) {
|
|
1325
|
-
return /* @__PURE__ */
|
|
2468
|
+
return /* @__PURE__ */ jsx10("div", { className: "text-muted-foreground text-sm", children: deps.states.loading });
|
|
1326
2469
|
}
|
|
1327
2470
|
if (formId && entityQuery.isError) {
|
|
1328
|
-
return /* @__PURE__ */
|
|
2471
|
+
return /* @__PURE__ */ jsx10("div", { className: "text-destructive text-sm", children: deps.states.error });
|
|
1329
2472
|
}
|
|
1330
|
-
return /* @__PURE__ */
|
|
2473
|
+
return /* @__PURE__ */ jsx10(FormProvider3, { ...form, children: /* @__PURE__ */ jsx10("form", { onSubmit, noValidate: true, className: "space-y-6", children: /* @__PURE__ */ jsx10(
|
|
1331
2474
|
Body,
|
|
1332
2475
|
{
|
|
1333
2476
|
formId,
|
|
@@ -1354,15 +2497,15 @@ function createBuilderListEditorPageComponent(deps) {
|
|
|
1354
2497
|
const entityQuery = deps.hooks.useEntity(listId);
|
|
1355
2498
|
const tables = deps.hooks.useTables();
|
|
1356
2499
|
const save = deps.hooks.useSave();
|
|
1357
|
-
const form =
|
|
2500
|
+
const form = useForm4({
|
|
1358
2501
|
resolver: deps.resolver,
|
|
1359
2502
|
defaultValues: deps.emptyValues
|
|
1360
2503
|
});
|
|
1361
2504
|
const columnArray = useFieldArray({ control: form.control, name: "columns" });
|
|
1362
2505
|
const triggerArray = useFieldArray({ control: form.control, name: "triggers" });
|
|
1363
|
-
const sourceType =
|
|
1364
|
-
const sourceTable =
|
|
1365
|
-
|
|
2506
|
+
const sourceType = useWatch2({ control: form.control, name: "sourceType" });
|
|
2507
|
+
const sourceTable = useWatch2({ control: form.control, name: "sourceTable" });
|
|
2508
|
+
useEffect4(() => {
|
|
1366
2509
|
if (listId && !entityQuery.data) return;
|
|
1367
2510
|
form.reset(builderListEditorValuesFromEntity(entityQuery.data ?? null, deps.emptyValues));
|
|
1368
2511
|
}, [entityQuery.data, form, listId]);
|
|
@@ -1381,12 +2524,12 @@ function createBuilderListEditorPageComponent(deps) {
|
|
|
1381
2524
|
}
|
|
1382
2525
|
});
|
|
1383
2526
|
if (listId && entityQuery.isPending) {
|
|
1384
|
-
return /* @__PURE__ */
|
|
2527
|
+
return /* @__PURE__ */ jsx10("div", { className: "text-muted-foreground text-sm", children: deps.states.loading });
|
|
1385
2528
|
}
|
|
1386
2529
|
if (listId && entityQuery.isError) {
|
|
1387
|
-
return /* @__PURE__ */
|
|
2530
|
+
return /* @__PURE__ */ jsx10("div", { className: "text-destructive text-sm", children: deps.states.error });
|
|
1388
2531
|
}
|
|
1389
|
-
return /* @__PURE__ */
|
|
2532
|
+
return /* @__PURE__ */ jsx10(FormProvider3, { ...form, children: /* @__PURE__ */ jsx10("form", { onSubmit, noValidate: true, className: "space-y-6", children: /* @__PURE__ */ jsx10(
|
|
1390
2533
|
Body,
|
|
1391
2534
|
{
|
|
1392
2535
|
listId,
|
|
@@ -1406,7 +2549,7 @@ function createBuilderListEditorPageComponent(deps) {
|
|
|
1406
2549
|
}
|
|
1407
2550
|
|
|
1408
2551
|
// src/admin/BuilderAdminPages.tsx
|
|
1409
|
-
import { jsx as
|
|
2552
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1410
2553
|
var defaultFieldTypeOptions = [
|
|
1411
2554
|
{ value: "text", label: "Text" },
|
|
1412
2555
|
{ value: "textarea", label: "Textarea" },
|
|
@@ -1534,6 +2677,7 @@ function createBuilderAdminPages({
|
|
|
1534
2677
|
const emptyFormValues = {
|
|
1535
2678
|
title: "",
|
|
1536
2679
|
description: "",
|
|
2680
|
+
presentation: "dialog",
|
|
1537
2681
|
sourceType: "none",
|
|
1538
2682
|
sourceTable: BUILDER_EDITOR_NONE_VALUE,
|
|
1539
2683
|
apiBasePath: "",
|
|
@@ -1663,14 +2807,14 @@ function createBuilderAdminPages({
|
|
|
1663
2807
|
href: viewsPath
|
|
1664
2808
|
}
|
|
1665
2809
|
];
|
|
1666
|
-
return /* @__PURE__ */
|
|
1667
|
-
/* @__PURE__ */
|
|
1668
|
-
/* @__PURE__ */
|
|
1669
|
-
/* @__PURE__ */
|
|
2810
|
+
return /* @__PURE__ */ jsxs10("section", { style: homeStyles.page, children: [
|
|
2811
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
2812
|
+
/* @__PURE__ */ jsx11("h1", { style: homeStyles.headerTitle, children: "Builder" }),
|
|
2813
|
+
/* @__PURE__ */ jsx11("p", { style: homeStyles.description, children: "Manage dynamic forms, lists, and views." })
|
|
1670
2814
|
] }),
|
|
1671
|
-
/* @__PURE__ */
|
|
1672
|
-
/* @__PURE__ */
|
|
1673
|
-
/* @__PURE__ */
|
|
2815
|
+
/* @__PURE__ */ jsx11("div", { style: homeStyles.grid, children: items.map((item) => /* @__PURE__ */ jsxs10("a", { href: item.href, style: homeStyles.card, children: [
|
|
2816
|
+
/* @__PURE__ */ jsx11("h2", { style: homeStyles.cardTitle, children: item.title }),
|
|
2817
|
+
/* @__PURE__ */ jsx11("p", { style: homeStyles.description, children: item.description })
|
|
1674
2818
|
] }, item.href)) })
|
|
1675
2819
|
] });
|
|
1676
2820
|
};
|
|
@@ -1759,24 +2903,24 @@ function createBuilderAdminPages({
|
|
|
1759
2903
|
AdminHomePage,
|
|
1760
2904
|
AdminFormsPage,
|
|
1761
2905
|
AdminNewFormPage: function BuilderAdminNewFormPage() {
|
|
1762
|
-
return /* @__PURE__ */
|
|
2906
|
+
return /* @__PURE__ */ jsx11(FormEditorPage, {});
|
|
1763
2907
|
},
|
|
1764
2908
|
AdminEditFormPage: function BuilderAdminEditFormPage({ formId }) {
|
|
1765
|
-
return /* @__PURE__ */
|
|
2909
|
+
return /* @__PURE__ */ jsx11(FormEditorPage, { formId });
|
|
1766
2910
|
},
|
|
1767
2911
|
AdminListsPage,
|
|
1768
2912
|
AdminNewListPage: function BuilderAdminNewListPage() {
|
|
1769
|
-
return /* @__PURE__ */
|
|
2913
|
+
return /* @__PURE__ */ jsx11(ListEditorPage, {});
|
|
1770
2914
|
},
|
|
1771
2915
|
AdminEditListPage: function BuilderAdminEditListPage({ listId }) {
|
|
1772
|
-
return /* @__PURE__ */
|
|
2916
|
+
return /* @__PURE__ */ jsx11(ListEditorPage, { listId });
|
|
1773
2917
|
},
|
|
1774
2918
|
AdminViewsPage,
|
|
1775
2919
|
AdminNewViewPage: function BuilderAdminNewViewPage() {
|
|
1776
|
-
return /* @__PURE__ */
|
|
2920
|
+
return /* @__PURE__ */ jsx11(ViewEditorPage, {});
|
|
1777
2921
|
},
|
|
1778
2922
|
AdminEditViewPage: function BuilderAdminEditViewPage({ viewId }) {
|
|
1779
|
-
return /* @__PURE__ */
|
|
2923
|
+
return /* @__PURE__ */ jsx11(ViewEditorPage, { viewId });
|
|
1780
2924
|
},
|
|
1781
2925
|
routes: {
|
|
1782
2926
|
adminBasePath,
|
|
@@ -1794,16 +2938,16 @@ function createBuilderAdminPages({
|
|
|
1794
2938
|
}
|
|
1795
2939
|
|
|
1796
2940
|
// src/admin/BuilderEntityManager.tsx
|
|
1797
|
-
import { useCallback, useMemo as
|
|
1798
|
-
import { jsx as
|
|
2941
|
+
import { useCallback as useCallback2, useMemo as useMemo6, useState as useState6 } from "react";
|
|
2942
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1799
2943
|
function createBuilderEntityManagerComponent(deps) {
|
|
1800
2944
|
return function BuilderEntityManager() {
|
|
1801
|
-
const [pendingDelete, setPendingDelete] =
|
|
2945
|
+
const [pendingDelete, setPendingDelete] = useState6(null);
|
|
1802
2946
|
const state = deps.useDataTableState({ pageSize: 20 });
|
|
1803
2947
|
const query = deps.hooks.useEntities(state.query);
|
|
1804
2948
|
const remove = deps.hooks.useDelete();
|
|
1805
2949
|
const replicate = deps.hooks.useReplicate();
|
|
1806
|
-
const columns =
|
|
2950
|
+
const columns = useMemo6(
|
|
1807
2951
|
() => deps.buildColumns({
|
|
1808
2952
|
onEdit: deps.navigateToEdit,
|
|
1809
2953
|
onReplicate: async (entity) => {
|
|
@@ -1823,8 +2967,8 @@ function createBuilderEntityManagerComponent(deps) {
|
|
|
1823
2967
|
state,
|
|
1824
2968
|
getRowId: (row) => row.id
|
|
1825
2969
|
});
|
|
1826
|
-
return /* @__PURE__ */
|
|
1827
|
-
/* @__PURE__ */
|
|
2970
|
+
return /* @__PURE__ */ jsxs11("div", { className: "space-y-6", children: [
|
|
2971
|
+
/* @__PURE__ */ jsx12(
|
|
1828
2972
|
deps.DataGrid,
|
|
1829
2973
|
{
|
|
1830
2974
|
title: deps.labels.title,
|
|
@@ -1835,10 +2979,10 @@ function createBuilderEntityManagerComponent(deps) {
|
|
|
1835
2979
|
emptyTitle: deps.labels.emptyTitle,
|
|
1836
2980
|
emptyDescription: deps.labels.emptyDescription,
|
|
1837
2981
|
onRowClick: deps.navigateToEdit,
|
|
1838
|
-
toolbarExtra: /* @__PURE__ */
|
|
2982
|
+
toolbarExtra: /* @__PURE__ */ jsx12(deps.AddButton, { href: deps.createHref, label: deps.labels.addLabel })
|
|
1839
2983
|
}
|
|
1840
2984
|
),
|
|
1841
|
-
/* @__PURE__ */
|
|
2985
|
+
/* @__PURE__ */ jsx12(
|
|
1842
2986
|
deps.DeleteDialog,
|
|
1843
2987
|
{
|
|
1844
2988
|
entity: pendingDelete,
|
|
@@ -1858,18 +3002,18 @@ function createBuilderEntityManagerComponent(deps) {
|
|
|
1858
3002
|
}
|
|
1859
3003
|
function createBuilderEntityDialogManagerComponent(deps) {
|
|
1860
3004
|
return function BuilderEntityDialogManager() {
|
|
1861
|
-
const [editing, setEditing] =
|
|
1862
|
-
const [isEditorOpen, setEditorOpen] =
|
|
1863
|
-
const [pendingDelete, setPendingDelete] =
|
|
3005
|
+
const [editing, setEditing] = useState6(null);
|
|
3006
|
+
const [isEditorOpen, setEditorOpen] = useState6(false);
|
|
3007
|
+
const [pendingDelete, setPendingDelete] = useState6(null);
|
|
1864
3008
|
const state = deps.useDataTableState({ pageSize: 20 });
|
|
1865
3009
|
const query = deps.hooks.useEntities(state.query);
|
|
1866
3010
|
const remove = deps.hooks.useDelete();
|
|
1867
3011
|
const replicate = deps.hooks.useReplicate();
|
|
1868
|
-
const openEditor =
|
|
3012
|
+
const openEditor = useCallback2((entity) => {
|
|
1869
3013
|
setEditing(entity);
|
|
1870
3014
|
setEditorOpen(true);
|
|
1871
3015
|
}, []);
|
|
1872
|
-
const columns =
|
|
3016
|
+
const columns = useMemo6(
|
|
1873
3017
|
() => deps.buildColumns({
|
|
1874
3018
|
onEdit: (entity) => openEditor(entity),
|
|
1875
3019
|
onReplicate: async (entity) => {
|
|
@@ -1889,8 +3033,8 @@ function createBuilderEntityDialogManagerComponent(deps) {
|
|
|
1889
3033
|
state,
|
|
1890
3034
|
getRowId: (row) => row.id
|
|
1891
3035
|
});
|
|
1892
|
-
return /* @__PURE__ */
|
|
1893
|
-
/* @__PURE__ */
|
|
3036
|
+
return /* @__PURE__ */ jsxs11("div", { className: "space-y-6", children: [
|
|
3037
|
+
/* @__PURE__ */ jsx12(
|
|
1894
3038
|
deps.DataGrid,
|
|
1895
3039
|
{
|
|
1896
3040
|
title: deps.labels.title,
|
|
@@ -1901,10 +3045,10 @@ function createBuilderEntityDialogManagerComponent(deps) {
|
|
|
1901
3045
|
emptyTitle: deps.labels.emptyTitle,
|
|
1902
3046
|
emptyDescription: deps.labels.emptyDescription,
|
|
1903
3047
|
onRowClick: openEditor,
|
|
1904
|
-
toolbarExtra: /* @__PURE__ */
|
|
3048
|
+
toolbarExtra: /* @__PURE__ */ jsx12(deps.AddButton, { label: deps.labels.addLabel, onAdd: () => openEditor(null) })
|
|
1905
3049
|
}
|
|
1906
3050
|
),
|
|
1907
|
-
/* @__PURE__ */
|
|
3051
|
+
/* @__PURE__ */ jsx12(
|
|
1908
3052
|
deps.EditorDialog,
|
|
1909
3053
|
{
|
|
1910
3054
|
open: isEditorOpen,
|
|
@@ -1912,7 +3056,7 @@ function createBuilderEntityDialogManagerComponent(deps) {
|
|
|
1912
3056
|
onClose: () => setEditorOpen(false)
|
|
1913
3057
|
}
|
|
1914
3058
|
),
|
|
1915
|
-
/* @__PURE__ */
|
|
3059
|
+
/* @__PURE__ */ jsx12(
|
|
1916
3060
|
deps.DeleteDialog,
|
|
1917
3061
|
{
|
|
1918
3062
|
entity: pendingDelete,
|
|
@@ -1932,9 +3076,9 @@ function createBuilderEntityDialogManagerComponent(deps) {
|
|
|
1932
3076
|
}
|
|
1933
3077
|
|
|
1934
3078
|
// src/admin/BuilderViewDialog.tsx
|
|
1935
|
-
import { useEffect as
|
|
1936
|
-
import { FormProvider as
|
|
1937
|
-
import { jsx as
|
|
3079
|
+
import { useEffect as useEffect5 } from "react";
|
|
3080
|
+
import { FormProvider as FormProvider4, useForm as useForm5 } from "react-hook-form";
|
|
3081
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1938
3082
|
function createBuilderViewDialogComponent(deps) {
|
|
1939
3083
|
return function BuilderViewDialog({
|
|
1940
3084
|
open,
|
|
@@ -1945,11 +3089,11 @@ function createBuilderViewDialogComponent(deps) {
|
|
|
1945
3089
|
onSave,
|
|
1946
3090
|
isSaving
|
|
1947
3091
|
}) {
|
|
1948
|
-
const form =
|
|
3092
|
+
const form = useForm5({
|
|
1949
3093
|
resolver: deps.resolver,
|
|
1950
3094
|
defaultValues: deps.emptyValues
|
|
1951
3095
|
});
|
|
1952
|
-
|
|
3096
|
+
useEffect5(() => {
|
|
1953
3097
|
if (!open) return;
|
|
1954
3098
|
form.reset(
|
|
1955
3099
|
builderViewEditorValuesFromEntity(editing, deps.emptyValues, deps.defaultPermission)
|
|
@@ -1964,7 +3108,7 @@ function createBuilderViewDialogComponent(deps) {
|
|
|
1964
3108
|
deps.notifications.error(error);
|
|
1965
3109
|
}
|
|
1966
3110
|
});
|
|
1967
|
-
return /* @__PURE__ */
|
|
3111
|
+
return /* @__PURE__ */ jsx13(deps.Shell, { open, editing, onClose, children: /* @__PURE__ */ jsx13(FormProvider4, { ...form, children: /* @__PURE__ */ jsx13("form", { onSubmit, noValidate: true, children: deps.Body({
|
|
1968
3112
|
form,
|
|
1969
3113
|
editing,
|
|
1970
3114
|
forms,
|
|
@@ -1978,8 +3122,8 @@ function createBuilderViewDialogComponent(deps) {
|
|
|
1978
3122
|
}
|
|
1979
3123
|
|
|
1980
3124
|
// src/admin/formLayoutEditorState.ts
|
|
1981
|
-
import { useMemo as
|
|
1982
|
-
import { useWatch as
|
|
3125
|
+
import { useMemo as useMemo7 } from "react";
|
|
3126
|
+
import { useWatch as useWatch3 } from "react-hook-form";
|
|
1983
3127
|
var builderFormLayoutDragDataType = "application/x-winu-builder-layout-field";
|
|
1984
3128
|
function clampBuilderFormLayoutSpan(span, columns) {
|
|
1985
3129
|
return Math.max(1, Math.min(columns, span));
|
|
@@ -2026,8 +3170,8 @@ function parseBuilderFormLayoutDragPayload(raw) {
|
|
|
2026
3170
|
}
|
|
2027
3171
|
}
|
|
2028
3172
|
function useBuilderFormLayoutEditor({ form, fields, subforms = [] }) {
|
|
2029
|
-
const layoutGroups =
|
|
2030
|
-
const layoutItems =
|
|
3173
|
+
const layoutGroups = useWatch3({ control: form.control, name: "layoutGroups" }) ?? [];
|
|
3174
|
+
const layoutItems = useMemo7(
|
|
2031
3175
|
() => [
|
|
2032
3176
|
...fields.map((field) => ({
|
|
2033
3177
|
key: field.key,
|
|
@@ -2044,11 +3188,11 @@ function useBuilderFormLayoutEditor({ form, fields, subforms = [] }) {
|
|
|
2044
3188
|
],
|
|
2045
3189
|
[fields, subforms]
|
|
2046
3190
|
);
|
|
2047
|
-
const assignedKeys =
|
|
3191
|
+
const assignedKeys = useMemo7(
|
|
2048
3192
|
() => new Set(layoutGroups.flatMap((group) => group.fields.map((field) => field.key))),
|
|
2049
3193
|
[layoutGroups]
|
|
2050
3194
|
);
|
|
2051
|
-
const unassignedItems =
|
|
3195
|
+
const unassignedItems = useMemo7(
|
|
2052
3196
|
() => layoutItems.filter((item) => !assignedKeys.has(item.key)),
|
|
2053
3197
|
[assignedKeys, layoutItems]
|
|
2054
3198
|
);
|
|
@@ -2133,149 +3277,32 @@ function useBuilderFormLayoutEditor({ form, fields, subforms = [] }) {
|
|
|
2133
3277
|
return {
|
|
2134
3278
|
assignedKeys,
|
|
2135
3279
|
layoutGroups,
|
|
2136
|
-
layoutItems,
|
|
2137
|
-
unassignedItems,
|
|
2138
|
-
addGroup,
|
|
2139
|
-
addItemToGroup,
|
|
2140
|
-
addItemToNewGroup,
|
|
2141
|
-
applyDragPayload,
|
|
2142
|
-
resetDefaultLayout,
|
|
2143
|
-
setGroups,
|
|
2144
|
-
updateGroup,
|
|
2145
|
-
updateGroupFields
|
|
2146
|
-
};
|
|
2147
|
-
}
|
|
2148
|
-
|
|
2149
|
-
// src/api/createBuilderApiClient.ts
|
|
2150
|
-
function queryParams(query) {
|
|
2151
|
-
return { ...query };
|
|
2152
|
-
}
|
|
2153
|
-
function fieldOptionsQueryParams(query) {
|
|
2154
|
-
const flatQuery = { search: query.search };
|
|
2155
|
-
for (const [key, value] of Object.entries(query.depends ?? {})) {
|
|
2156
|
-
flatQuery[`depends.${key}`] = value;
|
|
2157
|
-
}
|
|
2158
|
-
return flatQuery;
|
|
2159
|
-
}
|
|
2160
|
-
function createBuilderApiClient(transport) {
|
|
2161
|
-
return {
|
|
2162
|
-
listBuilderForms: (query) => transport.get("/builder/forms", {
|
|
2163
|
-
query: queryParams(query)
|
|
2164
|
-
}),
|
|
2165
|
-
listBuilderDbTables: () => transport.get("/builder/datasources/tables"),
|
|
2166
|
-
listBuilderFormOptions: () => transport.get("/builder/forms/options"),
|
|
2167
|
-
getBuilderForm: (id) => transport.get(`/builder/forms/${encodeURIComponent(id)}`),
|
|
2168
|
-
createBuilderForm: (input) => transport.post("/builder/forms", input),
|
|
2169
|
-
updateBuilderForm: (id, input) => transport.patch(`/builder/forms/${encodeURIComponent(id)}`, input),
|
|
2170
|
-
replicateBuilderForm: (id, input) => transport.post(`/builder/forms/${encodeURIComponent(id)}/replicate`, input),
|
|
2171
|
-
deleteBuilderForm: (id) => transport.delete(`/builder/forms/${encodeURIComponent(id)}`),
|
|
2172
|
-
listBuilderLists: (query) => transport.get("/builder/lists", {
|
|
2173
|
-
query: queryParams(query)
|
|
2174
|
-
}),
|
|
2175
|
-
listBuilderListOptions: () => transport.get("/builder/lists/options"),
|
|
2176
|
-
getBuilderList: (id) => transport.get(`/builder/lists/${encodeURIComponent(id)}`),
|
|
2177
|
-
createBuilderList: (input) => transport.post("/builder/lists", input),
|
|
2178
|
-
updateBuilderList: (id, input) => transport.patch(`/builder/lists/${encodeURIComponent(id)}`, input),
|
|
2179
|
-
replicateBuilderList: (id, input) => transport.post(`/builder/lists/${encodeURIComponent(id)}/replicate`, input),
|
|
2180
|
-
deleteBuilderList: (id) => transport.delete(`/builder/lists/${encodeURIComponent(id)}`),
|
|
2181
|
-
listBuilderViews: (query) => transport.get("/builder/views", {
|
|
2182
|
-
query: queryParams(query)
|
|
2183
|
-
}),
|
|
2184
|
-
getBuilderView: (id) => transport.get(`/builder/views/${encodeURIComponent(id)}`),
|
|
2185
|
-
createBuilderView: (input) => transport.post("/builder/views", input),
|
|
2186
|
-
updateBuilderView: (id, input) => transport.patch(`/builder/views/${encodeURIComponent(id)}`, input),
|
|
2187
|
-
replicateBuilderView: (id, input) => transport.post(`/builder/views/${encodeURIComponent(id)}/replicate`, input),
|
|
2188
|
-
deleteBuilderView: (id) => transport.delete(`/builder/views/${encodeURIComponent(id)}`),
|
|
2189
|
-
getRuntimeBuilderForm: (id) => transport.get(`/builder/runtime/forms/${encodeURIComponent(id)}`),
|
|
2190
|
-
createRuntimeBuilderFormEntry: (formId, input) => transport.post(
|
|
2191
|
-
`/builder/runtime/forms/${encodeURIComponent(formId)}/entries`,
|
|
2192
|
-
input
|
|
2193
|
-
),
|
|
2194
|
-
listRuntimeBuilderFormFieldOptions: (formId, fieldKey, query) => transport.get(
|
|
2195
|
-
`/builder/runtime/forms/${encodeURIComponent(formId)}/fields/${encodeURIComponent(fieldKey)}/options`,
|
|
2196
|
-
{ query: fieldOptionsQueryParams(query) }
|
|
2197
|
-
),
|
|
2198
|
-
runRuntimeBuilderFormFieldTrigger: (formId, fieldKey, event, input) => transport.post(
|
|
2199
|
-
`/builder/runtime/forms/${encodeURIComponent(formId)}/fields/${encodeURIComponent(fieldKey)}/triggers/${encodeURIComponent(event)}`,
|
|
2200
|
-
input
|
|
2201
|
-
),
|
|
2202
|
-
getRuntimeBuilderList: (id) => transport.get(`/builder/runtime/lists/${encodeURIComponent(id)}`),
|
|
2203
|
-
listRuntimeBuilderListEntries: (listId, query) => transport.get(
|
|
2204
|
-
`/builder/runtime/lists/${encodeURIComponent(listId)}/entries`,
|
|
2205
|
-
{ query: queryParams(query) }
|
|
2206
|
-
),
|
|
2207
|
-
getRuntimeBuilderView: (id) => transport.get(`/builder/runtime/views/${encodeURIComponent(id)}`),
|
|
2208
|
-
runRuntimeBuilderViewFieldTrigger: (viewId, fieldKey, event, input) => transport.post(
|
|
2209
|
-
`/builder/runtime/views/${encodeURIComponent(viewId)}/fields/${encodeURIComponent(fieldKey)}/triggers/${encodeURIComponent(event)}`,
|
|
2210
|
-
input
|
|
2211
|
-
),
|
|
2212
|
-
listBuilderViewEntries: (viewId, query) => transport.get(
|
|
2213
|
-
`/builder/runtime/views/${encodeURIComponent(viewId)}/entries`,
|
|
2214
|
-
{ query: queryParams(query) }
|
|
2215
|
-
),
|
|
2216
|
-
createBuilderViewEntry: (viewId, input) => transport.post(
|
|
2217
|
-
`/builder/runtime/views/${encodeURIComponent(viewId)}/entries`,
|
|
2218
|
-
input
|
|
2219
|
-
),
|
|
2220
|
-
createCompositeBuilderViewEntry: (viewId, input) => transport.post(
|
|
2221
|
-
`/builder/runtime/views/${encodeURIComponent(viewId)}/composite-entries`,
|
|
2222
|
-
input
|
|
2223
|
-
),
|
|
2224
|
-
updateCompositeBuilderViewEntry: (viewId, id, input) => transport.patch(
|
|
2225
|
-
`/builder/runtime/views/${encodeURIComponent(viewId)}/composite-entries/${encodeURIComponent(id)}`,
|
|
2226
|
-
input
|
|
2227
|
-
),
|
|
2228
|
-
updateBuilderViewEntry: (viewId, id, input) => transport.patch(
|
|
2229
|
-
`/builder/runtime/views/${encodeURIComponent(viewId)}/entries/${encodeURIComponent(id)}`,
|
|
2230
|
-
input
|
|
2231
|
-
),
|
|
2232
|
-
deleteBuilderViewEntry: (viewId, id) => transport.delete(
|
|
2233
|
-
`/builder/runtime/views/${encodeURIComponent(viewId)}/entries/${encodeURIComponent(id)}`
|
|
2234
|
-
)
|
|
3280
|
+
layoutItems,
|
|
3281
|
+
unassignedItems,
|
|
3282
|
+
addGroup,
|
|
3283
|
+
addItemToGroup,
|
|
3284
|
+
addItemToNewGroup,
|
|
3285
|
+
applyDragPayload,
|
|
3286
|
+
resetDefaultLayout,
|
|
3287
|
+
setGroups,
|
|
3288
|
+
updateGroup,
|
|
3289
|
+
updateGroupFields
|
|
2235
3290
|
};
|
|
2236
3291
|
}
|
|
2237
3292
|
|
|
2238
3293
|
// src/components/DynamicForm.tsx
|
|
2239
|
-
import { useMemo as
|
|
2240
|
-
import { FormProvider as
|
|
2241
|
-
|
|
2242
|
-
// src/runtime/runtimeUtils.ts
|
|
2243
|
-
function emptyFieldValue(field) {
|
|
2244
|
-
return field.type === "checkbox" ? false : "";
|
|
2245
|
-
}
|
|
2246
|
-
function createBuilderFormDefaultValues(schema) {
|
|
2247
|
-
const values = {};
|
|
2248
|
-
for (const field of schema?.fields ?? []) {
|
|
2249
|
-
values[field.key] = emptyFieldValue(field);
|
|
2250
|
-
}
|
|
2251
|
-
return { values };
|
|
2252
|
-
}
|
|
2253
|
-
function createBuilderEntryDefaultValues(view, editing) {
|
|
2254
|
-
const values = {};
|
|
2255
|
-
for (const field of view.form?.schema.fields ?? []) {
|
|
2256
|
-
const existing = editing?.values[field.key];
|
|
2257
|
-
values[field.key] = existing === void 0 ? emptyFieldValue(field) : existing;
|
|
2258
|
-
}
|
|
2259
|
-
return { values, version: editing?.version ?? 0 };
|
|
2260
|
-
}
|
|
2261
|
-
function formatBuilderRuntimeValue(value, locale = "mn-MN") {
|
|
2262
|
-
if (value === null || value === void 0 || value === "") return "\u2014";
|
|
2263
|
-
if (typeof value === "boolean") return value ? "\u0422\u0438\u0439\u043C" : "\u04AE\u0433\u04AF\u0439";
|
|
2264
|
-
if (typeof value === "number") return new Intl.NumberFormat(locale).format(value);
|
|
2265
|
-
return String(value);
|
|
2266
|
-
}
|
|
2267
|
-
|
|
2268
|
-
// src/components/DynamicForm.tsx
|
|
2269
|
-
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3294
|
+
import { useMemo as useMemo8 } from "react";
|
|
3295
|
+
import { FormProvider as FormProvider5, useForm as useForm6 } from "react-hook-form";
|
|
3296
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2270
3297
|
function createDynamicFormComponent(deps) {
|
|
2271
3298
|
return function DynamicForm({ formId }) {
|
|
2272
3299
|
const query = deps.hooks.useRuntimeBuilderForm(formId);
|
|
2273
3300
|
const save = deps.hooks.useSaveRuntimeBuilderFormEntry(formId);
|
|
2274
|
-
const formValues =
|
|
3301
|
+
const formValues = useMemo8(
|
|
2275
3302
|
() => query.data ? createBuilderFormDefaultValues(query.data.schema) : void 0,
|
|
2276
3303
|
[query.data]
|
|
2277
3304
|
);
|
|
2278
|
-
const form =
|
|
3305
|
+
const form = useForm6({
|
|
2279
3306
|
defaultValues: createBuilderFormDefaultValues(query.data?.schema),
|
|
2280
3307
|
values: formValues
|
|
2281
3308
|
});
|
|
@@ -2289,7 +3316,7 @@ function createDynamicFormComponent(deps) {
|
|
|
2289
3316
|
}
|
|
2290
3317
|
});
|
|
2291
3318
|
if (query.isError) {
|
|
2292
|
-
return /* @__PURE__ */
|
|
3319
|
+
return /* @__PURE__ */ jsx14(
|
|
2293
3320
|
deps.ErrorState,
|
|
2294
3321
|
{
|
|
2295
3322
|
title: "Form \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439",
|
|
@@ -2298,22 +3325,22 @@ function createDynamicFormComponent(deps) {
|
|
|
2298
3325
|
);
|
|
2299
3326
|
}
|
|
2300
3327
|
if (!query.data) return null;
|
|
2301
|
-
return /* @__PURE__ */
|
|
2302
|
-
/* @__PURE__ */
|
|
2303
|
-
/* @__PURE__ */
|
|
3328
|
+
return /* @__PURE__ */ jsx14(deps.FormShell, { title: query.data.title, children: /* @__PURE__ */ jsx14(FormProvider5, { ...form, children: /* @__PURE__ */ jsxs12("form", { onSubmit, noValidate: true, className: "space-y-6", children: [
|
|
3329
|
+
/* @__PURE__ */ jsx14(deps.FormFields, { formId, schema: query.data.schema, namePrefix: "values" }),
|
|
3330
|
+
/* @__PURE__ */ jsx14(deps.SubmitButton, { isSaving: save.isPending })
|
|
2304
3331
|
] }) }) });
|
|
2305
3332
|
};
|
|
2306
3333
|
}
|
|
2307
3334
|
|
|
2308
3335
|
// src/components/DynamicList.tsx
|
|
2309
|
-
import { useMemo as
|
|
2310
|
-
import { jsx as
|
|
3336
|
+
import { useMemo as useMemo9 } from "react";
|
|
3337
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
2311
3338
|
function createDynamicListComponent(deps) {
|
|
2312
3339
|
return function DynamicList({ listId }) {
|
|
2313
3340
|
const query = deps.hooks.useRuntimeBuilderList(listId);
|
|
2314
3341
|
const state = deps.useDataTableState({ pageSize: 20 });
|
|
2315
3342
|
const entriesQuery = deps.hooks.useRuntimeBuilderListEntries(listId, state.query);
|
|
2316
|
-
const columns =
|
|
3343
|
+
const columns = useMemo9(() => query.data ? deps.buildColumns(query.data) : [], [query.data]);
|
|
2317
3344
|
const entries = entriesQuery.data?.items ?? [];
|
|
2318
3345
|
const controller = deps.useDataTable({
|
|
2319
3346
|
columns,
|
|
@@ -2323,7 +3350,7 @@ function createDynamicListComponent(deps) {
|
|
|
2323
3350
|
getRowId: (row) => row.id
|
|
2324
3351
|
});
|
|
2325
3352
|
if (query.isError) {
|
|
2326
|
-
return /* @__PURE__ */
|
|
3353
|
+
return /* @__PURE__ */ jsx15(
|
|
2327
3354
|
deps.ErrorState,
|
|
2328
3355
|
{
|
|
2329
3356
|
title: "List \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439",
|
|
@@ -2331,560 +3358,269 @@ function createDynamicListComponent(deps) {
|
|
|
2331
3358
|
}
|
|
2332
3359
|
);
|
|
2333
3360
|
}
|
|
2334
|
-
return /* @__PURE__ */
|
|
3361
|
+
return /* @__PURE__ */ jsx15(
|
|
2335
3362
|
deps.DataGrid,
|
|
2336
3363
|
{
|
|
2337
3364
|
title: query.data?.title ?? "Dynamic List",
|
|
2338
|
-
description: query.data?.description ?? `/winu/list?id=${listId}`,
|
|
2339
|
-
controller,
|
|
2340
|
-
isLoading: query.isPending || entriesQuery.isPending,
|
|
2341
|
-
searchPlaceholder: "\u041C\u04E9\u0440 \u0445\u0430\u0439\u0445...",
|
|
2342
|
-
emptyTitle: "\u041C\u04E9\u0440 \u0430\u043B\u0433\u0430",
|
|
2343
|
-
emptyDescription: "\u042D\u043D\u044D list-\u0438\u0439\u043D datasource \u0434\u044D\u044D\u0440 \u043C\u04E9\u0440 \u0430\u043B\u0433\u0430."
|
|
2344
|
-
}
|
|
2345
|
-
);
|
|
2346
|
-
};
|
|
2347
|
-
}
|
|
2348
|
-
|
|
2349
|
-
// src/components/DynamicView.tsx
|
|
2350
|
-
import { useMemo as useMemo6, useState as useState3 } from "react";
|
|
2351
|
-
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2352
|
-
function createDynamicViewComponent(deps) {
|
|
2353
|
-
return function DynamicView({ viewId }) {
|
|
2354
|
-
const [editing, setEditing] = useState3(null);
|
|
2355
|
-
const [isDialogOpen, setDialogOpen] = useState3(false);
|
|
2356
|
-
const [pendingDelete, setPendingDelete] = useState3(null);
|
|
2357
|
-
const viewQuery = deps.hooks.useRuntimeBuilderView(viewId);
|
|
2358
|
-
const state = deps.useDataTableState({ pageSize: 20 });
|
|
2359
|
-
const entriesQuery = deps.hooks.useBuilderViewEntries(viewId, state.query);
|
|
2360
|
-
const save = deps.hooks.useSaveBuilderViewEntry(viewId);
|
|
2361
|
-
const remove = deps.hooks.useDeleteBuilderViewEntry(viewId);
|
|
2362
|
-
const view = viewQuery.data;
|
|
2363
|
-
const columns = useMemo6(
|
|
2364
|
-
() => view ? deps.buildColumns(view, {
|
|
2365
|
-
onEdit: (entry) => {
|
|
2366
|
-
setEditing(entry);
|
|
2367
|
-
setDialogOpen(true);
|
|
2368
|
-
},
|
|
2369
|
-
onDelete: setPendingDelete
|
|
2370
|
-
}) : [],
|
|
2371
|
-
[view]
|
|
2372
|
-
);
|
|
2373
|
-
const controller = deps.useDataTable({
|
|
2374
|
-
columns,
|
|
2375
|
-
data: entriesQuery.data?.items ?? [],
|
|
2376
|
-
rowCount: entriesQuery.data?.total ?? 0,
|
|
2377
|
-
state,
|
|
2378
|
-
getRowId: (row) => row.id
|
|
2379
|
-
});
|
|
2380
|
-
if (viewQuery.isError) {
|
|
2381
|
-
return /* @__PURE__ */ jsx10(
|
|
2382
|
-
deps.ErrorState,
|
|
2383
|
-
{
|
|
2384
|
-
title: "View \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439",
|
|
2385
|
-
description: `\xAB${viewId}\xBB id-\u0442\u0430\u0439 view \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439.`
|
|
2386
|
-
}
|
|
2387
|
-
);
|
|
2388
|
-
}
|
|
2389
|
-
return /* @__PURE__ */ jsxs7("div", { className: "space-y-6", children: [
|
|
2390
|
-
/* @__PURE__ */ jsx10(
|
|
2391
|
-
deps.DataGrid,
|
|
2392
|
-
{
|
|
2393
|
-
title: view?.title ?? "Dynamic View",
|
|
2394
|
-
description: view?.description ?? `/winu/view?id=${viewId}`,
|
|
2395
|
-
controller,
|
|
2396
|
-
isLoading: viewQuery.isPending || entriesQuery.isPending,
|
|
2397
|
-
searchPlaceholder: "\u041C\u04E9\u0440 \u0445\u0430\u0439\u0445...",
|
|
2398
|
-
emptyTitle: "\u041C\u04E9\u0440 \u0430\u043B\u0433\u0430",
|
|
2399
|
-
emptyDescription: "\u042D\u043D\u044D view \u0434\u044D\u044D\u0440 \u044D\u0445\u043D\u0438\u0439 \u043C\u04E9\u0440\u04E9\u04E9 \u043D\u044D\u043C\u044D\u044D\u0440\u044D\u0439.",
|
|
2400
|
-
onRowClick: (entry) => {
|
|
2401
|
-
setEditing(entry);
|
|
2402
|
-
setDialogOpen(true);
|
|
2403
|
-
},
|
|
2404
|
-
toolbarExtra: /* @__PURE__ */ jsx10(
|
|
2405
|
-
deps.AddButton,
|
|
2406
|
-
{
|
|
2407
|
-
disabled: !view?.form,
|
|
2408
|
-
onAdd: () => {
|
|
2409
|
-
setEditing(null);
|
|
2410
|
-
setDialogOpen(true);
|
|
2411
|
-
}
|
|
2412
|
-
}
|
|
2413
|
-
)
|
|
2414
|
-
}
|
|
2415
|
-
),
|
|
2416
|
-
view ? /* @__PURE__ */ jsx10(
|
|
2417
|
-
deps.EntryDialog,
|
|
2418
|
-
{
|
|
2419
|
-
open: isDialogOpen,
|
|
2420
|
-
view,
|
|
2421
|
-
editing,
|
|
2422
|
-
onClose: () => setDialogOpen(false),
|
|
2423
|
-
onSave: save.mutateAsync,
|
|
2424
|
-
isSaving: save.isPending
|
|
2425
|
-
}
|
|
2426
|
-
) : null,
|
|
2427
|
-
/* @__PURE__ */ jsx10(
|
|
2428
|
-
deps.DeleteDialog,
|
|
2429
|
-
{
|
|
2430
|
-
entry: pendingDelete,
|
|
2431
|
-
isDeleting: remove.isPending,
|
|
2432
|
-
onClose: () => setPendingDelete(null),
|
|
2433
|
-
onConfirm: async () => {
|
|
2434
|
-
if (!pendingDelete) return;
|
|
2435
|
-
await remove.mutateAsync(pendingDelete.id);
|
|
2436
|
-
setPendingDelete(null);
|
|
2437
|
-
}
|
|
2438
|
-
}
|
|
2439
|
-
)
|
|
2440
|
-
] });
|
|
2441
|
-
};
|
|
2442
|
-
}
|
|
2443
|
-
|
|
2444
|
-
// src/components/RuntimeEntryDialog.tsx
|
|
2445
|
-
import { useEffect as useEffect4, useMemo as useMemo7, useState as useState4 } from "react";
|
|
2446
|
-
import { FormProvider as FormProvider4, useForm as useForm5 } from "react-hook-form";
|
|
2447
|
-
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2448
|
-
function isDbTableSource(source) {
|
|
2449
|
-
return source?.type === "dbTable" && "tableName" in source;
|
|
2450
|
-
}
|
|
2451
|
-
function runtimeViewTableName(view) {
|
|
2452
|
-
const listSource = view.list?.source;
|
|
2453
|
-
if (isDbTableSource(listSource)) return listSource.tableName;
|
|
2454
|
-
const formSource = view.form?.source;
|
|
2455
|
-
return isDbTableSource(formSource) ? formSource.tableName : void 0;
|
|
2456
|
-
}
|
|
2457
|
-
function cleanRowValues(values) {
|
|
2458
|
-
return Object.fromEntries(
|
|
2459
|
-
Object.entries(values).filter(([key]) => key === "_delete" || !key.startsWith("_"))
|
|
2460
|
-
);
|
|
2461
|
-
}
|
|
2462
|
-
function childRowPayload(row, includeIdentity) {
|
|
2463
|
-
const values = cleanRowValues(row.values);
|
|
2464
|
-
if (!includeIdentity || row.values._draftNew === true) return values;
|
|
2465
|
-
return {
|
|
2466
|
-
id: row.id,
|
|
2467
|
-
version: row.version,
|
|
2468
|
-
...values
|
|
2469
|
-
};
|
|
2470
|
-
}
|
|
2471
|
-
function createRuntimeEntryDialogComponent(deps) {
|
|
2472
|
-
return function RuntimeEntryDialog({
|
|
2473
|
-
open,
|
|
2474
|
-
view,
|
|
2475
|
-
editing,
|
|
2476
|
-
onClose,
|
|
2477
|
-
onSave,
|
|
2478
|
-
isSaving
|
|
2479
|
-
}) {
|
|
2480
|
-
const [draftSubforms, setDraftSubforms] = useState4({});
|
|
2481
|
-
const compositeCreate = deps.useCreateCompositeEntry?.(view.id);
|
|
2482
|
-
const compositeUpdate = deps.useUpdateCompositeEntry?.(view.id);
|
|
2483
|
-
const form = useForm5({
|
|
2484
|
-
defaultValues: createBuilderEntryDefaultValues(view, editing),
|
|
2485
|
-
values: open ? createBuilderEntryDefaultValues(view, editing) : void 0
|
|
2486
|
-
});
|
|
2487
|
-
const mainTableName = runtimeViewTableName(view);
|
|
2488
|
-
const hasDraftRows = useMemo7(
|
|
2489
|
-
() => Object.values(draftSubforms).some((draft) => draft.rows.length > 0),
|
|
2490
|
-
[draftSubforms]
|
|
2491
|
-
);
|
|
2492
|
-
useEffect4(() => {
|
|
2493
|
-
if (open) setDraftSubforms({});
|
|
2494
|
-
}, [open]);
|
|
2495
|
-
const onSubmit = form.handleSubmit(async (values) => {
|
|
2496
|
-
try {
|
|
2497
|
-
if (!editing && hasDraftRows) {
|
|
2498
|
-
if (!mainTableName) throw new Error("Main form datasource table \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439");
|
|
2499
|
-
if (!compositeCreate) throw new Error("Composite create handler \u0442\u043E\u0445\u0438\u0440\u0443\u0443\u043B\u0430\u0433\u0434\u0430\u0430\u0433\u04AF\u0439 \u0431\u0430\u0439\u043D\u0430");
|
|
2500
|
-
await compositeCreate.mutateAsync({
|
|
2501
|
-
data: {
|
|
2502
|
-
[mainTableName]: values.values,
|
|
2503
|
-
...Object.fromEntries(
|
|
2504
|
-
Object.values(draftSubforms).map((draft) => [
|
|
2505
|
-
draft.dataKey,
|
|
2506
|
-
draft.rows.filter((row) => row.values._delete !== true).map((row) => childRowPayload(row, false))
|
|
2507
|
-
])
|
|
2508
|
-
)
|
|
2509
|
-
}
|
|
2510
|
-
});
|
|
2511
|
-
} else if (editing && hasDraftRows) {
|
|
2512
|
-
if (!mainTableName) throw new Error("Main form datasource table \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439");
|
|
2513
|
-
if (!compositeUpdate) throw new Error("Composite update handler \u0442\u043E\u0445\u0438\u0440\u0443\u0443\u043B\u0430\u0433\u0434\u0430\u0430\u0433\u04AF\u0439 \u0431\u0430\u0439\u043D\u0430");
|
|
2514
|
-
await compositeUpdate.mutateAsync({
|
|
2515
|
-
id: editing.id,
|
|
2516
|
-
input: {
|
|
2517
|
-
data: {
|
|
2518
|
-
[mainTableName]: {
|
|
2519
|
-
id: editing.id,
|
|
2520
|
-
version: values.version,
|
|
2521
|
-
...values.values
|
|
2522
|
-
},
|
|
2523
|
-
...Object.fromEntries(
|
|
2524
|
-
Object.values(draftSubforms).map((draft) => [
|
|
2525
|
-
draft.dataKey,
|
|
2526
|
-
draft.rows.map((row) => childRowPayload(row, true))
|
|
2527
|
-
])
|
|
2528
|
-
)
|
|
2529
|
-
}
|
|
2530
|
-
}
|
|
2531
|
-
});
|
|
2532
|
-
} else {
|
|
2533
|
-
await onSave({ id: editing?.id, input: values });
|
|
2534
|
-
}
|
|
2535
|
-
onClose();
|
|
2536
|
-
deps.notifications.success(editing ? "\u041C\u04E9\u0440 \u0445\u0430\u0434\u0433\u0430\u043B\u0430\u0433\u0434\u043B\u0430\u0430" : "\u041C\u04E9\u0440 \u043D\u044D\u043C\u044D\u0433\u0434\u043B\u044D\u044D");
|
|
2537
|
-
} catch (error) {
|
|
2538
|
-
deps.notifications.error(deps.notifications.errorMessage(error, "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445\u0430\u0434 \u0430\u043B\u0434\u0430\u0430 \u0433\u0430\u0440\u043B\u0430\u0430"));
|
|
2539
|
-
}
|
|
2540
|
-
});
|
|
2541
|
-
const saving = isSaving || Boolean(compositeCreate?.isPending || compositeUpdate?.isPending);
|
|
2542
|
-
const extraItems = deps.SubformField && view.form?.schema.subforms?.length ? view.form.schema.subforms.map((subform) => ({
|
|
2543
|
-
key: subform.key,
|
|
2544
|
-
render: () => deps.SubformField ? /* @__PURE__ */ jsx11(
|
|
2545
|
-
deps.SubformField,
|
|
2546
|
-
{
|
|
2547
|
-
subform,
|
|
2548
|
-
parentEntry: editing,
|
|
2549
|
-
draftRows: draftSubforms[subform.key]?.rows ?? [],
|
|
2550
|
-
onDraftRowsChange: ({ subformKey, dataKey, rows }) => {
|
|
2551
|
-
setDraftSubforms((current) => ({
|
|
2552
|
-
...current,
|
|
2553
|
-
[subformKey]: { dataKey, rows }
|
|
2554
|
-
}));
|
|
2555
|
-
}
|
|
2556
|
-
}
|
|
2557
|
-
) : null
|
|
2558
|
-
})) : void 0;
|
|
2559
|
-
return /* @__PURE__ */ jsx11(
|
|
2560
|
-
deps.DialogShell,
|
|
2561
|
-
{
|
|
2562
|
-
open,
|
|
2563
|
-
title: editing ? "\u041C\u04E9\u0440 \u0437\u0430\u0441\u0430\u0445" : "\u041C\u04E9\u0440 \u043D\u044D\u043C\u044D\u0445",
|
|
2564
|
-
description: view.title,
|
|
2565
|
-
onClose,
|
|
2566
|
-
children: /* @__PURE__ */ jsx11(FormProvider4, { ...form, children: /* @__PURE__ */ jsxs8("form", { onSubmit, noValidate: true, className: deps.formClassName, children: [
|
|
2567
|
-
view.form ? /* @__PURE__ */ jsx11(
|
|
2568
|
-
deps.FormFields,
|
|
2569
|
-
{
|
|
2570
|
-
formId: view.form.id,
|
|
2571
|
-
viewId: view.id,
|
|
2572
|
-
entry: editing,
|
|
2573
|
-
schema: view.form.schema,
|
|
2574
|
-
namePrefix: "values",
|
|
2575
|
-
extraItems
|
|
2576
|
-
}
|
|
2577
|
-
) : null,
|
|
2578
|
-
/* @__PURE__ */ jsx11(deps.Actions, { isSaving: saving, onClose })
|
|
2579
|
-
] }) })
|
|
3365
|
+
description: query.data?.description ?? `/winu/list?id=${listId}`,
|
|
3366
|
+
controller,
|
|
3367
|
+
isLoading: query.isPending || entriesQuery.isPending,
|
|
3368
|
+
searchPlaceholder: "\u041C\u04E9\u0440 \u0445\u0430\u0439\u0445...",
|
|
3369
|
+
emptyTitle: "\u041C\u04E9\u0440 \u0430\u043B\u0433\u0430",
|
|
3370
|
+
emptyDescription: "\u042D\u043D\u044D list-\u0438\u0439\u043D datasource \u0434\u044D\u044D\u0440 \u043C\u04E9\u0440 \u0430\u043B\u0433\u0430."
|
|
2580
3371
|
}
|
|
2581
3372
|
);
|
|
2582
3373
|
};
|
|
2583
3374
|
}
|
|
2584
3375
|
|
|
2585
|
-
// src/
|
|
2586
|
-
import {
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
formList: (query) => [...builderKeys.forms, "list", query],
|
|
2592
|
-
form: (id) => [...builderKeys.forms, "detail", id],
|
|
2593
|
-
formOptions: () => [...builderKeys.forms, "options"],
|
|
2594
|
-
lists: ["builder", "lists"],
|
|
2595
|
-
listList: (query) => [...builderKeys.lists, "list", query],
|
|
2596
|
-
list: (id) => [...builderKeys.lists, "detail", id],
|
|
2597
|
-
listOptions: () => [...builderKeys.lists, "options"],
|
|
2598
|
-
views: ["builder", "views"],
|
|
2599
|
-
viewList: (query) => [...builderKeys.views, "list", query],
|
|
2600
|
-
view: (id) => [...builderKeys.views, "detail", id],
|
|
2601
|
-
runtimeForm: (id) => ["builder", "runtime", "form", id],
|
|
2602
|
-
runtimeFieldOptions: (formId, fieldKey, query) => [...builderKeys.runtimeForm(formId), "fields", fieldKey, "options", query],
|
|
2603
|
-
runtimeFormEntries: (id) => [...builderKeys.runtimeForm(id), "entries"],
|
|
2604
|
-
runtimeList: (id) => ["builder", "runtime", "list", id],
|
|
2605
|
-
runtimeListEntries: (id, query) => [...builderKeys.runtimeList(id), "entries", query],
|
|
2606
|
-
runtimeView: (id) => ["builder", "runtime", "view", id],
|
|
2607
|
-
entries: (id, query) => [...builderKeys.runtimeView(id), "entries", query]
|
|
2608
|
-
};
|
|
2609
|
-
return builderKeys;
|
|
3376
|
+
// src/components/DynamicView.tsx
|
|
3377
|
+
import { useMemo as useMemo10, useState as useState7 } from "react";
|
|
3378
|
+
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3379
|
+
var interactiveRowTargetSelector = "button,a,input,select,textarea,[role='button'],[role='menuitem'],[data-builder-row-action]";
|
|
3380
|
+
function hasClosest(target) {
|
|
3381
|
+
return typeof target === "object" && target !== null && "closest" in target && typeof target.closest === "function";
|
|
2610
3382
|
}
|
|
2611
|
-
function
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
queryClient.invalidateQueries({ queryKey: builderKeys.forms });
|
|
2648
|
-
queryClient.invalidateQueries({ queryKey: builderKeys.form(form.id) });
|
|
2649
|
-
queryClient.invalidateQueries({ queryKey: builderKeys.runtimeForm(form.id) });
|
|
2650
|
-
}
|
|
2651
|
-
});
|
|
2652
|
-
}
|
|
2653
|
-
function useReplicateBuilderForm() {
|
|
2654
|
-
const queryClient = useQueryClient();
|
|
2655
|
-
return useMutation({
|
|
2656
|
-
mutationFn: ({ id, input }) => client.replicateBuilderForm(id, input),
|
|
2657
|
-
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.forms })
|
|
2658
|
-
});
|
|
2659
|
-
}
|
|
2660
|
-
function useDeleteBuilderForm() {
|
|
2661
|
-
const queryClient = useQueryClient();
|
|
2662
|
-
return useMutation({
|
|
2663
|
-
mutationFn: client.deleteBuilderForm,
|
|
2664
|
-
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.forms })
|
|
2665
|
-
});
|
|
2666
|
-
}
|
|
2667
|
-
function useBuilderLists(query) {
|
|
2668
|
-
return useQuery({
|
|
2669
|
-
queryKey: builderKeys.listList(query),
|
|
2670
|
-
queryFn: () => client.listBuilderLists(query),
|
|
2671
|
-
placeholderData: keepPreviousData
|
|
2672
|
-
});
|
|
2673
|
-
}
|
|
2674
|
-
function useBuilderListOptions() {
|
|
2675
|
-
return useQuery({
|
|
2676
|
-
queryKey: builderKeys.listOptions(),
|
|
2677
|
-
queryFn: client.listBuilderListOptions
|
|
2678
|
-
});
|
|
2679
|
-
}
|
|
2680
|
-
function useBuilderList(id) {
|
|
2681
|
-
return useQuery({
|
|
2682
|
-
queryKey: builderKeys.list(id ?? ""),
|
|
2683
|
-
queryFn: () => client.getBuilderList(id ?? ""),
|
|
2684
|
-
enabled: Boolean(id)
|
|
2685
|
-
});
|
|
2686
|
-
}
|
|
2687
|
-
function useSaveBuilderList() {
|
|
2688
|
-
const queryClient = useQueryClient();
|
|
2689
|
-
return useMutation({
|
|
2690
|
-
mutationFn: ({ id, input }) => id ? client.updateBuilderList(id, input) : client.createBuilderList(input),
|
|
2691
|
-
onSuccess: (list) => {
|
|
2692
|
-
queryClient.invalidateQueries({ queryKey: builderKeys.lists });
|
|
2693
|
-
queryClient.invalidateQueries({ queryKey: builderKeys.list(list.id) });
|
|
2694
|
-
queryClient.invalidateQueries({ queryKey: builderKeys.runtimeList(list.id) });
|
|
2695
|
-
}
|
|
2696
|
-
});
|
|
2697
|
-
}
|
|
2698
|
-
function useReplicateBuilderList() {
|
|
2699
|
-
const queryClient = useQueryClient();
|
|
2700
|
-
return useMutation({
|
|
2701
|
-
mutationFn: ({ id, input }) => client.replicateBuilderList(id, input),
|
|
2702
|
-
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.lists })
|
|
2703
|
-
});
|
|
2704
|
-
}
|
|
2705
|
-
function useDeleteBuilderList() {
|
|
2706
|
-
const queryClient = useQueryClient();
|
|
2707
|
-
return useMutation({
|
|
2708
|
-
mutationFn: client.deleteBuilderList,
|
|
2709
|
-
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.lists })
|
|
2710
|
-
});
|
|
2711
|
-
}
|
|
2712
|
-
function useBuilderViews(query) {
|
|
2713
|
-
return useQuery({
|
|
2714
|
-
queryKey: builderKeys.viewList(query),
|
|
2715
|
-
queryFn: () => client.listBuilderViews(query),
|
|
2716
|
-
placeholderData: keepPreviousData
|
|
2717
|
-
});
|
|
2718
|
-
}
|
|
2719
|
-
function useBuilderView(id) {
|
|
2720
|
-
return useQuery({
|
|
2721
|
-
queryKey: builderKeys.view(id ?? ""),
|
|
2722
|
-
queryFn: () => client.getBuilderView(id ?? ""),
|
|
2723
|
-
enabled: Boolean(id)
|
|
2724
|
-
});
|
|
2725
|
-
}
|
|
2726
|
-
function useSaveBuilderView() {
|
|
2727
|
-
const queryClient = useQueryClient();
|
|
2728
|
-
return useMutation({
|
|
2729
|
-
mutationFn: ({ id, input }) => id ? client.updateBuilderView(id, input) : client.createBuilderView(input),
|
|
2730
|
-
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.views })
|
|
2731
|
-
});
|
|
2732
|
-
}
|
|
2733
|
-
function useReplicateBuilderView() {
|
|
2734
|
-
const queryClient = useQueryClient();
|
|
2735
|
-
return useMutation({
|
|
2736
|
-
mutationFn: ({ id, input }) => client.replicateBuilderView(id, input),
|
|
2737
|
-
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.views })
|
|
2738
|
-
});
|
|
2739
|
-
}
|
|
2740
|
-
function useDeleteBuilderView() {
|
|
2741
|
-
const queryClient = useQueryClient();
|
|
2742
|
-
return useMutation({
|
|
2743
|
-
mutationFn: client.deleteBuilderView,
|
|
2744
|
-
onSuccess: () => queryClient.invalidateQueries({ queryKey: builderKeys.views })
|
|
2745
|
-
});
|
|
2746
|
-
}
|
|
2747
|
-
function useRuntimeBuilderForm(id) {
|
|
2748
|
-
return useQuery({
|
|
2749
|
-
queryKey: builderKeys.runtimeForm(id),
|
|
2750
|
-
queryFn: () => client.getRuntimeBuilderForm(id)
|
|
2751
|
-
});
|
|
2752
|
-
}
|
|
2753
|
-
function useRuntimeBuilderFormFieldOptions(formId, fieldKey, query, enabled = true) {
|
|
2754
|
-
return useQuery({
|
|
2755
|
-
queryKey: builderKeys.runtimeFieldOptions(formId ?? "", fieldKey, query),
|
|
2756
|
-
queryFn: () => client.listRuntimeBuilderFormFieldOptions(formId ?? "", fieldKey, query),
|
|
2757
|
-
enabled: Boolean(formId) && enabled
|
|
3383
|
+
function shouldHandleDynamicViewRowClick(event) {
|
|
3384
|
+
if (!event) return true;
|
|
3385
|
+
if (event.defaultPrevented) return false;
|
|
3386
|
+
return !hasClosest(event.target) || !event.target.closest(interactiveRowTargetSelector);
|
|
3387
|
+
}
|
|
3388
|
+
function createDynamicViewComponent(deps) {
|
|
3389
|
+
return function DynamicView({ viewId }) {
|
|
3390
|
+
const [editing, setEditing] = useState7(null);
|
|
3391
|
+
const [isDialogOpen, setDialogOpen] = useState7(false);
|
|
3392
|
+
const [pendingDelete, setPendingDelete] = useState7(null);
|
|
3393
|
+
const viewQuery = deps.hooks.useRuntimeBuilderView(viewId);
|
|
3394
|
+
const state = deps.useDataTableState({ pageSize: 20 });
|
|
3395
|
+
const entriesQuery = deps.hooks.useBuilderViewEntries(viewId, state.query);
|
|
3396
|
+
const save = deps.hooks.useSaveBuilderViewEntry(viewId);
|
|
3397
|
+
const remove = deps.hooks.useDeleteBuilderViewEntry(viewId);
|
|
3398
|
+
const view = viewQuery.data;
|
|
3399
|
+
const columns = useMemo10(
|
|
3400
|
+
() => view ? deps.buildColumns(view, {
|
|
3401
|
+
onEdit: (entry, event) => {
|
|
3402
|
+
event?.stopPropagation?.();
|
|
3403
|
+
setEditing(entry);
|
|
3404
|
+
setDialogOpen(true);
|
|
3405
|
+
},
|
|
3406
|
+
onDelete: (entry, event) => {
|
|
3407
|
+
event?.stopPropagation?.();
|
|
3408
|
+
setPendingDelete(entry);
|
|
3409
|
+
}
|
|
3410
|
+
}) : [],
|
|
3411
|
+
[view]
|
|
3412
|
+
);
|
|
3413
|
+
const controller = deps.useDataTable({
|
|
3414
|
+
columns,
|
|
3415
|
+
data: entriesQuery.data?.items ?? [],
|
|
3416
|
+
rowCount: entriesQuery.data?.total ?? 0,
|
|
3417
|
+
state,
|
|
3418
|
+
getRowId: (row) => row.id
|
|
2758
3419
|
});
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
3420
|
+
if (viewQuery.isError) {
|
|
3421
|
+
return /* @__PURE__ */ jsx16(
|
|
3422
|
+
deps.ErrorState,
|
|
3423
|
+
{
|
|
3424
|
+
title: "View \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D\u0433\u04AF\u0439",
|
|
3425
|
+
description: `\xAB${viewId}\xBB id-\u0442\u0430\u0439 view \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439.`
|
|
3426
|
+
}
|
|
3427
|
+
);
|
|
3428
|
+
}
|
|
3429
|
+
return /* @__PURE__ */ jsxs13("div", { className: "space-y-6", children: [
|
|
3430
|
+
/* @__PURE__ */ jsx16(
|
|
3431
|
+
deps.DataGrid,
|
|
3432
|
+
{
|
|
3433
|
+
title: view?.title ?? "Dynamic View",
|
|
3434
|
+
description: view?.description ?? `/winu/view?id=${viewId}`,
|
|
3435
|
+
controller,
|
|
3436
|
+
isLoading: viewQuery.isPending || entriesQuery.isPending,
|
|
3437
|
+
searchPlaceholder: "\u041C\u04E9\u0440 \u0445\u0430\u0439\u0445...",
|
|
3438
|
+
emptyTitle: "\u041C\u04E9\u0440 \u0430\u043B\u0433\u0430",
|
|
3439
|
+
emptyDescription: "\u042D\u043D\u044D view \u0434\u044D\u044D\u0440 \u044D\u0445\u043D\u0438\u0439 \u043C\u04E9\u0440\u04E9\u04E9 \u043D\u044D\u043C\u044D\u044D\u0440\u044D\u0439.",
|
|
3440
|
+
onRowClick: (entry, event) => {
|
|
3441
|
+
if (!shouldHandleDynamicViewRowClick(event)) return;
|
|
3442
|
+
setEditing(entry);
|
|
3443
|
+
setDialogOpen(true);
|
|
3444
|
+
},
|
|
3445
|
+
toolbarExtra: /* @__PURE__ */ jsx16(
|
|
3446
|
+
deps.AddButton,
|
|
3447
|
+
{
|
|
3448
|
+
disabled: !view?.form,
|
|
3449
|
+
onAdd: () => {
|
|
3450
|
+
setEditing(null);
|
|
3451
|
+
setDialogOpen(true);
|
|
3452
|
+
}
|
|
3453
|
+
}
|
|
3454
|
+
)
|
|
3455
|
+
}
|
|
3456
|
+
),
|
|
3457
|
+
view ? /* @__PURE__ */ jsx16(
|
|
3458
|
+
deps.EntryDialog,
|
|
3459
|
+
{
|
|
3460
|
+
open: isDialogOpen,
|
|
3461
|
+
view,
|
|
3462
|
+
editing,
|
|
3463
|
+
onClose: () => setDialogOpen(false),
|
|
3464
|
+
onSave: save.mutateAsync,
|
|
3465
|
+
isSaving: save.isPending
|
|
3466
|
+
}
|
|
3467
|
+
) : null,
|
|
3468
|
+
/* @__PURE__ */ jsx16(
|
|
3469
|
+
deps.DeleteDialog,
|
|
3470
|
+
{
|
|
3471
|
+
entry: pendingDelete,
|
|
3472
|
+
isDeleting: remove.isPending,
|
|
3473
|
+
onClose: () => setPendingDelete(null),
|
|
3474
|
+
onConfirm: async () => {
|
|
3475
|
+
if (!pendingDelete) return;
|
|
3476
|
+
await remove.mutateAsync(pendingDelete.id);
|
|
3477
|
+
setPendingDelete(null);
|
|
3478
|
+
}
|
|
2770
3479
|
}
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
3480
|
+
)
|
|
3481
|
+
] });
|
|
3482
|
+
};
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3485
|
+
// src/components/RuntimeEntryDialog.tsx
|
|
3486
|
+
import { useEffect as useEffect6, useMemo as useMemo11, useState as useState8 } from "react";
|
|
3487
|
+
import { FormProvider as FormProvider6, useForm as useForm7 } from "react-hook-form";
|
|
3488
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3489
|
+
function isDbTableSource(source) {
|
|
3490
|
+
return source?.type === "dbTable" && "tableName" in source;
|
|
3491
|
+
}
|
|
3492
|
+
function runtimeViewTableName(view) {
|
|
3493
|
+
const listSource = view.list?.source;
|
|
3494
|
+
if (isDbTableSource(listSource)) return listSource.tableName;
|
|
3495
|
+
const formSource = view.form?.source;
|
|
3496
|
+
return isDbTableSource(formSource) ? formSource.tableName : void 0;
|
|
3497
|
+
}
|
|
3498
|
+
function cleanRowValues(values) {
|
|
3499
|
+
return Object.fromEntries(
|
|
3500
|
+
Object.entries(values).filter(([key]) => key === "_delete" || !key.startsWith("_"))
|
|
3501
|
+
);
|
|
3502
|
+
}
|
|
3503
|
+
function childRowPayload(row, includeIdentity) {
|
|
3504
|
+
const values = cleanRowValues(row.values);
|
|
3505
|
+
if (!includeIdentity || row.values._draftNew === true) return values;
|
|
3506
|
+
return {
|
|
3507
|
+
id: row.id,
|
|
3508
|
+
version: row.version,
|
|
3509
|
+
...values
|
|
3510
|
+
};
|
|
3511
|
+
}
|
|
3512
|
+
function createRuntimeEntryDialogComponent(deps) {
|
|
3513
|
+
return function RuntimeEntryDialog({
|
|
3514
|
+
open,
|
|
3515
|
+
view,
|
|
3516
|
+
editing,
|
|
3517
|
+
onClose,
|
|
3518
|
+
onSave,
|
|
3519
|
+
isSaving
|
|
3520
|
+
}) {
|
|
3521
|
+
const [draftSubforms, setDraftSubforms] = useState8({});
|
|
3522
|
+
const compositeCreate = deps.useCreateCompositeEntry?.(view.id);
|
|
3523
|
+
const compositeUpdate = deps.useUpdateCompositeEntry?.(view.id);
|
|
3524
|
+
const form = useForm7({
|
|
3525
|
+
defaultValues: createBuilderEntryDefaultValues(view, editing),
|
|
3526
|
+
values: open ? createBuilderEntryDefaultValues(view, editing) : void 0
|
|
3527
|
+
});
|
|
3528
|
+
const mainTableName = runtimeViewTableName(view);
|
|
3529
|
+
const hasDraftRows = useMemo11(
|
|
3530
|
+
() => Object.values(draftSubforms).some((draft) => draft.rows.length > 0),
|
|
3531
|
+
[draftSubforms]
|
|
3532
|
+
);
|
|
3533
|
+
useEffect6(() => {
|
|
3534
|
+
if (open) setDraftSubforms({});
|
|
3535
|
+
}, [open]);
|
|
3536
|
+
const onSubmit = form.handleSubmit(async (values) => {
|
|
3537
|
+
try {
|
|
3538
|
+
if (!editing && hasDraftRows) {
|
|
3539
|
+
if (!mainTableName) throw new Error("Main form datasource table \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439");
|
|
3540
|
+
if (!compositeCreate) throw new Error("Composite create handler \u0442\u043E\u0445\u0438\u0440\u0443\u0443\u043B\u0430\u0433\u0434\u0430\u0430\u0433\u04AF\u0439 \u0431\u0430\u0439\u043D\u0430");
|
|
3541
|
+
await compositeCreate.mutateAsync({
|
|
3542
|
+
data: {
|
|
3543
|
+
[mainTableName]: values.values,
|
|
3544
|
+
...Object.fromEntries(
|
|
3545
|
+
Object.values(draftSubforms).map((draft) => [
|
|
3546
|
+
draft.dataKey,
|
|
3547
|
+
draft.rows.filter((row) => row.values._delete !== true).map((row) => childRowPayload(row, false))
|
|
3548
|
+
])
|
|
3549
|
+
)
|
|
3550
|
+
}
|
|
3551
|
+
});
|
|
3552
|
+
} else if (editing && hasDraftRows) {
|
|
3553
|
+
if (!mainTableName) throw new Error("Main form datasource table \u043E\u043B\u0434\u0441\u043E\u043D\u0433\u04AF\u0439");
|
|
3554
|
+
if (!compositeUpdate) throw new Error("Composite update handler \u0442\u043E\u0445\u0438\u0440\u0443\u0443\u043B\u0430\u0433\u0434\u0430\u0430\u0433\u04AF\u0439 \u0431\u0430\u0439\u043D\u0430");
|
|
3555
|
+
await compositeUpdate.mutateAsync({
|
|
3556
|
+
id: editing.id,
|
|
3557
|
+
input: {
|
|
3558
|
+
data: {
|
|
3559
|
+
[mainTableName]: {
|
|
3560
|
+
id: editing.id,
|
|
3561
|
+
version: values.version,
|
|
3562
|
+
...values.values
|
|
3563
|
+
},
|
|
3564
|
+
...Object.fromEntries(
|
|
3565
|
+
Object.values(draftSubforms).map((draft) => [
|
|
3566
|
+
draft.dataKey,
|
|
3567
|
+
draft.rows.map((row) => childRowPayload(row, true))
|
|
3568
|
+
])
|
|
3569
|
+
)
|
|
3570
|
+
}
|
|
3571
|
+
}
|
|
3572
|
+
});
|
|
3573
|
+
} else {
|
|
3574
|
+
await onSave({ id: editing?.id, input: values });
|
|
2778
3575
|
}
|
|
2779
|
-
|
|
3576
|
+
onClose();
|
|
3577
|
+
deps.notifications.success(editing ? "\u041C\u04E9\u0440 \u0445\u0430\u0434\u0433\u0430\u043B\u0430\u0433\u0434\u043B\u0430\u0430" : "\u041C\u04E9\u0440 \u043D\u044D\u043C\u044D\u0433\u0434\u043B\u044D\u044D");
|
|
3578
|
+
} catch (error) {
|
|
3579
|
+
deps.notifications.error(deps.notifications.errorMessage(error, "\u0425\u0430\u0434\u0433\u0430\u043B\u0430\u0445\u0430\u0434 \u0430\u043B\u0434\u0430\u0430 \u0433\u0430\u0440\u043B\u0430\u0430"));
|
|
2780
3580
|
}
|
|
2781
3581
|
});
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
3582
|
+
const saving = isSaving || Boolean(compositeCreate?.isPending || compositeUpdate?.isPending);
|
|
3583
|
+
const extraItems = deps.SubformField && view.form?.schema.subforms?.length ? view.form.schema.subforms.map((subform) => ({
|
|
3584
|
+
key: subform.key,
|
|
3585
|
+
render: () => deps.SubformField ? /* @__PURE__ */ jsx17(
|
|
3586
|
+
deps.SubformField,
|
|
3587
|
+
{
|
|
3588
|
+
subform,
|
|
3589
|
+
parentEntry: editing,
|
|
3590
|
+
draftRows: draftSubforms[subform.key]?.rows ?? [],
|
|
3591
|
+
onDraftRowsChange: ({ subformKey, dataKey: dataKey2, rows }) => {
|
|
3592
|
+
setDraftSubforms((current) => ({
|
|
3593
|
+
...current,
|
|
3594
|
+
[subformKey]: { dataKey: dataKey2, rows }
|
|
3595
|
+
}));
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
) : null
|
|
3599
|
+
})) : void 0;
|
|
3600
|
+
return /* @__PURE__ */ jsx17(
|
|
3601
|
+
deps.DialogShell,
|
|
3602
|
+
{
|
|
3603
|
+
open,
|
|
3604
|
+
presentation: view.form?.schema.presentation ?? "dialog",
|
|
3605
|
+
title: editing ? "\u041C\u04E9\u0440 \u0437\u0430\u0441\u0430\u0445" : "\u041C\u04E9\u0440 \u043D\u044D\u043C\u044D\u0445",
|
|
3606
|
+
description: view.title,
|
|
3607
|
+
onClose,
|
|
3608
|
+
children: /* @__PURE__ */ jsx17(FormProvider6, { ...form, children: /* @__PURE__ */ jsxs14("form", { onSubmit, noValidate: true, className: deps.formClassName, children: [
|
|
3609
|
+
view.form ? /* @__PURE__ */ jsx17(
|
|
3610
|
+
deps.FormFields,
|
|
3611
|
+
{
|
|
3612
|
+
formId: view.form.id,
|
|
3613
|
+
viewId: view.id,
|
|
3614
|
+
entry: editing,
|
|
3615
|
+
schema: view.form.schema,
|
|
3616
|
+
namePrefix: "values",
|
|
3617
|
+
extraItems
|
|
3618
|
+
}
|
|
3619
|
+
) : null,
|
|
3620
|
+
/* @__PURE__ */ jsx17(deps.Actions, { isSaving: saving, onClose })
|
|
3621
|
+
] }) })
|
|
2804
3622
|
}
|
|
2805
|
-
|
|
2806
|
-
}
|
|
2807
|
-
function useRuntimeBuilderView(id, enabled = true) {
|
|
2808
|
-
return useQuery({
|
|
2809
|
-
queryKey: builderKeys.runtimeView(id),
|
|
2810
|
-
queryFn: () => client.getRuntimeBuilderView(id),
|
|
2811
|
-
enabled: Boolean(id) && enabled
|
|
2812
|
-
});
|
|
2813
|
-
}
|
|
2814
|
-
function useBuilderViewEntries(id, query, enabled = true) {
|
|
2815
|
-
return useQuery({
|
|
2816
|
-
queryKey: builderKeys.entries(id, query),
|
|
2817
|
-
queryFn: () => client.listBuilderViewEntries(id, query),
|
|
2818
|
-
placeholderData: keepPreviousData,
|
|
2819
|
-
enabled: Boolean(id) && enabled
|
|
2820
|
-
});
|
|
2821
|
-
}
|
|
2822
|
-
function useSaveBuilderViewEntry(viewId) {
|
|
2823
|
-
const queryClient = useQueryClient();
|
|
2824
|
-
return useMutation({
|
|
2825
|
-
mutationFn: ({ id, input }) => id ? client.updateBuilderViewEntry(viewId, id, input) : client.createBuilderViewEntry(
|
|
2826
|
-
viewId,
|
|
2827
|
-
input
|
|
2828
|
-
),
|
|
2829
|
-
onSuccess: () => invalidateRuntimeViewEntries(queryClient, viewId)
|
|
2830
|
-
});
|
|
2831
|
-
}
|
|
2832
|
-
function useCreateCompositeBuilderViewEntry(viewId) {
|
|
2833
|
-
const queryClient = useQueryClient();
|
|
2834
|
-
return useMutation({
|
|
2835
|
-
mutationFn: (input) => client.createCompositeBuilderViewEntry(viewId, input),
|
|
2836
|
-
onSuccess: () => invalidateRuntimeViewEntries(queryClient, viewId)
|
|
2837
|
-
});
|
|
2838
|
-
}
|
|
2839
|
-
function useUpdateCompositeBuilderViewEntry(viewId) {
|
|
2840
|
-
const queryClient = useQueryClient();
|
|
2841
|
-
return useMutation({
|
|
2842
|
-
mutationFn: ({
|
|
2843
|
-
id,
|
|
2844
|
-
input
|
|
2845
|
-
}) => client.updateCompositeBuilderViewEntry(viewId, id, input),
|
|
2846
|
-
onSuccess: () => invalidateRuntimeViewEntries(queryClient, viewId)
|
|
2847
|
-
});
|
|
2848
|
-
}
|
|
2849
|
-
function useDeleteBuilderViewEntry(id) {
|
|
2850
|
-
const queryClient = useQueryClient();
|
|
2851
|
-
return useMutation({
|
|
2852
|
-
mutationFn: (entryId) => client.deleteBuilderViewEntry(id, entryId),
|
|
2853
|
-
onSuccess: () => invalidateRuntimeViewEntries(queryClient, id)
|
|
2854
|
-
});
|
|
2855
|
-
}
|
|
2856
|
-
return {
|
|
2857
|
-
builderKeys,
|
|
2858
|
-
useBuilderDbTables,
|
|
2859
|
-
useBuilderForm,
|
|
2860
|
-
useBuilderFormOptions,
|
|
2861
|
-
useBuilderForms,
|
|
2862
|
-
useBuilderList,
|
|
2863
|
-
useBuilderListOptions,
|
|
2864
|
-
useBuilderLists,
|
|
2865
|
-
useBuilderViewEntries,
|
|
2866
|
-
useBuilderView,
|
|
2867
|
-
useBuilderViews,
|
|
2868
|
-
useDeleteBuilderForm,
|
|
2869
|
-
useDeleteBuilderList,
|
|
2870
|
-
useDeleteBuilderView,
|
|
2871
|
-
useDeleteBuilderViewEntry,
|
|
2872
|
-
useCreateCompositeBuilderViewEntry,
|
|
2873
|
-
useReplicateBuilderForm,
|
|
2874
|
-
useReplicateBuilderList,
|
|
2875
|
-
useReplicateBuilderView,
|
|
2876
|
-
useRuntimeBuilderForm,
|
|
2877
|
-
useRuntimeBuilderFormFieldOptions,
|
|
2878
|
-
useRuntimeBuilderList,
|
|
2879
|
-
useRuntimeBuilderListEntries,
|
|
2880
|
-
useRuntimeBuilderView,
|
|
2881
|
-
useRunRuntimeBuilderFieldTrigger,
|
|
2882
|
-
useSaveBuilderForm,
|
|
2883
|
-
useSaveBuilderList,
|
|
2884
|
-
useSaveBuilderView,
|
|
2885
|
-
useSaveBuilderViewEntry,
|
|
2886
|
-
useSaveRuntimeBuilderFormEntry,
|
|
2887
|
-
useUpdateCompositeBuilderViewEntry
|
|
3623
|
+
);
|
|
2888
3624
|
};
|
|
2889
3625
|
}
|
|
2890
3626
|
|
|
@@ -2905,7 +3641,7 @@ function withQuery(path, query) {
|
|
|
2905
3641
|
function createBuilderIntegration(config) {
|
|
2906
3642
|
const adminBasePath = normalizeBasePath(config.adminBasePath ?? "/admin/dev/builder");
|
|
2907
3643
|
const runtimeBasePath = normalizeBasePath(config.runtimeBasePath ?? "/admin/winu");
|
|
2908
|
-
const api = createBuilderApiClient(config.transport);
|
|
3644
|
+
const api = createBuilderApiClient(config.transport, { apiBasePath: config.apiBasePath });
|
|
2909
3645
|
const hooks = createBuilderHooks(api);
|
|
2910
3646
|
const formsPath = `${adminBasePath}/forms`;
|
|
2911
3647
|
const listsPath = `${adminBasePath}/lists`;
|
|
@@ -2936,18 +3672,51 @@ function createBuilderIntegration(config) {
|
|
|
2936
3672
|
adminPages
|
|
2937
3673
|
};
|
|
2938
3674
|
}
|
|
3675
|
+
function createBuilderPortalIntegration(config) {
|
|
3676
|
+
return createBuilderIntegration(config);
|
|
3677
|
+
}
|
|
3678
|
+
function validateBuilderFrontendSetup(config) {
|
|
3679
|
+
const checks = [
|
|
3680
|
+
{
|
|
3681
|
+
name: "adminBasePath",
|
|
3682
|
+
ok: Boolean(config.adminBasePath && normalizeBasePath(config.adminBasePath).startsWith("/")),
|
|
3683
|
+
message: "adminBasePath must be an absolute route path."
|
|
3684
|
+
},
|
|
3685
|
+
{
|
|
3686
|
+
name: "runtimeBasePath",
|
|
3687
|
+
ok: Boolean(config.runtimeBasePath && normalizeBasePath(config.runtimeBasePath).startsWith("/")),
|
|
3688
|
+
message: "runtimeBasePath must be an absolute route path."
|
|
3689
|
+
},
|
|
3690
|
+
{
|
|
3691
|
+
name: "transport",
|
|
3692
|
+
ok: Boolean(config.transport),
|
|
3693
|
+
message: "API transport is required."
|
|
3694
|
+
},
|
|
3695
|
+
{
|
|
3696
|
+
name: "apiBasePath",
|
|
3697
|
+
ok: config.apiBasePath === void 0 || normalizeBasePath(config.apiBasePath).startsWith("/"),
|
|
3698
|
+
message: "apiBasePath must be an absolute API path."
|
|
3699
|
+
}
|
|
3700
|
+
].map((check) => check.ok ? { name: check.name, ok: true } : check);
|
|
3701
|
+
return { ok: checks.every((check) => check.ok), checks };
|
|
3702
|
+
}
|
|
2939
3703
|
|
|
2940
3704
|
// src/index.ts
|
|
2941
3705
|
var builderUiPackage = {
|
|
2942
3706
|
name: "@duke333/builder-ui",
|
|
2943
|
-
version: "0.
|
|
3707
|
+
version: "0.2.0"
|
|
2944
3708
|
};
|
|
2945
3709
|
export {
|
|
2946
3710
|
BUILDER_EDITOR_NONE_VALUE,
|
|
3711
|
+
BuilderForm,
|
|
3712
|
+
BuilderGrid,
|
|
3713
|
+
BuilderProvider,
|
|
3714
|
+
BuilderView,
|
|
2947
3715
|
builderEditorOptionsToText,
|
|
2948
3716
|
builderEditorSearchFieldsToText,
|
|
2949
3717
|
builderEditorTextToOptions,
|
|
2950
3718
|
builderEditorTextToSearchFields,
|
|
3719
|
+
builderErrorMessage,
|
|
2951
3720
|
builderFormEditorFieldsFromTable,
|
|
2952
3721
|
builderFormEditorInputFromValues,
|
|
2953
3722
|
builderFormEditorValuesFromEntity,
|
|
@@ -2961,6 +3730,7 @@ export {
|
|
|
2961
3730
|
clampBuilderFormLayoutSpan,
|
|
2962
3731
|
createBuilderAdminPages,
|
|
2963
3732
|
createBuilderApiClient,
|
|
3733
|
+
createBuilderClient,
|
|
2964
3734
|
createBuilderDefaultEntityManagerComponent,
|
|
2965
3735
|
createBuilderDefaultFormEditorBody,
|
|
2966
3736
|
createBuilderDefaultListEditorBody,
|
|
@@ -2974,6 +3744,7 @@ export {
|
|
|
2974
3744
|
createBuilderIntegration,
|
|
2975
3745
|
createBuilderKeys,
|
|
2976
3746
|
createBuilderListEditorPageComponent,
|
|
3747
|
+
createBuilderPortalIntegration,
|
|
2977
3748
|
createBuilderViewDialogComponent,
|
|
2978
3749
|
createDynamicFormComponent,
|
|
2979
3750
|
createDynamicListComponent,
|
|
@@ -2984,7 +3755,10 @@ export {
|
|
|
2984
3755
|
nextBuilderFormLayoutGroupId,
|
|
2985
3756
|
parseBuilderFormLayoutDragPayload,
|
|
2986
3757
|
serializeBuilderFormLayoutDragPayload,
|
|
3758
|
+
shouldHandleDynamicViewRowClick,
|
|
2987
3759
|
swapBuilderFormLayoutItems,
|
|
2988
|
-
useBuilderFormLayoutEditor
|
|
3760
|
+
useBuilderFormLayoutEditor,
|
|
3761
|
+
useBuilderRuntime,
|
|
3762
|
+
validateBuilderFrontendSetup
|
|
2989
3763
|
};
|
|
2990
3764
|
//# sourceMappingURL=index.js.map
|