@dxos/react-ui-form 0.7.4 → 0.7.5-feature-compute.4d9d99a
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/dist/lib/browser/index.mjs +292 -221
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +380 -308
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +292 -221
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +2 -2
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +10 -4
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +5 -0
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Input.d.ts +3 -3
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/{Custom.d.ts → custom/GeoPointInput.d.ts} +3 -3
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -0
- package/dist/types/src/components/Form/custom/TupleInput.d.ts +7 -0
- package/dist/types/src/components/Form/custom/TupleInput.d.ts.map +1 -0
- package/dist/types/src/components/Form/custom/index.d.ts +3 -0
- package/dist/types/src/components/Form/custom/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/factory.d.ts.map +1 -1
- package/dist/types/src/components/Form/index.d.ts +2 -2
- package/dist/types/src/components/Form/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +6 -5
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/hooks/useForm.d.ts +10 -11
- package/dist/types/src/hooks/useForm.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +26 -26
- package/src/components/FieldEditor/FieldEditor.stories.tsx +2 -2
- package/src/components/FieldEditor/FieldEditor.tsx +75 -50
- package/src/components/Form/Defaults.tsx +2 -0
- package/src/components/Form/Form.stories.tsx +33 -1
- package/src/components/Form/Form.tsx +33 -5
- package/src/components/Form/Input.tsx +3 -3
- package/src/components/Form/{Custom.tsx → custom/GeoPointInput.tsx} +4 -16
- package/src/components/Form/custom/TupleInput.tsx +53 -0
- package/src/components/Form/custom/index.ts +6 -0
- package/src/components/Form/factory.tsx +2 -2
- package/src/components/Form/index.ts +3 -2
- package/src/components/ViewEditor/ViewEditor.stories.tsx +30 -8
- package/src/components/ViewEditor/ViewEditor.tsx +13 -8
- package/src/hooks/useForm.ts +35 -54
- package/dist/types/src/components/Form/Custom.d.ts.map +0 -1
|
@@ -80,27 +80,16 @@ var DeprecatedFormInput = ({ label, description, secondary, children }) => {
|
|
|
80
80
|
};
|
|
81
81
|
|
|
82
82
|
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
83
|
-
import
|
|
83
|
+
import React7, { useCallback as useCallback2, useEffect as useEffect3, useMemo as useMemo3, useState as useState2 } from "react";
|
|
84
84
|
import { FormatEnum as FormatEnum2, FormatEnums, formatToType } from "@dxos/echo-schema";
|
|
85
85
|
import { log as log3 } from "@dxos/log";
|
|
86
86
|
import { useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
87
87
|
import { getFormatSchema, getSchemaProperties as getSchemaProperties2, sortProperties } from "@dxos/schema";
|
|
88
88
|
|
|
89
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
90
|
-
import { pipe } from "effect";
|
|
91
|
-
import { capitalize } from "effect/String";
|
|
92
|
-
import React5, { useEffect as useEffect2, useMemo as useMemo2 } from "react";
|
|
93
|
-
import { AST, S } from "@dxos/echo-schema";
|
|
94
|
-
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
95
|
-
import { log as log2 } from "@dxos/log";
|
|
96
|
-
import { IconButton, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
97
|
-
import { mx } from "@dxos/react-ui-theme";
|
|
98
|
-
import { getSchemaProperties } from "@dxos/schema";
|
|
99
|
-
import { isNotFalsy } from "@dxos/util";
|
|
100
|
-
|
|
101
|
-
// packages/ui/react-ui-form/src/components/Form/Defaults.tsx
|
|
89
|
+
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
102
90
|
import React3 from "react";
|
|
103
|
-
import { Input as Input2,
|
|
91
|
+
import { Input as Input2, useTranslation } from "@dxos/react-ui";
|
|
92
|
+
import { safeParseFloat } from "@dxos/util";
|
|
104
93
|
|
|
105
94
|
// packages/ui/react-ui-form/src/components/Form/Input.tsx
|
|
106
95
|
import React2 from "react";
|
|
@@ -121,120 +110,156 @@ var InputHeader = ({ children, error }) => {
|
|
|
121
110
|
}, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null), error)));
|
|
122
111
|
};
|
|
123
112
|
|
|
124
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
125
|
-
var
|
|
113
|
+
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
114
|
+
var GeoPointInput = ({ property, type, label, disabled, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
|
|
115
|
+
const { t } = useTranslation(translationKey);
|
|
126
116
|
const { status, error } = getStatus?.(property);
|
|
117
|
+
const [lng = 0, lat = 0] = getValue2(property) ?? [];
|
|
127
118
|
return /* @__PURE__ */ React3.createElement(Input2.Root, {
|
|
128
119
|
validationValence: status
|
|
129
|
-
},
|
|
120
|
+
}, /* @__PURE__ */ React3.createElement(InputHeader, {
|
|
130
121
|
error
|
|
131
|
-
}, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement(
|
|
122
|
+
}, /* @__PURE__ */ React3.createElement(Input2.Label, null, label)), /* @__PURE__ */ React3.createElement("div", {
|
|
123
|
+
className: "grid grid-cols-2 gap-2"
|
|
124
|
+
}, /* @__PURE__ */ React3.createElement(Input2.TextInput, {
|
|
125
|
+
type: "number",
|
|
126
|
+
disabled,
|
|
127
|
+
placeholder: t("placeholder longitude"),
|
|
128
|
+
value: lng,
|
|
129
|
+
onChange: (event) => onValueChange(property, type, [
|
|
130
|
+
lat,
|
|
131
|
+
safeParseFloat(event.target.value, 0)
|
|
132
|
+
]),
|
|
133
|
+
onBlur
|
|
134
|
+
}), /* @__PURE__ */ React3.createElement(Input2.TextInput, {
|
|
135
|
+
type: "number",
|
|
136
|
+
disabled,
|
|
137
|
+
placeholder: t("placeholder latitude"),
|
|
138
|
+
value: lat,
|
|
139
|
+
onChange: (event) => onValueChange(property, type, [
|
|
140
|
+
safeParseFloat(event.target.value, 0),
|
|
141
|
+
lng
|
|
142
|
+
]),
|
|
143
|
+
onBlur
|
|
144
|
+
})));
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// packages/ui/react-ui-form/src/components/Form/custom/TupleInput.tsx
|
|
148
|
+
import React4 from "react";
|
|
149
|
+
import { Input as Input3 } from "@dxos/react-ui";
|
|
150
|
+
import { mx } from "@dxos/react-ui-theme";
|
|
151
|
+
import { safeParseFloat as safeParseFloat2 } from "@dxos/util";
|
|
152
|
+
var gridCols = [
|
|
153
|
+
"grid-cols-1",
|
|
154
|
+
"grid-cols-2",
|
|
155
|
+
"grid-cols-3",
|
|
156
|
+
"grid-cols-4"
|
|
157
|
+
];
|
|
158
|
+
var TupleInput = ({ binding, property, type, label, disabled, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
|
|
159
|
+
const { status, error } = getStatus?.(property);
|
|
160
|
+
const values = getValue2(property) ?? {};
|
|
161
|
+
return /* @__PURE__ */ React4.createElement(Input3.Root, {
|
|
162
|
+
validationValence: status
|
|
163
|
+
}, /* @__PURE__ */ React4.createElement(InputHeader, {
|
|
164
|
+
error
|
|
165
|
+
}, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement("div", {
|
|
166
|
+
className: mx("grid gap-2", gridCols[binding.length - 1])
|
|
167
|
+
}, binding.map((prop) => /* @__PURE__ */ React4.createElement(Input3.TextInput, {
|
|
168
|
+
key: prop,
|
|
169
|
+
type: "number",
|
|
170
|
+
disabled,
|
|
171
|
+
value: values[prop],
|
|
172
|
+
onChange: (event) => onValueChange(property, type, {
|
|
173
|
+
...values,
|
|
174
|
+
[prop]: safeParseFloat2(event.target.value, 0)
|
|
175
|
+
}),
|
|
176
|
+
onBlur
|
|
177
|
+
}))));
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// packages/ui/react-ui-form/src/components/Form/Defaults.tsx
|
|
181
|
+
import React5 from "react";
|
|
182
|
+
import { Input as Input4, Select } from "@dxos/react-ui";
|
|
183
|
+
var TextInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
|
|
184
|
+
const { status, error } = getStatus?.(property);
|
|
185
|
+
return /* @__PURE__ */ React5.createElement(Input4.Root, {
|
|
186
|
+
validationValence: status
|
|
187
|
+
}, !inputOnly && /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
188
|
+
error
|
|
189
|
+
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement(Input4.TextInput, {
|
|
132
190
|
disabled,
|
|
133
191
|
placeholder,
|
|
134
|
-
value:
|
|
192
|
+
value: getValue2(property) ?? "",
|
|
135
193
|
onChange: (event) => onValueChange(property, type, event.target.value),
|
|
136
194
|
onBlur
|
|
137
|
-
}), inputOnly && /* @__PURE__ */
|
|
195
|
+
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.Validation, null, error));
|
|
138
196
|
};
|
|
139
|
-
var NumberInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue, onValueChange, onBlur }) => {
|
|
197
|
+
var NumberInput = ({ property, type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue2, onValueChange, onBlur }) => {
|
|
140
198
|
const { status, error } = getStatus?.(property);
|
|
141
|
-
return /* @__PURE__ */
|
|
199
|
+
return /* @__PURE__ */ React5.createElement(Input4.Root, {
|
|
142
200
|
validationValence: status
|
|
143
|
-
}, !inputOnly && /* @__PURE__ */
|
|
201
|
+
}, !inputOnly && /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
144
202
|
error
|
|
145
|
-
}, /* @__PURE__ */
|
|
203
|
+
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement(Input4.TextInput, {
|
|
146
204
|
type: "number",
|
|
147
205
|
disabled,
|
|
148
206
|
placeholder,
|
|
149
|
-
value:
|
|
207
|
+
value: getValue2(property) ?? 0,
|
|
150
208
|
onChange: (event) => onValueChange(property, type, event.target.value),
|
|
151
209
|
onBlur
|
|
152
|
-
}), inputOnly && /* @__PURE__ */
|
|
210
|
+
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.DescriptionAndValidation, null, error));
|
|
153
211
|
};
|
|
154
|
-
var BooleanInput = ({ property, type, label, inputOnly, getStatus, getValue, onValueChange }) => {
|
|
212
|
+
var BooleanInput = ({ property, type, label, inputOnly, getStatus, getValue: getValue2, onValueChange }) => {
|
|
155
213
|
const { status, error } = getStatus?.(property);
|
|
156
|
-
return /* @__PURE__ */
|
|
214
|
+
return /* @__PURE__ */ React5.createElement(Input4.Root, {
|
|
157
215
|
validationValence: status
|
|
158
|
-
}, !inputOnly && /* @__PURE__ */
|
|
216
|
+
}, !inputOnly && /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
159
217
|
error
|
|
160
|
-
}, /* @__PURE__ */
|
|
161
|
-
checked:
|
|
218
|
+
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement(Input4.Switch, {
|
|
219
|
+
checked: getValue2(property),
|
|
162
220
|
onCheckedChange: (value) => onValueChange(property, type, value)
|
|
163
|
-
}), inputOnly && /* @__PURE__ */
|
|
221
|
+
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.DescriptionAndValidation, null, error));
|
|
164
222
|
};
|
|
165
|
-
var SelectInput = ({ property, type, label, inputOnly, disabled, placeholder, options, getStatus, getValue, onValueChange }) => {
|
|
223
|
+
var SelectInput = ({ property, type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue2, onValueChange }) => {
|
|
166
224
|
const { status, error } = getStatus?.(property);
|
|
167
|
-
return /* @__PURE__ */
|
|
225
|
+
return /* @__PURE__ */ React5.createElement(Input4.Root, {
|
|
168
226
|
validationValence: status
|
|
169
|
-
}, !inputOnly && /* @__PURE__ */
|
|
227
|
+
}, !inputOnly && /* @__PURE__ */ React5.createElement(InputHeader, {
|
|
170
228
|
error
|
|
171
|
-
}, /* @__PURE__ */
|
|
172
|
-
value:
|
|
229
|
+
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement(Select.Root, {
|
|
230
|
+
value: getValue2(property),
|
|
173
231
|
onValueChange: (value) => onValueChange(property, type, value)
|
|
174
|
-
}, /* @__PURE__ */
|
|
232
|
+
}, /* @__PURE__ */ React5.createElement(Select.TriggerButton, {
|
|
175
233
|
classNames: "is-full",
|
|
176
234
|
disabled,
|
|
177
235
|
placeholder
|
|
178
|
-
}), /* @__PURE__ */
|
|
236
|
+
}), /* @__PURE__ */ React5.createElement(Select.Portal, null, /* @__PURE__ */ React5.createElement(Select.Content, null, /* @__PURE__ */ React5.createElement(Select.Viewport, null, options?.map(({ value, label: label2 }) => (
|
|
179
237
|
// NOTE: Numeric values are converted to and from strings.
|
|
180
|
-
/* @__PURE__ */
|
|
238
|
+
/* @__PURE__ */ React5.createElement(Select.Option, {
|
|
181
239
|
key: String(value),
|
|
182
240
|
value: String(value)
|
|
183
241
|
}, label2 ?? String(value))
|
|
184
|
-
)))))), inputOnly && /* @__PURE__ */
|
|
242
|
+
)))))), inputOnly && /* @__PURE__ */ React5.createElement(Input4.DescriptionAndValidation, null, error));
|
|
185
243
|
};
|
|
186
244
|
|
|
187
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
188
|
-
import {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
import
|
|
192
|
-
import {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
validationValence: status
|
|
199
|
-
}, /* @__PURE__ */ React4.createElement(InputHeader, {
|
|
200
|
-
error
|
|
201
|
-
}, /* @__PURE__ */ React4.createElement(Input3.Label, null, label)), /* @__PURE__ */ React4.createElement("div", {
|
|
202
|
-
className: "grid grid-cols-2 gap-2"
|
|
203
|
-
}, /* @__PURE__ */ React4.createElement(Input3.TextInput, {
|
|
204
|
-
type: "number",
|
|
205
|
-
disabled,
|
|
206
|
-
placeholder: t("placeholder longitude"),
|
|
207
|
-
value: lng,
|
|
208
|
-
onChange: (event) => onValueChange(property, type, [
|
|
209
|
-
lat,
|
|
210
|
-
safeParseFloat(event.target.value, 0)
|
|
211
|
-
]),
|
|
212
|
-
onBlur
|
|
213
|
-
}), /* @__PURE__ */ React4.createElement(Input3.TextInput, {
|
|
214
|
-
type: "number",
|
|
215
|
-
disabled,
|
|
216
|
-
placeholder: t("placeholder latitude"),
|
|
217
|
-
value: lat,
|
|
218
|
-
onChange: (event) => onValueChange(property, type, [
|
|
219
|
-
safeParseFloat(event.target.value, 0),
|
|
220
|
-
lng
|
|
221
|
-
]),
|
|
222
|
-
onBlur
|
|
223
|
-
})));
|
|
224
|
-
};
|
|
225
|
-
var safeParseFloat = (str, defaultValue) => {
|
|
226
|
-
try {
|
|
227
|
-
return parseFloat(str);
|
|
228
|
-
} catch {
|
|
229
|
-
return defaultValue ?? 0;
|
|
230
|
-
}
|
|
231
|
-
};
|
|
245
|
+
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
246
|
+
import { pipe } from "effect";
|
|
247
|
+
import { capitalize } from "effect/String";
|
|
248
|
+
import React6, { useEffect as useEffect2, useMemo as useMemo2 } from "react";
|
|
249
|
+
import { AST as AST2, S } from "@dxos/echo-schema";
|
|
250
|
+
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
251
|
+
import { log as log2 } from "@dxos/log";
|
|
252
|
+
import { IconButton, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
253
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
254
|
+
import { getSchemaProperties } from "@dxos/schema";
|
|
255
|
+
import { isNotFalsy } from "@dxos/util";
|
|
232
256
|
|
|
233
257
|
// packages/ui/react-ui-form/src/components/Form/factory.tsx
|
|
258
|
+
import { FormatEnum } from "@dxos/echo-schema";
|
|
234
259
|
var getInputComponent = (type, format) => {
|
|
235
260
|
switch (format) {
|
|
236
261
|
case FormatEnum.LatLng:
|
|
237
|
-
return
|
|
262
|
+
return GeoPointInput;
|
|
238
263
|
}
|
|
239
264
|
switch (type) {
|
|
240
265
|
case "string":
|
|
@@ -248,11 +273,22 @@ var getInputComponent = (type, format) => {
|
|
|
248
273
|
|
|
249
274
|
// packages/ui/react-ui-form/src/hooks/useForm.ts
|
|
250
275
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
276
|
+
import { getValue, setValue } from "@dxos/echo-schema";
|
|
277
|
+
import { AST } from "@dxos/effect";
|
|
251
278
|
import { invariant } from "@dxos/invariant";
|
|
252
279
|
import { log } from "@dxos/log";
|
|
253
280
|
import { validateSchema } from "@dxos/schema";
|
|
254
281
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
|
|
255
282
|
var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
|
|
283
|
+
invariant(AST.isTypeLiteral(schema.ast), void 0, {
|
|
284
|
+
F: __dxlog_file,
|
|
285
|
+
L: 91,
|
|
286
|
+
S: void 0,
|
|
287
|
+
A: [
|
|
288
|
+
"AST.isTypeLiteral(schema.ast)",
|
|
289
|
+
""
|
|
290
|
+
]
|
|
291
|
+
});
|
|
256
292
|
const [values, setValues] = useState(initialValues);
|
|
257
293
|
useEffect(() => {
|
|
258
294
|
setValues(initialValues);
|
|
@@ -266,10 +302,12 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
266
302
|
const validate = useCallback((values2) => {
|
|
267
303
|
let errors2 = validateSchema(schema, values2) ?? [];
|
|
268
304
|
if (errors2.length === 0 && onValidate) {
|
|
269
|
-
|
|
305
|
+
const validatedValues = values2;
|
|
306
|
+
errors2 = onValidate(validatedValues) ?? [];
|
|
270
307
|
}
|
|
271
308
|
setErrors(flatMap(errors2));
|
|
272
|
-
|
|
309
|
+
const valid = errors2.length === 0;
|
|
310
|
+
return valid;
|
|
273
311
|
}, [
|
|
274
312
|
schema,
|
|
275
313
|
onValidate
|
|
@@ -307,7 +345,8 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
307
345
|
}, [
|
|
308
346
|
values,
|
|
309
347
|
validate,
|
|
310
|
-
onSave
|
|
348
|
+
onSave,
|
|
349
|
+
changed
|
|
311
350
|
]);
|
|
312
351
|
const getStatus = useCallback((property) => ({
|
|
313
352
|
status: errors[property] ? "error" : void 0,
|
|
@@ -316,8 +355,8 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
316
355
|
touched,
|
|
317
356
|
errors
|
|
318
357
|
]);
|
|
319
|
-
const
|
|
320
|
-
return
|
|
358
|
+
const getFormValue = (property) => {
|
|
359
|
+
return getValue(values, property);
|
|
321
360
|
};
|
|
322
361
|
const onValueChange = (property, type, value) => {
|
|
323
362
|
let parsedValue = value;
|
|
@@ -328,13 +367,15 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
328
367
|
} catch (err) {
|
|
329
368
|
log.catch(err, void 0, {
|
|
330
369
|
F: __dxlog_file,
|
|
331
|
-
L:
|
|
370
|
+
L: 179,
|
|
332
371
|
S: void 0,
|
|
333
372
|
C: (f, a) => f(...a)
|
|
334
373
|
});
|
|
335
374
|
parsedValue = void 0;
|
|
336
375
|
}
|
|
337
|
-
const newValues =
|
|
376
|
+
const newValues = {
|
|
377
|
+
...setValue(values, property, parsedValue)
|
|
378
|
+
};
|
|
338
379
|
setValues(newValues);
|
|
339
380
|
setChanged((prev) => ({
|
|
340
381
|
...prev,
|
|
@@ -372,7 +413,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
372
413
|
handleSave,
|
|
373
414
|
// Field utils.
|
|
374
415
|
getStatus,
|
|
375
|
-
getValue,
|
|
416
|
+
getValue: getFormValue,
|
|
376
417
|
onValueChange,
|
|
377
418
|
onBlur
|
|
378
419
|
};
|
|
@@ -380,7 +421,7 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
380
421
|
var createKeySet = (obj, value) => {
|
|
381
422
|
invariant(obj, void 0, {
|
|
382
423
|
F: __dxlog_file,
|
|
383
|
-
L:
|
|
424
|
+
L: 230,
|
|
384
425
|
S: void 0,
|
|
385
426
|
A: [
|
|
386
427
|
"obj",
|
|
@@ -400,25 +441,11 @@ var flatMap = (errors) => {
|
|
|
400
441
|
return result;
|
|
401
442
|
}, {});
|
|
402
443
|
};
|
|
403
|
-
var getByPath = (obj, path) => {
|
|
404
|
-
const [key, index] = path.split(".");
|
|
405
|
-
return index === void 0 ? obj[key] : obj[key][parseInt(index)];
|
|
406
|
-
};
|
|
407
|
-
var setByPath = (obj, path, value) => {
|
|
408
|
-
const [key, index] = path.split(".");
|
|
409
|
-
const newValue = index === void 0 ? value : [
|
|
410
|
-
...obj[key]
|
|
411
|
-
].map((v, i) => i === parseInt(index) ? value : v);
|
|
412
|
-
return {
|
|
413
|
-
...obj,
|
|
414
|
-
[key]: newValue
|
|
415
|
-
};
|
|
416
|
-
};
|
|
417
444
|
|
|
418
445
|
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
419
446
|
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/Form.tsx";
|
|
420
447
|
var padding = "px-2";
|
|
421
|
-
var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, Custom }) => {
|
|
448
|
+
var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
|
|
422
449
|
const onValid = useMemo2(() => autoSave ? onSave : void 0, [
|
|
423
450
|
autoSave,
|
|
424
451
|
onSave
|
|
@@ -450,7 +477,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
450
477
|
errors
|
|
451
478
|
}, {
|
|
452
479
|
F: __dxlog_file2,
|
|
453
|
-
L:
|
|
480
|
+
L: 106,
|
|
454
481
|
S: void 0,
|
|
455
482
|
C: (f, a) => f(...a)
|
|
456
483
|
});
|
|
@@ -458,9 +485,9 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
458
485
|
}, [
|
|
459
486
|
errors
|
|
460
487
|
]);
|
|
461
|
-
return /* @__PURE__ */
|
|
488
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
462
489
|
role: "form",
|
|
463
|
-
className:
|
|
490
|
+
className: mx2("flex flex-col w-full gap-2 py-2", classNames),
|
|
464
491
|
"data-testid": testId
|
|
465
492
|
}, properties.map((property) => {
|
|
466
493
|
const { ast, name, type, format, title, description, examples, options, array } = property;
|
|
@@ -470,14 +497,34 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
470
497
|
];
|
|
471
498
|
const label = title ?? pipe(name, capitalize);
|
|
472
499
|
const placeholder = examples?.length ? `Example: "${examples[0]}"` : description;
|
|
500
|
+
const FoundComponent = lookupComponent?.({
|
|
501
|
+
prop: name,
|
|
502
|
+
schema: S.make(ast),
|
|
503
|
+
inputProps: {
|
|
504
|
+
property: name,
|
|
505
|
+
type,
|
|
506
|
+
format,
|
|
507
|
+
label,
|
|
508
|
+
disabled: readonly,
|
|
509
|
+
placeholder,
|
|
510
|
+
...inputProps
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
if (FoundComponent) {
|
|
514
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
515
|
+
key: name,
|
|
516
|
+
role: "none",
|
|
517
|
+
className: padding
|
|
518
|
+
}, FoundComponent);
|
|
519
|
+
}
|
|
473
520
|
let InputComponent = Custom?.[key.join(".")];
|
|
474
521
|
if (!InputComponent) {
|
|
475
522
|
if (options) {
|
|
476
|
-
return /* @__PURE__ */
|
|
523
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
477
524
|
key: name,
|
|
478
525
|
role: "none",
|
|
479
526
|
className: padding
|
|
480
|
-
}, /* @__PURE__ */
|
|
527
|
+
}, /* @__PURE__ */ React6.createElement(SelectInput, {
|
|
481
528
|
type,
|
|
482
529
|
format,
|
|
483
530
|
property: name,
|
|
@@ -493,7 +540,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
493
540
|
}
|
|
494
541
|
InputComponent = getInputComponent(type, format);
|
|
495
542
|
if (array) {
|
|
496
|
-
return /* @__PURE__ */
|
|
543
|
+
return /* @__PURE__ */ React6.createElement(ArrayField, {
|
|
497
544
|
key: name,
|
|
498
545
|
name,
|
|
499
546
|
type,
|
|
@@ -512,15 +559,15 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
512
559
|
if (!InputComponent) {
|
|
513
560
|
if (type === "object") {
|
|
514
561
|
const baseNode = findNode(ast, isDiscriminatedUnion);
|
|
515
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(ast,
|
|
562
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(ast, AST2.isTypeLiteral);
|
|
516
563
|
if (typeLiteral) {
|
|
517
564
|
const schema2 = S.make(typeLiteral);
|
|
518
|
-
return /* @__PURE__ */
|
|
565
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
519
566
|
key: name,
|
|
520
567
|
role: "none"
|
|
521
|
-
}, /* @__PURE__ */
|
|
568
|
+
}, /* @__PURE__ */ React6.createElement("div", {
|
|
522
569
|
className: padding
|
|
523
|
-
}, label), /* @__PURE__ */
|
|
570
|
+
}, label), /* @__PURE__ */ React6.createElement(Form, {
|
|
524
571
|
schema: schema2,
|
|
525
572
|
path: key,
|
|
526
573
|
values: values[name] ?? {},
|
|
@@ -536,17 +583,17 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
536
583
|
type
|
|
537
584
|
}, {
|
|
538
585
|
F: __dxlog_file2,
|
|
539
|
-
L:
|
|
586
|
+
L: 213,
|
|
540
587
|
S: void 0,
|
|
541
588
|
C: (f, a) => f(...a)
|
|
542
589
|
});
|
|
543
590
|
return null;
|
|
544
591
|
}
|
|
545
|
-
return /* @__PURE__ */
|
|
592
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
546
593
|
key: name,
|
|
547
594
|
role: "none",
|
|
548
595
|
className: padding
|
|
549
|
-
}, /* @__PURE__ */
|
|
596
|
+
}, /* @__PURE__ */ React6.createElement(InputComponent, {
|
|
550
597
|
type,
|
|
551
598
|
format,
|
|
552
599
|
property: name,
|
|
@@ -555,7 +602,7 @@ var Form = ({ classNames, schema, values: initialValues, path = [], readonly, fi
|
|
|
555
602
|
placeholder,
|
|
556
603
|
...inputProps
|
|
557
604
|
}));
|
|
558
|
-
}).filter(isNotFalsy), (onCancel || onSave) && !autoSave && /* @__PURE__ */
|
|
605
|
+
}).filter(isNotFalsy), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React6.createElement(FormActions, {
|
|
559
606
|
onCancel,
|
|
560
607
|
onSubmit: handleSave,
|
|
561
608
|
canSubmit: canSave,
|
|
@@ -568,33 +615,33 @@ var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholde
|
|
|
568
615
|
const key = [
|
|
569
616
|
name
|
|
570
617
|
];
|
|
571
|
-
const tupleType = findNode(ast,
|
|
618
|
+
const tupleType = findNode(ast, AST2.isTupleType);
|
|
572
619
|
const elementType = tupleType?.rest[0]?.type;
|
|
573
620
|
if (type === "object" && elementType) {
|
|
574
621
|
const baseNode = findNode(elementType, isDiscriminatedUnion);
|
|
575
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(elementType,
|
|
622
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(elementType, AST2.isTypeLiteral);
|
|
576
623
|
if (typeLiteral) {
|
|
577
624
|
const schema = S.make(typeLiteral);
|
|
578
|
-
return /* @__PURE__ */
|
|
625
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
579
626
|
key: name,
|
|
580
627
|
role: "none",
|
|
581
|
-
className:
|
|
582
|
-
}, /* @__PURE__ */
|
|
628
|
+
className: mx2(padding)
|
|
629
|
+
}, /* @__PURE__ */ React6.createElement(InputHeader, null, label), /* @__PURE__ */ React6.createElement("div", {
|
|
583
630
|
role: "none",
|
|
584
631
|
className: "flex flex-col gap-1"
|
|
585
632
|
}, arrayValues.map((value, index) => {
|
|
586
|
-
return /* @__PURE__ */
|
|
633
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
587
634
|
key: index,
|
|
588
635
|
role: "none",
|
|
589
636
|
className: "flex items-center gap-1"
|
|
590
|
-
}, /* @__PURE__ */
|
|
637
|
+
}, /* @__PURE__ */ React6.createElement("div", {
|
|
591
638
|
role: "none",
|
|
592
639
|
className: "flex-1"
|
|
593
|
-
}, /* @__PURE__ */
|
|
640
|
+
}, /* @__PURE__ */ React6.createElement(Form, {
|
|
594
641
|
schema,
|
|
595
642
|
path: [
|
|
596
643
|
...key,
|
|
597
|
-
index
|
|
644
|
+
`[${index}]`
|
|
598
645
|
],
|
|
599
646
|
values: value,
|
|
600
647
|
onValuesChanged: (childValues) => {
|
|
@@ -605,7 +652,7 @@ var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholde
|
|
|
605
652
|
inputProps.onValueChange(name, "object", newValues);
|
|
606
653
|
},
|
|
607
654
|
Custom
|
|
608
|
-
})), /* @__PURE__ */
|
|
655
|
+
})), /* @__PURE__ */ React6.createElement(IconButton, {
|
|
609
656
|
icon: "ph--trash--regular",
|
|
610
657
|
iconOnly: true,
|
|
611
658
|
label: t("button remove"),
|
|
@@ -614,10 +661,10 @@ var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholde
|
|
|
614
661
|
inputProps.onValueChange(name, type, newValues);
|
|
615
662
|
}
|
|
616
663
|
}));
|
|
617
|
-
})), /* @__PURE__ */
|
|
664
|
+
})), /* @__PURE__ */ React6.createElement("div", {
|
|
618
665
|
role: "none",
|
|
619
666
|
className: "flex justify-between items-center plb-1"
|
|
620
|
-
}, /* @__PURE__ */
|
|
667
|
+
}, /* @__PURE__ */ React6.createElement(IconButton, {
|
|
621
668
|
icon: "ph--plus--regular",
|
|
622
669
|
iconOnly: true,
|
|
623
670
|
label: t("button add"),
|
|
@@ -630,7 +677,7 @@ var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholde
|
|
|
630
677
|
}
|
|
631
678
|
})));
|
|
632
679
|
}
|
|
633
|
-
return /* @__PURE__ */
|
|
680
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
634
681
|
key: name,
|
|
635
682
|
role: "none"
|
|
636
683
|
}, "Nested form not supported in arrays, yet.");
|
|
@@ -639,30 +686,30 @@ var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholde
|
|
|
639
686
|
if (!InputComponent) {
|
|
640
687
|
return null;
|
|
641
688
|
}
|
|
642
|
-
return /* @__PURE__ */
|
|
689
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
643
690
|
role: "none",
|
|
644
691
|
key: "meta-input",
|
|
645
|
-
className:
|
|
646
|
-
}, /* @__PURE__ */
|
|
692
|
+
className: mx2(padding)
|
|
693
|
+
}, /* @__PURE__ */ React6.createElement(InputHeader, null, label), /* @__PURE__ */ React6.createElement("div", {
|
|
647
694
|
role: "none",
|
|
648
695
|
className: "flex flex-col gap-1"
|
|
649
|
-
}, arrayValues.map((_, index) => /* @__PURE__ */
|
|
696
|
+
}, arrayValues.map((_, index) => /* @__PURE__ */ React6.createElement("div", {
|
|
650
697
|
key: index,
|
|
651
698
|
role: "none",
|
|
652
699
|
className: "flex items-start gap-1"
|
|
653
|
-
}, /* @__PURE__ */
|
|
700
|
+
}, /* @__PURE__ */ React6.createElement("div", {
|
|
654
701
|
role: "none",
|
|
655
702
|
className: "flex-1"
|
|
656
|
-
}, /* @__PURE__ */
|
|
703
|
+
}, /* @__PURE__ */ React6.createElement(InputComponent, {
|
|
657
704
|
type,
|
|
658
705
|
format,
|
|
659
706
|
label,
|
|
660
707
|
inputOnly: true,
|
|
661
|
-
property: `${name}
|
|
708
|
+
property: `${name}[${index}]`,
|
|
662
709
|
disabled: readonly,
|
|
663
710
|
placeholder,
|
|
664
711
|
...inputProps
|
|
665
|
-
})), /* @__PURE__ */
|
|
712
|
+
})), /* @__PURE__ */ React6.createElement(IconButton, {
|
|
666
713
|
icon: "ph--trash--regular",
|
|
667
714
|
iconOnly: true,
|
|
668
715
|
label: t("button remove"),
|
|
@@ -670,10 +717,10 @@ var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholde
|
|
|
670
717
|
const newValues = arrayValues.filter((_2, i) => i !== index);
|
|
671
718
|
inputProps.onValueChange(name, type, newValues);
|
|
672
719
|
}
|
|
673
|
-
})))), /* @__PURE__ */
|
|
720
|
+
})))), /* @__PURE__ */ React6.createElement("div", {
|
|
674
721
|
role: "none",
|
|
675
722
|
className: "flex justify-between items-center plb-1"
|
|
676
|
-
}, /* @__PURE__ */
|
|
723
|
+
}, /* @__PURE__ */ React6.createElement(IconButton, {
|
|
677
724
|
icon: "ph--plus--regular",
|
|
678
725
|
iconOnly: true,
|
|
679
726
|
label: t("button add"),
|
|
@@ -688,18 +735,18 @@ var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholde
|
|
|
688
735
|
};
|
|
689
736
|
var FormActions = ({ onCancel, onSubmit, canSubmit, readonly }) => {
|
|
690
737
|
const { t } = useTranslation2(translationKey);
|
|
691
|
-
return /* @__PURE__ */
|
|
738
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
692
739
|
role: "none",
|
|
693
740
|
className: "flex justify-center"
|
|
694
|
-
}, /* @__PURE__ */
|
|
741
|
+
}, /* @__PURE__ */ React6.createElement("div", {
|
|
695
742
|
role: "none",
|
|
696
|
-
className:
|
|
697
|
-
}, onCancel && !readonly && /* @__PURE__ */
|
|
743
|
+
className: mx2(onCancel && !readonly && "grid grid-cols-2 gap-2")
|
|
744
|
+
}, onCancel && !readonly && /* @__PURE__ */ React6.createElement(IconButton, {
|
|
698
745
|
"data-testid": "cancel-button",
|
|
699
746
|
icon: "ph--x--regular",
|
|
700
747
|
label: t("button cancel"),
|
|
701
748
|
onClick: onCancel
|
|
702
|
-
}), onSubmit && /* @__PURE__ */
|
|
749
|
+
}), onSubmit && /* @__PURE__ */ React6.createElement(IconButton, {
|
|
703
750
|
type: "submit",
|
|
704
751
|
"data-testid": "save-button",
|
|
705
752
|
disabled: !canSubmit,
|
|
@@ -723,9 +770,11 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
723
770
|
if (!registry) {
|
|
724
771
|
return;
|
|
725
772
|
}
|
|
726
|
-
const subscription = registry.subscribe(setSchemas)
|
|
773
|
+
const subscription = registry.query().subscribe((query) => setSchemas(query.results), {
|
|
774
|
+
fire: true
|
|
775
|
+
});
|
|
727
776
|
const t2 = setTimeout(async () => {
|
|
728
|
-
const schemas2 = await registry.query();
|
|
777
|
+
const schemas2 = await registry.query().run();
|
|
729
778
|
setSchemas(schemas2);
|
|
730
779
|
});
|
|
731
780
|
return () => {
|
|
@@ -735,9 +784,9 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
735
784
|
}, [
|
|
736
785
|
registry
|
|
737
786
|
]);
|
|
738
|
-
const [
|
|
787
|
+
const [referenceSchema, setReferenceSchema] = useState2();
|
|
739
788
|
useEffect3(() => {
|
|
740
|
-
|
|
789
|
+
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
741
790
|
}, [
|
|
742
791
|
schemas,
|
|
743
792
|
props?.referenceSchema
|
|
@@ -746,14 +795,24 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
746
795
|
fieldSchema: getFormatSchema(props?.format)
|
|
747
796
|
});
|
|
748
797
|
const handleValuesChanged = useCallback2((_props) => {
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
798
|
+
setFieldSchema((prev) => {
|
|
799
|
+
const fieldSchema2 = getFormatSchema(_props.format);
|
|
800
|
+
if (prev.fieldSchema === fieldSchema2) {
|
|
801
|
+
return prev;
|
|
802
|
+
}
|
|
803
|
+
return {
|
|
804
|
+
fieldSchema: fieldSchema2
|
|
805
|
+
};
|
|
806
|
+
});
|
|
807
|
+
setReferenceSchema((prev) => {
|
|
808
|
+
if (_props.referenceSchema !== prev?.typename) {
|
|
809
|
+
const newSchema = schemas.find((schema) => schema.typename === _props.referenceSchema);
|
|
810
|
+
if (newSchema) {
|
|
811
|
+
return newSchema;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
return prev;
|
|
815
|
+
});
|
|
757
816
|
setProps((props2) => {
|
|
758
817
|
const type = formatToType[_props.format];
|
|
759
818
|
if (props2.type !== type) {
|
|
@@ -767,7 +826,8 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
767
826
|
});
|
|
768
827
|
}, [
|
|
769
828
|
schemas,
|
|
770
|
-
props
|
|
829
|
+
props.format,
|
|
830
|
+
props.referenceSchema
|
|
771
831
|
]);
|
|
772
832
|
const handleValidate = useCallback2(({ property }) => {
|
|
773
833
|
if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
|
|
@@ -799,23 +859,49 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
799
859
|
}, [
|
|
800
860
|
onSave
|
|
801
861
|
]);
|
|
862
|
+
const Custom = useMemo3(() => ({
|
|
863
|
+
["format"]: (props2) => /* @__PURE__ */ React7.createElement(SelectInput, {
|
|
864
|
+
...props2,
|
|
865
|
+
options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
|
|
866
|
+
value,
|
|
867
|
+
label: t(`format ${value}`)
|
|
868
|
+
}))
|
|
869
|
+
}),
|
|
870
|
+
["referenceSchema"]: (props2) => /* @__PURE__ */ React7.createElement(SelectInput, {
|
|
871
|
+
...props2,
|
|
872
|
+
options: schemas.map((schema) => ({
|
|
873
|
+
value: schema.typename
|
|
874
|
+
}))
|
|
875
|
+
}),
|
|
876
|
+
["referencePath"]: (props2) => /* @__PURE__ */ React7.createElement(SelectInput, {
|
|
877
|
+
...props2,
|
|
878
|
+
options: referenceSchema ? getSchemaProperties2(referenceSchema.ast).sort(sortProperties).map((p) => ({
|
|
879
|
+
value: p.name
|
|
880
|
+
})) : []
|
|
881
|
+
})
|
|
882
|
+
}), [
|
|
883
|
+
t,
|
|
884
|
+
schemas,
|
|
885
|
+
referenceSchema
|
|
886
|
+
]);
|
|
887
|
+
const propIsNotType = useCallback2((props2) => props2.filter((p) => p.name !== "type"), []);
|
|
802
888
|
if (!fieldSchema) {
|
|
803
889
|
log3.warn("invalid format", {
|
|
804
890
|
props
|
|
805
891
|
}, {
|
|
806
892
|
F: __dxlog_file3,
|
|
807
|
-
L:
|
|
893
|
+
L: 173,
|
|
808
894
|
S: void 0,
|
|
809
895
|
C: (f, a) => f(...a)
|
|
810
896
|
});
|
|
811
897
|
return null;
|
|
812
898
|
}
|
|
813
|
-
return /* @__PURE__ */
|
|
899
|
+
return /* @__PURE__ */ React7.createElement(Form, {
|
|
814
900
|
key: field.id,
|
|
815
901
|
autoFocus: true,
|
|
816
902
|
values: props,
|
|
817
903
|
schema: fieldSchema,
|
|
818
|
-
filter:
|
|
904
|
+
filter: propIsNotType,
|
|
819
905
|
sort: [
|
|
820
906
|
"property",
|
|
821
907
|
"format"
|
|
@@ -824,55 +910,35 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
824
910
|
onValidate: handleValidate,
|
|
825
911
|
onSave: handleSave,
|
|
826
912
|
onCancel: handleCancel,
|
|
827
|
-
Custom
|
|
828
|
-
["format"]: (props2) => /* @__PURE__ */ React6.createElement(SelectInput, {
|
|
829
|
-
...props2,
|
|
830
|
-
options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
|
|
831
|
-
value,
|
|
832
|
-
label: t(`format ${value}`)
|
|
833
|
-
}))
|
|
834
|
-
}),
|
|
835
|
-
["referenceSchema"]: (props2) => /* @__PURE__ */ React6.createElement(SelectInput, {
|
|
836
|
-
...props2,
|
|
837
|
-
options: schemas.map((schema2) => ({
|
|
838
|
-
value: schema2.typename
|
|
839
|
-
}))
|
|
840
|
-
}),
|
|
841
|
-
["referencePath"]: (props2) => /* @__PURE__ */ React6.createElement(SelectInput, {
|
|
842
|
-
...props2,
|
|
843
|
-
options: schema ? getSchemaProperties2(schema.schema.ast).sort(sortProperties).map((p) => ({
|
|
844
|
-
value: p.name
|
|
845
|
-
})) : []
|
|
846
|
-
})
|
|
847
|
-
}
|
|
913
|
+
Custom
|
|
848
914
|
});
|
|
849
915
|
};
|
|
850
916
|
|
|
851
917
|
// packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
|
|
852
|
-
import
|
|
853
|
-
import { AST as
|
|
918
|
+
import React8, { useCallback as useCallback3, useMemo as useMemo4, useState as useState3 } from "react";
|
|
919
|
+
import { AST as AST3, Format, S as S2 } from "@dxos/echo-schema";
|
|
854
920
|
import { IconButton as IconButton2, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
855
921
|
import { List } from "@dxos/react-ui-list";
|
|
856
|
-
import { ghostHover, inputTextLabel, mx as
|
|
922
|
+
import { ghostHover, inputTextLabel, mx as mx3 } from "@dxos/react-ui-theme";
|
|
857
923
|
import { FieldSchema, ViewProjection, VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
858
924
|
import { arrayMove } from "@dxos/util";
|
|
859
925
|
var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
|
|
860
926
|
var ViewMetaSchema = S2.Struct({
|
|
861
927
|
name: S2.String.annotations({
|
|
862
|
-
[
|
|
928
|
+
[AST3.TitleAnnotationId]: "View"
|
|
863
929
|
}),
|
|
864
930
|
typename: Format.DXN.annotations({
|
|
865
|
-
[
|
|
931
|
+
[AST3.TitleAnnotationId]: "Typename"
|
|
866
932
|
})
|
|
867
933
|
}).pipe(S2.mutable);
|
|
868
|
-
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onDelete }) => {
|
|
934
|
+
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
|
|
869
935
|
const { t } = useTranslation4(translationKey);
|
|
870
|
-
const projection =
|
|
936
|
+
const projection = useMemo4(() => new ViewProjection(schema, view), [
|
|
871
937
|
schema,
|
|
872
938
|
view
|
|
873
939
|
]);
|
|
874
940
|
const [field, setField] = useState3();
|
|
875
|
-
const viewValues =
|
|
941
|
+
const viewValues = useMemo4(() => {
|
|
876
942
|
return {
|
|
877
943
|
name: view.name,
|
|
878
944
|
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
@@ -884,13 +950,17 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
884
950
|
]);
|
|
885
951
|
const handleViewUpdate = useCallback3(({ name, typename }) => {
|
|
886
952
|
requestAnimationFrame(() => {
|
|
887
|
-
view.name
|
|
888
|
-
|
|
889
|
-
|
|
953
|
+
if (view.name !== name) {
|
|
954
|
+
view.name = name;
|
|
955
|
+
}
|
|
956
|
+
if (view.query.type !== typename) {
|
|
957
|
+
onTypenameChanged(typename);
|
|
958
|
+
}
|
|
890
959
|
});
|
|
891
960
|
}, [
|
|
892
961
|
view,
|
|
893
|
-
schema
|
|
962
|
+
schema,
|
|
963
|
+
onTypenameChanged
|
|
894
964
|
]);
|
|
895
965
|
const handleSelect = useCallback3((field2) => {
|
|
896
966
|
setField((f) => f === field2 ? void 0 : field2);
|
|
@@ -907,52 +977,52 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
907
977
|
view.fields
|
|
908
978
|
]);
|
|
909
979
|
const handleClose = useCallback3(() => setField(void 0), []);
|
|
910
|
-
return /* @__PURE__ */
|
|
980
|
+
return /* @__PURE__ */ React8.createElement("div", {
|
|
911
981
|
role: "none",
|
|
912
|
-
className:
|
|
913
|
-
}, /* @__PURE__ */
|
|
982
|
+
className: mx3("flex flex-col w-full divide-y divide-separator", classNames)
|
|
983
|
+
}, /* @__PURE__ */ React8.createElement(Form, {
|
|
914
984
|
autoFocus: true,
|
|
915
985
|
autoSave: true,
|
|
916
986
|
schema: ViewMetaSchema,
|
|
917
987
|
values: viewValues,
|
|
918
988
|
onSave: handleViewUpdate
|
|
919
|
-
}), /* @__PURE__ */
|
|
989
|
+
}), /* @__PURE__ */ React8.createElement("div", null, /* @__PURE__ */ React8.createElement("div", {
|
|
920
990
|
role: "none",
|
|
921
991
|
className: "p-2"
|
|
922
|
-
}, /* @__PURE__ */
|
|
923
|
-
className:
|
|
924
|
-
}, t("fields label"))), /* @__PURE__ */
|
|
992
|
+
}, /* @__PURE__ */ React8.createElement("label", {
|
|
993
|
+
className: mx3(inputTextLabel)
|
|
994
|
+
}, t("fields label"))), /* @__PURE__ */ React8.createElement(List.Root, {
|
|
925
995
|
items: view.fields,
|
|
926
996
|
isItem: S2.is(FieldSchema),
|
|
927
997
|
getId: (field2) => field2.id,
|
|
928
998
|
onMove: handleMove
|
|
929
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
999
|
+
}, ({ items: fields }) => /* @__PURE__ */ React8.createElement(React8.Fragment, null, showHeading && /* @__PURE__ */ React8.createElement("div", {
|
|
930
1000
|
role: "heading",
|
|
931
1001
|
className: grid
|
|
932
|
-
}, /* @__PURE__ */
|
|
1002
|
+
}, /* @__PURE__ */ React8.createElement("div", null), /* @__PURE__ */ React8.createElement("div", {
|
|
933
1003
|
className: "flex items-center text-sm"
|
|
934
|
-
}, t("field path label"))), /* @__PURE__ */
|
|
1004
|
+
}, t("field path label"))), /* @__PURE__ */ React8.createElement("div", {
|
|
935
1005
|
role: "list",
|
|
936
1006
|
className: "flex flex-col w-full"
|
|
937
|
-
}, fields?.map((field2) => /* @__PURE__ */
|
|
1007
|
+
}, fields?.map((field2) => /* @__PURE__ */ React8.createElement(List.Item, {
|
|
938
1008
|
key: field2.id,
|
|
939
1009
|
item: field2,
|
|
940
|
-
classNames:
|
|
941
|
-
}, /* @__PURE__ */
|
|
1010
|
+
classNames: mx3(grid, ghostHover, "cursor-pointer")
|
|
1011
|
+
}, /* @__PURE__ */ React8.createElement(List.ItemDragHandle, null), /* @__PURE__ */ React8.createElement(List.ItemTitle, {
|
|
942
1012
|
onClick: () => handleSelect(field2)
|
|
943
|
-
}, field2.path), /* @__PURE__ */
|
|
1013
|
+
}, field2.path), /* @__PURE__ */ React8.createElement(List.ItemDeleteButton, {
|
|
944
1014
|
disabled: view.fields.length <= 1,
|
|
945
1015
|
onClick: () => onDelete(field2.id)
|
|
946
|
-
}))))))), field && /* @__PURE__ */
|
|
1016
|
+
}))))))), field && /* @__PURE__ */ React8.createElement(FieldEditor, {
|
|
947
1017
|
key: field.id,
|
|
948
1018
|
view,
|
|
949
1019
|
projection,
|
|
950
1020
|
field,
|
|
951
1021
|
registry,
|
|
952
1022
|
onSave: handleClose
|
|
953
|
-
}), !readonly && !field && /* @__PURE__ */
|
|
1023
|
+
}), !readonly && !field && /* @__PURE__ */ React8.createElement("div", {
|
|
954
1024
|
className: "flex p-2 justify-center"
|
|
955
|
-
}, /* @__PURE__ */
|
|
1025
|
+
}, /* @__PURE__ */ React8.createElement(IconButton2, {
|
|
956
1026
|
icon: "ph--plus--regular",
|
|
957
1027
|
label: t("button add property"),
|
|
958
1028
|
onClick: handleAdd,
|
|
@@ -1186,11 +1256,12 @@ export {
|
|
|
1186
1256
|
FieldEditor,
|
|
1187
1257
|
Form,
|
|
1188
1258
|
FormActions,
|
|
1189
|
-
|
|
1259
|
+
GeoPointInput,
|
|
1190
1260
|
InputHeader,
|
|
1191
1261
|
NumberInput,
|
|
1192
1262
|
SelectInput,
|
|
1193
1263
|
TextInput,
|
|
1264
|
+
TupleInput,
|
|
1194
1265
|
ViewEditor,
|
|
1195
1266
|
cellClassesForFieldType,
|
|
1196
1267
|
cellClassesForRowSelection,
|