@dxos/react-ui-form 0.7.4 → 0.7.5-labs.5f04cf6
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 +574 -496
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +629 -565
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +574 -496
- 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/ArrayField.d.ts +16 -0
- package/dist/types/src/components/Form/ArrayField.d.ts.map +1 -0
- package/dist/types/src/components/Form/Defaults.d.ts +5 -6
- package/dist/types/src/components/Form/Defaults.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +13 -17
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +7 -1
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormActions.d.ts +7 -0
- package/dist/types/src/components/Form/FormActions.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormContent.d.ts +26 -0
- package/dist/types/src/components/Form/FormContent.d.ts.map +1 -0
- package/dist/types/src/components/Form/FormContext.d.ts +20 -0
- package/dist/types/src/components/Form/FormContext.d.ts.map +1 -0
- package/dist/types/src/components/Form/Input.d.ts +5 -6
- package/dist/types/src/components/Form/Input.d.ts.map +1 -1
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts +4 -0
- package/dist/types/src/components/Form/custom/GeoPointInput.d.ts.map +1 -0
- package/dist/types/src/components/Form/custom/TupleInput.d.ts +6 -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 +2 -2
- 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 +13 -15
- 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/ArrayField.tsx +111 -0
- package/src/components/Form/Defaults.tsx +20 -33
- package/src/components/Form/Form.stories.tsx +48 -6
- package/src/components/Form/Form.tsx +39 -333
- package/src/components/Form/FormActions.tsx +41 -0
- package/src/components/Form/FormContent.tsx +155 -0
- package/src/components/Form/FormContext.tsx +48 -0
- package/src/components/Form/Input.tsx +5 -6
- package/src/components/Form/custom/GeoPointInput.tsx +44 -0
- package/src/components/Form/custom/TupleInput.tsx +49 -0
- package/src/components/Form/custom/index.ts +6 -0
- package/src/components/Form/factory.tsx +4 -7
- 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 +67 -78
- package/dist/types/src/components/Form/Custom.d.ts +0 -5
- package/dist/types/src/components/Form/Custom.d.ts.map +0 -1
- package/src/components/Form/Custom.tsx +0 -65
|
@@ -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 React11, { useCallback as useCallback3, useEffect as useEffect2, useMemo as useMemo5, useState as useState2 } from "react";
|
|
84
84
|
import { FormatEnum as FormatEnum2, FormatEnums, formatToType } from "@dxos/echo-schema";
|
|
85
|
-
import { log as log3 } from "@dxos/log";
|
|
86
|
-
import { useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
87
|
-
import { getFormatSchema, getSchemaProperties as getSchemaProperties2, sortProperties } from "@dxos/schema";
|
|
88
|
-
|
|
89
|
-
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
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
85
|
import { log as log2 } from "@dxos/log";
|
|
96
|
-
import {
|
|
97
|
-
import {
|
|
98
|
-
import { getSchemaProperties } from "@dxos/schema";
|
|
99
|
-
import { isNotFalsy } from "@dxos/util";
|
|
86
|
+
import { useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
87
|
+
import { getFormatSchema, getSchemaProperties as getSchemaProperties3, sortProperties } from "@dxos/schema";
|
|
100
88
|
|
|
101
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
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,138 +110,171 @@ 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
|
|
126
|
-
const {
|
|
113
|
+
// packages/ui/react-ui-form/src/components/Form/custom/GeoPointInput.tsx
|
|
114
|
+
var GeoPointInput = ({ type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
115
|
+
const { t } = useTranslation(translationKey);
|
|
116
|
+
const { status, error } = getStatus();
|
|
117
|
+
const [lng = 0, lat = 0] = getValue3() ?? [];
|
|
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(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(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, type, label, disabled, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
159
|
+
const { status, error } = getStatus();
|
|
160
|
+
const values = getValue3() ?? {};
|
|
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(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 = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
184
|
+
const { status, error } = getStatus();
|
|
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:
|
|
135
|
-
onChange: (event) => onValueChange(
|
|
192
|
+
value: getValue3() ?? "",
|
|
193
|
+
onChange: (event) => onValueChange(type, event.target.value),
|
|
136
194
|
onBlur
|
|
137
|
-
}), inputOnly && /* @__PURE__ */
|
|
195
|
+
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.Validation, null, error));
|
|
138
196
|
};
|
|
139
|
-
var NumberInput = ({
|
|
140
|
-
const { status, error } = getStatus
|
|
141
|
-
return /* @__PURE__ */
|
|
197
|
+
var NumberInput = ({ type, label, inputOnly, disabled, placeholder, getStatus, getValue: getValue3, onValueChange, onBlur }) => {
|
|
198
|
+
const { status, error } = getStatus();
|
|
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:
|
|
150
|
-
onChange: (event) => onValueChange(
|
|
207
|
+
value: getValue3() ?? 0,
|
|
208
|
+
onChange: (event) => onValueChange(type, event.target.value),
|
|
151
209
|
onBlur
|
|
152
|
-
}), inputOnly && /* @__PURE__ */
|
|
210
|
+
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.DescriptionAndValidation, null, error));
|
|
153
211
|
};
|
|
154
|
-
var BooleanInput = ({
|
|
155
|
-
const { status, error } = getStatus
|
|
156
|
-
return /* @__PURE__ */
|
|
212
|
+
var BooleanInput = ({ type, label, inputOnly, getStatus, getValue: getValue3, onValueChange }) => {
|
|
213
|
+
const { status, error } = getStatus();
|
|
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:
|
|
162
|
-
onCheckedChange: (value) => onValueChange(
|
|
163
|
-
}), inputOnly && /* @__PURE__ */
|
|
218
|
+
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement(Input4.Switch, {
|
|
219
|
+
checked: getValue3(),
|
|
220
|
+
onCheckedChange: (value) => onValueChange(type, value)
|
|
221
|
+
}), inputOnly && /* @__PURE__ */ React5.createElement(Input4.DescriptionAndValidation, null, error));
|
|
164
222
|
};
|
|
165
|
-
var SelectInput = ({
|
|
166
|
-
const { status, error } = getStatus
|
|
167
|
-
return /* @__PURE__ */
|
|
223
|
+
var SelectInput = ({ type, label, inputOnly, disabled, placeholder, options, getStatus, getValue: getValue3, onValueChange }) => {
|
|
224
|
+
const { status, error } = getStatus();
|
|
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:
|
|
173
|
-
onValueChange: (value) => onValueChange(
|
|
174
|
-
}, /* @__PURE__ */
|
|
229
|
+
}, /* @__PURE__ */ React5.createElement(Input4.Label, null, label)), /* @__PURE__ */ React5.createElement(Select.Root, {
|
|
230
|
+
value: getValue3(),
|
|
231
|
+
onValueChange: (value) => onValueChange(type, value)
|
|
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 {
|
|
245
|
+
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
246
|
+
import React10, { useMemo as useMemo4 } from "react";
|
|
247
|
+
import { mx as mx5 } from "@dxos/react-ui-theme";
|
|
189
248
|
|
|
190
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
191
|
-
import
|
|
192
|
-
import {
|
|
193
|
-
|
|
194
|
-
const { t } = useTranslation(translationKey);
|
|
195
|
-
const { status, error } = getStatus?.(property);
|
|
196
|
-
const [lng = 0, lat = 0] = getValue(property) ?? [];
|
|
197
|
-
return /* @__PURE__ */ React4.createElement(Input3.Root, {
|
|
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
|
-
};
|
|
249
|
+
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
250
|
+
import React7 from "react";
|
|
251
|
+
import { IconButton, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
252
|
+
import { mx as mx2 } from "@dxos/react-ui-theme";
|
|
232
253
|
|
|
233
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
switch (type) {
|
|
240
|
-
case "string":
|
|
241
|
-
return TextInput;
|
|
242
|
-
case "number":
|
|
243
|
-
return NumberInput;
|
|
244
|
-
case "boolean":
|
|
245
|
-
return BooleanInput;
|
|
246
|
-
}
|
|
247
|
-
};
|
|
254
|
+
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
255
|
+
import React6, { createContext, useContext } from "react";
|
|
256
|
+
import { raise } from "@dxos/debug";
|
|
257
|
+
import { getValue as getValue2 } from "@dxos/echo-schema";
|
|
258
|
+
import { createJsonPath as createJsonPath2 } from "@dxos/effect";
|
|
248
259
|
|
|
249
260
|
// packages/ui/react-ui-form/src/hooks/useForm.ts
|
|
250
261
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
262
|
+
import { getValue, setValue } from "@dxos/echo-schema";
|
|
263
|
+
import { AST, createJsonPath, fromEffectValidationPath } from "@dxos/effect";
|
|
251
264
|
import { invariant } from "@dxos/invariant";
|
|
252
265
|
import { log } from "@dxos/log";
|
|
253
266
|
import { validateSchema } from "@dxos/schema";
|
|
254
267
|
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/hooks/useForm.ts";
|
|
255
268
|
var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, onSave }) => {
|
|
269
|
+
invariant(AST.isTypeLiteral(schema.ast), void 0, {
|
|
270
|
+
F: __dxlog_file,
|
|
271
|
+
L: 91,
|
|
272
|
+
S: void 0,
|
|
273
|
+
A: [
|
|
274
|
+
"AST.isTypeLiteral(schema.ast)",
|
|
275
|
+
""
|
|
276
|
+
]
|
|
277
|
+
});
|
|
256
278
|
const [values, setValues] = useState(initialValues);
|
|
257
279
|
useEffect(() => {
|
|
258
280
|
setValues(initialValues);
|
|
@@ -266,10 +288,12 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
266
288
|
const validate = useCallback((values2) => {
|
|
267
289
|
let errors2 = validateSchema(schema, values2) ?? [];
|
|
268
290
|
if (errors2.length === 0 && onValidate) {
|
|
269
|
-
|
|
291
|
+
const validatedValues = values2;
|
|
292
|
+
errors2 = onValidate(validatedValues) ?? [];
|
|
270
293
|
}
|
|
271
294
|
setErrors(flatMap(errors2));
|
|
272
|
-
|
|
295
|
+
const valid = errors2.length === 0;
|
|
296
|
+
return valid;
|
|
273
297
|
}, [
|
|
274
298
|
schema,
|
|
275
299
|
onValidate
|
|
@@ -287,8 +311,8 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
287
311
|
values,
|
|
288
312
|
schemaDirty
|
|
289
313
|
]);
|
|
290
|
-
const canSave = useMemo(() => !saving &&
|
|
291
|
-
|
|
314
|
+
const canSave = useMemo(() => !saving && // Check if any error paths that are touched have errors
|
|
315
|
+
!Object.entries(touched).some(([path, isTouched]) => isTouched && Object.keys(errors).some((errorPath) => errorPath === path || errorPath.startsWith(`${path}.`) || errorPath.startsWith(`${path}[`))), [
|
|
292
316
|
touched,
|
|
293
317
|
errors,
|
|
294
318
|
saving
|
|
@@ -307,19 +331,24 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
307
331
|
}, [
|
|
308
332
|
values,
|
|
309
333
|
validate,
|
|
310
|
-
onSave
|
|
334
|
+
onSave,
|
|
335
|
+
changed
|
|
311
336
|
]);
|
|
312
|
-
const getStatus = useCallback((
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
337
|
+
const getStatus = useCallback((path) => {
|
|
338
|
+
const jsonPath = Array.isArray(path) ? createJsonPath(path) : path;
|
|
339
|
+
const matchingError = Object.entries(errors).find(([errorPath]) => errorPath === jsonPath || errorPath.startsWith(`${jsonPath}.`) || errorPath.startsWith(`${jsonPath}[`));
|
|
340
|
+
return {
|
|
341
|
+
status: matchingError ? "error" : void 0,
|
|
342
|
+
error: matchingError ? matchingError[1] : void 0
|
|
343
|
+
};
|
|
344
|
+
}, [
|
|
317
345
|
errors
|
|
318
346
|
]);
|
|
319
|
-
const
|
|
320
|
-
return
|
|
347
|
+
const getFormValue = (path) => {
|
|
348
|
+
return getValue(values, createJsonPath(path));
|
|
321
349
|
};
|
|
322
|
-
const onValueChange = (
|
|
350
|
+
const onValueChange = (path, type, value) => {
|
|
351
|
+
const jsonPath = createJsonPath(path);
|
|
323
352
|
let parsedValue = value;
|
|
324
353
|
try {
|
|
325
354
|
if (type === "number") {
|
|
@@ -328,17 +357,19 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
328
357
|
} catch (err) {
|
|
329
358
|
log.catch(err, void 0, {
|
|
330
359
|
F: __dxlog_file,
|
|
331
|
-
L:
|
|
360
|
+
L: 194,
|
|
332
361
|
S: void 0,
|
|
333
362
|
C: (f, a) => f(...a)
|
|
334
363
|
});
|
|
335
364
|
parsedValue = void 0;
|
|
336
365
|
}
|
|
337
|
-
const newValues =
|
|
366
|
+
const newValues = {
|
|
367
|
+
...setValue(values, jsonPath, parsedValue)
|
|
368
|
+
};
|
|
338
369
|
setValues(newValues);
|
|
339
370
|
setChanged((prev) => ({
|
|
340
371
|
...prev,
|
|
341
|
-
[
|
|
372
|
+
[jsonPath]: true
|
|
342
373
|
}));
|
|
343
374
|
onValuesChanged?.(newValues);
|
|
344
375
|
const isValid = validate(newValues);
|
|
@@ -348,15 +379,12 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
348
379
|
});
|
|
349
380
|
}
|
|
350
381
|
};
|
|
351
|
-
const
|
|
352
|
-
const
|
|
382
|
+
const onTouched = useCallback((path) => {
|
|
383
|
+
const jsonPath = createJsonPath(path);
|
|
353
384
|
setTouched((touched2) => ({
|
|
354
385
|
...touched2,
|
|
355
|
-
[
|
|
386
|
+
[jsonPath]: true
|
|
356
387
|
}));
|
|
357
|
-
if (event.relatedTarget?.getAttribute("type") === "submit") {
|
|
358
|
-
setTouched(createKeySet(values, true));
|
|
359
|
-
}
|
|
360
388
|
validate(values);
|
|
361
389
|
}, [
|
|
362
390
|
validate,
|
|
@@ -372,15 +400,15 @@ var useForm = ({ schema, initialValues, onValuesChanged, onValidate, onValid, on
|
|
|
372
400
|
handleSave,
|
|
373
401
|
// Field utils.
|
|
374
402
|
getStatus,
|
|
375
|
-
getValue,
|
|
403
|
+
getValue: getFormValue,
|
|
376
404
|
onValueChange,
|
|
377
|
-
|
|
405
|
+
onTouched
|
|
378
406
|
};
|
|
379
407
|
};
|
|
380
408
|
var createKeySet = (obj, value) => {
|
|
381
409
|
invariant(obj, void 0, {
|
|
382
410
|
F: __dxlog_file,
|
|
383
|
-
L:
|
|
411
|
+
L: 236,
|
|
384
412
|
S: void 0,
|
|
385
413
|
A: [
|
|
386
414
|
"obj",
|
|
@@ -394,338 +422,367 @@ var createKeySet = (obj, value) => {
|
|
|
394
422
|
};
|
|
395
423
|
var flatMap = (errors) => {
|
|
396
424
|
return errors.reduce((result, { path, message }) => {
|
|
397
|
-
|
|
398
|
-
|
|
425
|
+
const jsonPath = fromEffectValidationPath(path);
|
|
426
|
+
if (!(jsonPath in result)) {
|
|
427
|
+
result[jsonPath] = message;
|
|
399
428
|
}
|
|
400
429
|
return result;
|
|
401
430
|
}, {});
|
|
402
431
|
};
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
432
|
+
|
|
433
|
+
// packages/ui/react-ui-form/src/components/Form/FormContext.tsx
|
|
434
|
+
var FormContext = /* @__PURE__ */ createContext(void 0);
|
|
435
|
+
var useFormContext = () => {
|
|
436
|
+
return useContext(FormContext) ?? raise(new Error("Missing FormContext"));
|
|
437
|
+
};
|
|
438
|
+
var useFormValues = (path = []) => {
|
|
439
|
+
const { values: formValues } = useFormContext();
|
|
440
|
+
const jsonPath = createJsonPath2(path);
|
|
441
|
+
return getValue2(formValues, jsonPath);
|
|
406
442
|
};
|
|
407
|
-
var
|
|
408
|
-
const
|
|
409
|
-
const newValue = index === void 0 ? value : [
|
|
410
|
-
...obj[key]
|
|
411
|
-
].map((v, i) => i === parseInt(index) ? value : v);
|
|
443
|
+
var useInputProps = (path = []) => {
|
|
444
|
+
const { getStatus, getValue: getFormValue, onValueChange, onTouched } = useFormContext();
|
|
412
445
|
return {
|
|
413
|
-
|
|
414
|
-
|
|
446
|
+
getStatus: () => getStatus(path),
|
|
447
|
+
getValue: () => getFormValue(path),
|
|
448
|
+
onValueChange: (type, value) => onValueChange(path, type, value),
|
|
449
|
+
onBlur: () => onTouched(path)
|
|
415
450
|
};
|
|
416
451
|
};
|
|
452
|
+
var FormProvider = ({ children, ...formOptions }) => {
|
|
453
|
+
const formHandler = useForm(formOptions);
|
|
454
|
+
return /* @__PURE__ */ React6.createElement(FormContext.Provider, {
|
|
455
|
+
value: formHandler
|
|
456
|
+
}, children);
|
|
457
|
+
};
|
|
417
458
|
|
|
418
|
-
// packages/ui/react-ui-form/src/components/Form/
|
|
419
|
-
var
|
|
459
|
+
// packages/ui/react-ui-form/src/components/Form/FormActions.tsx
|
|
460
|
+
var FormActions = ({ onCancel, readonly }) => {
|
|
461
|
+
const { t } = useTranslation2(translationKey);
|
|
462
|
+
const { canSave, handleSave } = useFormContext();
|
|
463
|
+
return /* @__PURE__ */ React7.createElement("div", {
|
|
464
|
+
role: "none",
|
|
465
|
+
className: "flex justify-center"
|
|
466
|
+
}, /* @__PURE__ */ React7.createElement("div", {
|
|
467
|
+
role: "none",
|
|
468
|
+
className: mx2(onCancel && !readonly && "grid grid-cols-2 gap-2")
|
|
469
|
+
}, onCancel && !readonly && /* @__PURE__ */ React7.createElement(IconButton, {
|
|
470
|
+
"data-testid": "cancel-button",
|
|
471
|
+
icon: "ph--x--regular",
|
|
472
|
+
label: t("button cancel"),
|
|
473
|
+
onClick: onCancel
|
|
474
|
+
}), handleSave && /* @__PURE__ */ React7.createElement(IconButton, {
|
|
475
|
+
type: "submit",
|
|
476
|
+
"data-testid": "save-button",
|
|
477
|
+
disabled: !canSave,
|
|
478
|
+
icon: "ph--check--regular",
|
|
479
|
+
label: t("button save"),
|
|
480
|
+
onClick: handleSave
|
|
481
|
+
})));
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
485
|
+
import { pipe as pipe2 } from "effect";
|
|
486
|
+
import { capitalize as capitalize2 } from "effect/String";
|
|
487
|
+
import React9, { useMemo as useMemo3 } from "react";
|
|
488
|
+
import { AST as AST3, S } from "@dxos/echo-schema";
|
|
489
|
+
import { createJsonPath as createJsonPath3, findNode as findNode2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2 } from "@dxos/effect";
|
|
490
|
+
import { mx as mx4 } from "@dxos/react-ui-theme";
|
|
491
|
+
import { getSchemaProperties as getSchemaProperties2 } from "@dxos/schema";
|
|
492
|
+
import { isNotFalsy } from "@dxos/util";
|
|
493
|
+
|
|
494
|
+
// packages/ui/react-ui-form/src/components/Form/ArrayField.tsx
|
|
495
|
+
import { pipe } from "effect";
|
|
496
|
+
import { capitalize } from "effect/String";
|
|
497
|
+
import React8, { useCallback as useCallback2, useMemo as useMemo2 } from "react";
|
|
498
|
+
import { AST as AST2 } from "@dxos/echo-schema";
|
|
499
|
+
import { findNode, getDiscriminatedType, isDiscriminatedUnion, SimpleType } from "@dxos/effect";
|
|
500
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
501
|
+
import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
502
|
+
import { mx as mx3 } from "@dxos/react-ui-theme";
|
|
503
|
+
import { getSchemaProperties } from "@dxos/schema";
|
|
504
|
+
var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/Form/ArrayField.tsx";
|
|
420
505
|
var padding = "px-2";
|
|
421
|
-
var
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
506
|
+
var ArrayField = ({ property, readonly, path, inputProps, Custom, lookupComponent }) => {
|
|
507
|
+
const { t } = useTranslation3(translationKey);
|
|
508
|
+
const { ast, name, type, title } = property;
|
|
509
|
+
const values = useFormValues(path ?? []);
|
|
510
|
+
invariant2(Array.isArray(values), void 0, {
|
|
511
|
+
F: __dxlog_file2,
|
|
512
|
+
L: 37,
|
|
513
|
+
S: void 0,
|
|
514
|
+
A: [
|
|
515
|
+
"Array.isArray(values)",
|
|
516
|
+
""
|
|
517
|
+
]
|
|
433
518
|
});
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
519
|
+
const label = title ?? pipe(name, capitalize);
|
|
520
|
+
const tupleType = findNode(ast, AST2.isTupleType);
|
|
521
|
+
const elementType = tupleType?.rest[0]?.type;
|
|
522
|
+
const getDefaultObjectValue = (typeNode) => {
|
|
523
|
+
const baseNode = findNode(typeNode, isDiscriminatedUnion);
|
|
524
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, {}) : findNode(typeNode, AST2.isTypeLiteral);
|
|
525
|
+
if (!typeLiteral) {
|
|
526
|
+
return {};
|
|
527
|
+
}
|
|
528
|
+
return Object.fromEntries(getSchemaProperties(typeLiteral, {}).map((prop) => [
|
|
529
|
+
prop.name,
|
|
530
|
+
prop.defaultValue
|
|
531
|
+
]));
|
|
532
|
+
};
|
|
533
|
+
const newValue = useMemo2(() => {
|
|
534
|
+
if (type === "object" && elementType) {
|
|
535
|
+
return getDefaultObjectValue(elementType);
|
|
536
|
+
} else {
|
|
537
|
+
return SimpleType.getDefaultValue(type);
|
|
538
|
+
}
|
|
442
539
|
}, [
|
|
443
|
-
|
|
444
|
-
|
|
540
|
+
type,
|
|
541
|
+
elementType
|
|
542
|
+
]);
|
|
543
|
+
const handleAdd = useCallback2(() => {
|
|
544
|
+
inputProps.onValueChange(type, [
|
|
545
|
+
...values,
|
|
546
|
+
newValue
|
|
547
|
+
]);
|
|
548
|
+
}, [
|
|
549
|
+
type,
|
|
550
|
+
elementType,
|
|
551
|
+
inputProps,
|
|
552
|
+
newValue,
|
|
445
553
|
values
|
|
446
554
|
]);
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
errors
|
|
451
|
-
}, {
|
|
452
|
-
F: __dxlog_file2,
|
|
453
|
-
L: 100,
|
|
454
|
-
S: void 0,
|
|
455
|
-
C: (f, a) => f(...a)
|
|
456
|
-
});
|
|
457
|
-
}
|
|
555
|
+
const handleRemove = useCallback2((index) => {
|
|
556
|
+
const newValues = values.filter((_, i) => i !== index);
|
|
557
|
+
inputProps.onValueChange(type, newValues);
|
|
458
558
|
}, [
|
|
459
|
-
|
|
559
|
+
type,
|
|
560
|
+
inputProps,
|
|
561
|
+
values
|
|
460
562
|
]);
|
|
461
|
-
|
|
462
|
-
role: "form",
|
|
463
|
-
className: mx("flex flex-col w-full gap-2 py-2", classNames),
|
|
464
|
-
"data-testid": testId
|
|
465
|
-
}, properties.map((property) => {
|
|
466
|
-
const { ast, name, type, format, title, description, examples, options, array } = property;
|
|
467
|
-
const key = [
|
|
468
|
-
...path,
|
|
469
|
-
name
|
|
470
|
-
];
|
|
471
|
-
const label = title ?? pipe(name, capitalize);
|
|
472
|
-
const placeholder = examples?.length ? `Example: "${examples[0]}"` : description;
|
|
473
|
-
let InputComponent = Custom?.[key.join(".")];
|
|
474
|
-
if (!InputComponent) {
|
|
475
|
-
if (options) {
|
|
476
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
477
|
-
key: name,
|
|
478
|
-
role: "none",
|
|
479
|
-
className: padding
|
|
480
|
-
}, /* @__PURE__ */ React5.createElement(SelectInput, {
|
|
481
|
-
type,
|
|
482
|
-
format,
|
|
483
|
-
property: name,
|
|
484
|
-
disabled: readonly,
|
|
485
|
-
label,
|
|
486
|
-
options: options.map((option) => ({
|
|
487
|
-
value: option,
|
|
488
|
-
label: String(option)
|
|
489
|
-
})),
|
|
490
|
-
placeholder,
|
|
491
|
-
...inputProps
|
|
492
|
-
}));
|
|
493
|
-
}
|
|
494
|
-
InputComponent = getInputComponent(type, format);
|
|
495
|
-
if (array) {
|
|
496
|
-
return /* @__PURE__ */ React5.createElement(ArrayField, {
|
|
497
|
-
key: name,
|
|
498
|
-
name,
|
|
499
|
-
type,
|
|
500
|
-
array: true,
|
|
501
|
-
label,
|
|
502
|
-
ast,
|
|
503
|
-
values,
|
|
504
|
-
format,
|
|
505
|
-
readonly,
|
|
506
|
-
placeholder,
|
|
507
|
-
inputProps,
|
|
508
|
-
Custom
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
if (!InputComponent) {
|
|
513
|
-
if (type === "object") {
|
|
514
|
-
const baseNode = findNode(ast, isDiscriminatedUnion);
|
|
515
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(ast, AST.isTypeLiteral);
|
|
516
|
-
if (typeLiteral) {
|
|
517
|
-
const schema2 = S.make(typeLiteral);
|
|
518
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
519
|
-
key: name,
|
|
520
|
-
role: "none"
|
|
521
|
-
}, /* @__PURE__ */ React5.createElement("div", {
|
|
522
|
-
className: padding
|
|
523
|
-
}, label), /* @__PURE__ */ React5.createElement(Form, {
|
|
524
|
-
schema: schema2,
|
|
525
|
-
path: key,
|
|
526
|
-
values: values[name] ?? {},
|
|
527
|
-
onValuesChanged: (childValues) => {
|
|
528
|
-
inputProps.onValueChange(name, "object", childValues);
|
|
529
|
-
},
|
|
530
|
-
Custom
|
|
531
|
-
}));
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
log2("no renderer for property", {
|
|
535
|
-
name,
|
|
536
|
-
type
|
|
537
|
-
}, {
|
|
538
|
-
F: __dxlog_file2,
|
|
539
|
-
L: 185,
|
|
540
|
-
S: void 0,
|
|
541
|
-
C: (f, a) => f(...a)
|
|
542
|
-
});
|
|
543
|
-
return null;
|
|
544
|
-
}
|
|
545
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
546
|
-
key: name,
|
|
547
|
-
role: "none",
|
|
548
|
-
className: padding
|
|
549
|
-
}, /* @__PURE__ */ React5.createElement(InputComponent, {
|
|
550
|
-
type,
|
|
551
|
-
format,
|
|
552
|
-
property: name,
|
|
553
|
-
disabled: readonly,
|
|
554
|
-
label,
|
|
555
|
-
placeholder,
|
|
556
|
-
...inputProps
|
|
557
|
-
}));
|
|
558
|
-
}).filter(isNotFalsy), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React5.createElement(FormActions, {
|
|
559
|
-
onCancel,
|
|
560
|
-
onSubmit: handleSave,
|
|
561
|
-
canSubmit: canSave,
|
|
562
|
-
readonly
|
|
563
|
-
}));
|
|
564
|
-
};
|
|
565
|
-
var ArrayField = ({ name, type, label, ast, values, format, readonly, placeholder, inputProps, Custom }) => {
|
|
566
|
-
const { t } = useTranslation2(translationKey);
|
|
567
|
-
const arrayValues = values[name] ?? [];
|
|
568
|
-
const key = [
|
|
569
|
-
name
|
|
570
|
-
];
|
|
571
|
-
const tupleType = findNode(ast, AST.isTupleType);
|
|
572
|
-
const elementType = tupleType?.rest[0]?.type;
|
|
573
|
-
if (type === "object" && elementType) {
|
|
574
|
-
const baseNode = findNode(elementType, isDiscriminatedUnion);
|
|
575
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, values[name]) : findNode(elementType, AST.isTypeLiteral);
|
|
576
|
-
if (typeLiteral) {
|
|
577
|
-
const schema = S.make(typeLiteral);
|
|
578
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
579
|
-
key: name,
|
|
580
|
-
role: "none",
|
|
581
|
-
className: mx(padding)
|
|
582
|
-
}, /* @__PURE__ */ React5.createElement(InputHeader, null, label), /* @__PURE__ */ React5.createElement("div", {
|
|
583
|
-
role: "none",
|
|
584
|
-
className: "flex flex-col gap-1"
|
|
585
|
-
}, arrayValues.map((value, index) => {
|
|
586
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
587
|
-
key: index,
|
|
588
|
-
role: "none",
|
|
589
|
-
className: "flex items-center gap-1"
|
|
590
|
-
}, /* @__PURE__ */ React5.createElement("div", {
|
|
591
|
-
role: "none",
|
|
592
|
-
className: "flex-1"
|
|
593
|
-
}, /* @__PURE__ */ React5.createElement(Form, {
|
|
594
|
-
schema,
|
|
595
|
-
path: [
|
|
596
|
-
...key,
|
|
597
|
-
index.toString()
|
|
598
|
-
],
|
|
599
|
-
values: value,
|
|
600
|
-
onValuesChanged: (childValues) => {
|
|
601
|
-
const newValues = [
|
|
602
|
-
...arrayValues
|
|
603
|
-
];
|
|
604
|
-
newValues[index] = childValues;
|
|
605
|
-
inputProps.onValueChange(name, "object", newValues);
|
|
606
|
-
},
|
|
607
|
-
Custom
|
|
608
|
-
})), /* @__PURE__ */ React5.createElement(IconButton, {
|
|
609
|
-
icon: "ph--trash--regular",
|
|
610
|
-
iconOnly: true,
|
|
611
|
-
label: t("button remove"),
|
|
612
|
-
onClick: () => {
|
|
613
|
-
const newValues = arrayValues.filter((_, i) => i !== index);
|
|
614
|
-
inputProps.onValueChange(name, type, newValues);
|
|
615
|
-
}
|
|
616
|
-
}));
|
|
617
|
-
})), /* @__PURE__ */ React5.createElement("div", {
|
|
618
|
-
role: "none",
|
|
619
|
-
className: "flex justify-between items-center plb-1"
|
|
620
|
-
}, /* @__PURE__ */ React5.createElement(IconButton, {
|
|
621
|
-
icon: "ph--plus--regular",
|
|
622
|
-
iconOnly: true,
|
|
623
|
-
label: t("button add"),
|
|
624
|
-
onClick: () => {
|
|
625
|
-
const newValues = [
|
|
626
|
-
...arrayValues,
|
|
627
|
-
{}
|
|
628
|
-
];
|
|
629
|
-
inputProps.onValueChange(name, type, newValues);
|
|
630
|
-
}
|
|
631
|
-
})));
|
|
632
|
-
}
|
|
633
|
-
return /* @__PURE__ */ React5.createElement("div", {
|
|
634
|
-
key: name,
|
|
635
|
-
role: "none"
|
|
636
|
-
}, "Nested form not supported in arrays, yet.");
|
|
637
|
-
}
|
|
638
|
-
const InputComponent = getInputComponent(type, format);
|
|
639
|
-
if (!InputComponent) {
|
|
563
|
+
if (!elementType) {
|
|
640
564
|
return null;
|
|
641
565
|
}
|
|
642
|
-
return /* @__PURE__ */
|
|
566
|
+
return /* @__PURE__ */ React8.createElement("div", {
|
|
643
567
|
role: "none",
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
}, /* @__PURE__ */ React5.createElement(InputHeader, null, label), /* @__PURE__ */ React5.createElement("div", {
|
|
568
|
+
className: mx3(padding)
|
|
569
|
+
}, /* @__PURE__ */ React8.createElement(InputHeader, null, label), /* @__PURE__ */ React8.createElement("div", {
|
|
647
570
|
role: "none",
|
|
648
571
|
className: "flex flex-col gap-1"
|
|
649
|
-
},
|
|
572
|
+
}, values.map((_value, index) => /* @__PURE__ */ React8.createElement("div", {
|
|
650
573
|
key: index,
|
|
651
574
|
role: "none",
|
|
652
|
-
className: "flex items-
|
|
653
|
-
}, /* @__PURE__ */
|
|
575
|
+
className: "flex items-center gap-1"
|
|
576
|
+
}, /* @__PURE__ */ React8.createElement("div", {
|
|
654
577
|
role: "none",
|
|
655
578
|
className: "flex-1"
|
|
656
|
-
}, /* @__PURE__ */
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
579
|
+
}, /* @__PURE__ */ React8.createElement(FormField, {
|
|
580
|
+
property: {
|
|
581
|
+
...property,
|
|
582
|
+
array: false,
|
|
583
|
+
ast: elementType
|
|
584
|
+
},
|
|
585
|
+
path: [
|
|
586
|
+
...path ?? [],
|
|
587
|
+
index
|
|
588
|
+
],
|
|
589
|
+
readonly,
|
|
590
|
+
inline: true,
|
|
591
|
+
Custom,
|
|
592
|
+
lookupComponent
|
|
593
|
+
})), /* @__PURE__ */ React8.createElement(IconButton2, {
|
|
666
594
|
icon: "ph--trash--regular",
|
|
667
595
|
iconOnly: true,
|
|
668
596
|
label: t("button remove"),
|
|
669
|
-
onClick: () =>
|
|
670
|
-
|
|
671
|
-
inputProps.onValueChange(name, type, newValues);
|
|
672
|
-
}
|
|
673
|
-
})))), /* @__PURE__ */ React5.createElement("div", {
|
|
597
|
+
onClick: () => handleRemove(index)
|
|
598
|
+
})))), /* @__PURE__ */ React8.createElement("div", {
|
|
674
599
|
role: "none",
|
|
675
600
|
className: "flex justify-between items-center plb-1"
|
|
676
|
-
}, /* @__PURE__ */
|
|
601
|
+
}, /* @__PURE__ */ React8.createElement(IconButton2, {
|
|
677
602
|
icon: "ph--plus--regular",
|
|
678
603
|
iconOnly: true,
|
|
679
604
|
label: t("button add"),
|
|
680
|
-
onClick:
|
|
681
|
-
const newValues = [
|
|
682
|
-
...arrayValues,
|
|
683
|
-
SimpleType.getDefaultValue(type)
|
|
684
|
-
];
|
|
685
|
-
inputProps.onValueChange(name, type, newValues);
|
|
686
|
-
}
|
|
605
|
+
onClick: handleAdd
|
|
687
606
|
})));
|
|
688
607
|
};
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
608
|
+
|
|
609
|
+
// packages/ui/react-ui-form/src/components/Form/factory.tsx
|
|
610
|
+
import { FormatEnum } from "@dxos/echo-schema";
|
|
611
|
+
var getInputComponent = (type, format) => {
|
|
612
|
+
switch (format) {
|
|
613
|
+
case FormatEnum.LatLng:
|
|
614
|
+
return GeoPointInput;
|
|
615
|
+
}
|
|
616
|
+
switch (type) {
|
|
617
|
+
case "string":
|
|
618
|
+
return TextInput;
|
|
619
|
+
case "number":
|
|
620
|
+
return NumberInput;
|
|
621
|
+
case "boolean":
|
|
622
|
+
return BooleanInput;
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
// packages/ui/react-ui-form/src/components/Form/FormContent.tsx
|
|
627
|
+
var FormField = ({ property, path, readonly, inline, lookupComponent, Custom }) => {
|
|
628
|
+
const inputProps = useInputProps(path);
|
|
629
|
+
const { ast, name, type, format, title, description, options, examples, array } = property;
|
|
630
|
+
const label = useMemo3(() => title ?? pipe2(name, capitalize2), [
|
|
631
|
+
title,
|
|
632
|
+
name
|
|
633
|
+
]);
|
|
634
|
+
const placeholder = useMemo3(() => examples?.length ? `Example: "${examples[0]}"` : description, [
|
|
635
|
+
examples,
|
|
636
|
+
description
|
|
637
|
+
]);
|
|
638
|
+
if (array) {
|
|
639
|
+
return /* @__PURE__ */ React9.createElement(ArrayField, {
|
|
640
|
+
property,
|
|
641
|
+
path,
|
|
642
|
+
inputProps,
|
|
643
|
+
readonly,
|
|
644
|
+
Custom
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
const FoundComponent = lookupComponent?.({
|
|
648
|
+
prop: name,
|
|
649
|
+
schema: S.make(ast),
|
|
650
|
+
inputProps: {
|
|
651
|
+
type,
|
|
652
|
+
format,
|
|
653
|
+
label,
|
|
654
|
+
disabled: readonly,
|
|
655
|
+
placeholder,
|
|
656
|
+
...inputProps
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
if (FoundComponent) {
|
|
660
|
+
return /* @__PURE__ */ React9.createElement("div", null, FoundComponent);
|
|
661
|
+
}
|
|
662
|
+
const jsonPath = createJsonPath3(path ?? []);
|
|
663
|
+
const InputComponent = Custom?.[jsonPath] || getInputComponent(type, format);
|
|
664
|
+
if (InputComponent) {
|
|
665
|
+
return /* @__PURE__ */ React9.createElement("div", null, /* @__PURE__ */ React9.createElement(InputComponent, {
|
|
666
|
+
type,
|
|
667
|
+
format,
|
|
668
|
+
label,
|
|
669
|
+
inputOnly: inline,
|
|
670
|
+
placeholder,
|
|
671
|
+
disabled: readonly,
|
|
672
|
+
...inputProps
|
|
673
|
+
}));
|
|
674
|
+
}
|
|
675
|
+
if (options) {
|
|
676
|
+
return /* @__PURE__ */ React9.createElement("div", {
|
|
677
|
+
role: "none"
|
|
678
|
+
}, /* @__PURE__ */ React9.createElement(SelectInput, {
|
|
679
|
+
type,
|
|
680
|
+
format,
|
|
681
|
+
disabled: readonly,
|
|
682
|
+
inputOnly: inline,
|
|
683
|
+
label,
|
|
684
|
+
options: options.map((option) => ({
|
|
685
|
+
value: option,
|
|
686
|
+
label: String(option)
|
|
687
|
+
})),
|
|
688
|
+
placeholder,
|
|
689
|
+
...inputProps
|
|
690
|
+
}));
|
|
691
|
+
}
|
|
692
|
+
if (type === "object") {
|
|
693
|
+
const baseNode = findNode2(ast, isDiscriminatedUnion2);
|
|
694
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, inputProps.getValue()) : findNode2(ast, AST3.isTypeLiteral);
|
|
695
|
+
if (typeLiteral) {
|
|
696
|
+
return /* @__PURE__ */ React9.createElement("div", null, !inline && /* @__PURE__ */ React9.createElement("div", null, label), /* @__PURE__ */ React9.createElement(FormFields, {
|
|
697
|
+
schema: S.make(typeLiteral),
|
|
698
|
+
path,
|
|
699
|
+
readonly,
|
|
700
|
+
Custom
|
|
701
|
+
}));
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
return null;
|
|
705
|
+
};
|
|
706
|
+
var FormFields = ({ schema, path, filter, sort, readonly, lookupComponent, Custom }) => {
|
|
707
|
+
const values = useFormValues(path);
|
|
708
|
+
const properties = useMemo3(() => {
|
|
709
|
+
const props = getSchemaProperties2(schema.ast, values);
|
|
710
|
+
const filtered = filter ? filter(props) : props;
|
|
711
|
+
return sort ? filtered.sort((a, b) => sort.indexOf(a.name) - sort.indexOf(b.name)) : filtered;
|
|
712
|
+
}, [
|
|
713
|
+
schema,
|
|
714
|
+
values,
|
|
715
|
+
filter,
|
|
716
|
+
sort
|
|
717
|
+
]);
|
|
718
|
+
return /* @__PURE__ */ React9.createElement("div", {
|
|
719
|
+
role: "form",
|
|
720
|
+
className: mx4("flex flex-col w-full gap-2 py-2")
|
|
721
|
+
}, properties.map((property) => {
|
|
722
|
+
return /* @__PURE__ */ React9.createElement(FormField, {
|
|
723
|
+
key: property.name,
|
|
724
|
+
property,
|
|
725
|
+
path: [
|
|
726
|
+
...path ?? [],
|
|
727
|
+
property.name
|
|
728
|
+
],
|
|
729
|
+
readonly,
|
|
730
|
+
lookupComponent,
|
|
731
|
+
Custom
|
|
732
|
+
});
|
|
733
|
+
}).filter(isNotFalsy));
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
// packages/ui/react-ui-form/src/components/Form/Form.tsx
|
|
737
|
+
var Form = ({ classNames, schema, values: initialValues, path = [], readonly, filter, sort, autoSave, testId, onValuesChanged, onValidate, onSave, onCancel, lookupComponent, Custom }) => {
|
|
738
|
+
const onValid = useMemo4(() => autoSave ? onSave : void 0, [
|
|
739
|
+
autoSave,
|
|
740
|
+
onSave
|
|
741
|
+
]);
|
|
742
|
+
return /* @__PURE__ */ React10.createElement(FormProvider, {
|
|
743
|
+
schema,
|
|
744
|
+
initialValues,
|
|
745
|
+
onValuesChanged,
|
|
746
|
+
onValidate,
|
|
747
|
+
onValid,
|
|
748
|
+
onSave
|
|
749
|
+
}, /* @__PURE__ */ React10.createElement("div", {
|
|
695
750
|
role: "none",
|
|
696
|
-
className:
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
751
|
+
className: mx5("p-2", classNames),
|
|
752
|
+
"data-testid": testId
|
|
753
|
+
}, /* @__PURE__ */ React10.createElement(FormFields, {
|
|
754
|
+
schema,
|
|
755
|
+
path,
|
|
756
|
+
readonly,
|
|
757
|
+
filter,
|
|
758
|
+
sort,
|
|
759
|
+
lookupComponent,
|
|
760
|
+
Custom
|
|
761
|
+
}), (onCancel || onSave) && !autoSave && /* @__PURE__ */ React10.createElement(FormActions, {
|
|
762
|
+
onCancel,
|
|
763
|
+
readonly
|
|
709
764
|
})));
|
|
710
765
|
};
|
|
711
766
|
|
|
712
767
|
// packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx
|
|
713
768
|
var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
714
769
|
var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
715
|
-
const { t } =
|
|
770
|
+
const { t } = useTranslation4(translationKey);
|
|
716
771
|
const [props, setProps] = useState2(projection.getFieldProjection(field.id).props);
|
|
717
|
-
|
|
772
|
+
useEffect2(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
718
773
|
field,
|
|
719
774
|
projection
|
|
720
775
|
]);
|
|
721
776
|
const [schemas, setSchemas] = useState2([]);
|
|
722
|
-
|
|
777
|
+
useEffect2(() => {
|
|
723
778
|
if (!registry) {
|
|
724
779
|
return;
|
|
725
780
|
}
|
|
726
|
-
const subscription = registry.subscribe(setSchemas)
|
|
781
|
+
const subscription = registry.query().subscribe((query) => setSchemas(query.results), {
|
|
782
|
+
fire: true
|
|
783
|
+
});
|
|
727
784
|
const t2 = setTimeout(async () => {
|
|
728
|
-
const schemas2 = await registry.query();
|
|
785
|
+
const schemas2 = await registry.query().run();
|
|
729
786
|
setSchemas(schemas2);
|
|
730
787
|
});
|
|
731
788
|
return () => {
|
|
@@ -735,9 +792,9 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
735
792
|
}, [
|
|
736
793
|
registry
|
|
737
794
|
]);
|
|
738
|
-
const [
|
|
739
|
-
|
|
740
|
-
|
|
795
|
+
const [referenceSchema, setReferenceSchema] = useState2();
|
|
796
|
+
useEffect2(() => {
|
|
797
|
+
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
741
798
|
}, [
|
|
742
799
|
schemas,
|
|
743
800
|
props?.referenceSchema
|
|
@@ -745,15 +802,25 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
745
802
|
const [{ fieldSchema }, setFieldSchema] = useState2({
|
|
746
803
|
fieldSchema: getFormatSchema(props?.format)
|
|
747
804
|
});
|
|
748
|
-
const handleValuesChanged =
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
805
|
+
const handleValuesChanged = useCallback3((_props) => {
|
|
806
|
+
setFieldSchema((prev) => {
|
|
807
|
+
const fieldSchema2 = getFormatSchema(_props.format);
|
|
808
|
+
if (prev.fieldSchema === fieldSchema2) {
|
|
809
|
+
return prev;
|
|
810
|
+
}
|
|
811
|
+
return {
|
|
812
|
+
fieldSchema: fieldSchema2
|
|
813
|
+
};
|
|
814
|
+
});
|
|
815
|
+
setReferenceSchema((prev) => {
|
|
816
|
+
if (_props.referenceSchema !== prev?.typename) {
|
|
817
|
+
const newSchema = schemas.find((schema) => schema.typename === _props.referenceSchema);
|
|
818
|
+
if (newSchema) {
|
|
819
|
+
return newSchema;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
return prev;
|
|
823
|
+
});
|
|
757
824
|
setProps((props2) => {
|
|
758
825
|
const type = formatToType[_props.format];
|
|
759
826
|
if (props2.type !== type) {
|
|
@@ -767,9 +834,10 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
767
834
|
});
|
|
768
835
|
}, [
|
|
769
836
|
schemas,
|
|
770
|
-
props
|
|
837
|
+
props.format,
|
|
838
|
+
props.referenceSchema
|
|
771
839
|
]);
|
|
772
|
-
const handleValidate =
|
|
840
|
+
const handleValidate = useCallback3(({ property }) => {
|
|
773
841
|
if (property && view.fields.find((f) => f.path === property && f.path !== field.path)) {
|
|
774
842
|
return [
|
|
775
843
|
{
|
|
@@ -782,7 +850,7 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
782
850
|
view.fields,
|
|
783
851
|
field
|
|
784
852
|
]);
|
|
785
|
-
const handleSave =
|
|
853
|
+
const handleSave = useCallback3((props2) => {
|
|
786
854
|
projection.setFieldProjection({
|
|
787
855
|
field,
|
|
788
856
|
props: props2
|
|
@@ -793,29 +861,55 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
793
861
|
field,
|
|
794
862
|
onSave
|
|
795
863
|
]);
|
|
796
|
-
const handleCancel =
|
|
864
|
+
const handleCancel = useCallback3(() => {
|
|
797
865
|
requestAnimationFrame(() => onCancel?.());
|
|
798
866
|
onSave();
|
|
799
867
|
}, [
|
|
800
868
|
onSave
|
|
801
869
|
]);
|
|
870
|
+
const Custom = useMemo5(() => ({
|
|
871
|
+
["format"]: (props2) => /* @__PURE__ */ React11.createElement(SelectInput, {
|
|
872
|
+
...props2,
|
|
873
|
+
options: FormatEnums.filter((value) => value !== FormatEnum2.None).map((value) => ({
|
|
874
|
+
value,
|
|
875
|
+
label: t(`format ${value}`)
|
|
876
|
+
}))
|
|
877
|
+
}),
|
|
878
|
+
["referenceSchema"]: (props2) => /* @__PURE__ */ React11.createElement(SelectInput, {
|
|
879
|
+
...props2,
|
|
880
|
+
options: schemas.map((schema) => ({
|
|
881
|
+
value: schema.typename
|
|
882
|
+
}))
|
|
883
|
+
}),
|
|
884
|
+
["referencePath"]: (props2) => /* @__PURE__ */ React11.createElement(SelectInput, {
|
|
885
|
+
...props2,
|
|
886
|
+
options: referenceSchema ? getSchemaProperties3(referenceSchema.ast).sort(sortProperties).map((p) => ({
|
|
887
|
+
value: p.name
|
|
888
|
+
})) : []
|
|
889
|
+
})
|
|
890
|
+
}), [
|
|
891
|
+
t,
|
|
892
|
+
schemas,
|
|
893
|
+
referenceSchema
|
|
894
|
+
]);
|
|
895
|
+
const propIsNotType = useCallback3((props2) => props2.filter((p) => p.name !== "type"), []);
|
|
802
896
|
if (!fieldSchema) {
|
|
803
|
-
|
|
897
|
+
log2.warn("invalid format", {
|
|
804
898
|
props
|
|
805
899
|
}, {
|
|
806
900
|
F: __dxlog_file3,
|
|
807
|
-
L:
|
|
901
|
+
L: 173,
|
|
808
902
|
S: void 0,
|
|
809
903
|
C: (f, a) => f(...a)
|
|
810
904
|
});
|
|
811
905
|
return null;
|
|
812
906
|
}
|
|
813
|
-
return /* @__PURE__ */
|
|
907
|
+
return /* @__PURE__ */ React11.createElement(Form, {
|
|
814
908
|
key: field.id,
|
|
815
909
|
autoFocus: true,
|
|
816
910
|
values: props,
|
|
817
911
|
schema: fieldSchema,
|
|
818
|
-
filter:
|
|
912
|
+
filter: propIsNotType,
|
|
819
913
|
sort: [
|
|
820
914
|
"property",
|
|
821
915
|
"format"
|
|
@@ -824,55 +918,35 @@ var FieldEditor = ({ view, projection, field, registry, onSave, onCancel }) => {
|
|
|
824
918
|
onValidate: handleValidate,
|
|
825
919
|
onSave: handleSave,
|
|
826
920
|
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
|
-
}
|
|
921
|
+
Custom
|
|
848
922
|
});
|
|
849
923
|
};
|
|
850
924
|
|
|
851
925
|
// packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx
|
|
852
|
-
import
|
|
853
|
-
import { AST as
|
|
854
|
-
import { IconButton as
|
|
926
|
+
import React12, { useCallback as useCallback4, useMemo as useMemo6, useState as useState3 } from "react";
|
|
927
|
+
import { AST as AST4, Format, S as S2 } from "@dxos/echo-schema";
|
|
928
|
+
import { IconButton as IconButton3, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
855
929
|
import { List } from "@dxos/react-ui-list";
|
|
856
|
-
import { ghostHover, inputTextLabel, mx as
|
|
930
|
+
import { ghostHover, inputTextLabel, mx as mx6 } from "@dxos/react-ui-theme";
|
|
857
931
|
import { FieldSchema, ViewProjection, VIEW_FIELD_LIMIT } from "@dxos/schema";
|
|
858
932
|
import { arrayMove } from "@dxos/util";
|
|
859
933
|
var grid = "grid grid-cols-[32px_1fr_32px] min-bs-[2.5rem]";
|
|
860
934
|
var ViewMetaSchema = S2.Struct({
|
|
861
935
|
name: S2.String.annotations({
|
|
862
|
-
[
|
|
936
|
+
[AST4.TitleAnnotationId]: "View"
|
|
863
937
|
}),
|
|
864
938
|
typename: Format.DXN.annotations({
|
|
865
|
-
[
|
|
939
|
+
[AST4.TitleAnnotationId]: "Typename"
|
|
866
940
|
})
|
|
867
941
|
}).pipe(S2.mutable);
|
|
868
|
-
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onDelete }) => {
|
|
869
|
-
const { t } =
|
|
870
|
-
const projection =
|
|
942
|
+
var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading = false, onTypenameChanged, onDelete }) => {
|
|
943
|
+
const { t } = useTranslation5(translationKey);
|
|
944
|
+
const projection = useMemo6(() => new ViewProjection(schema, view), [
|
|
871
945
|
schema,
|
|
872
946
|
view
|
|
873
947
|
]);
|
|
874
948
|
const [field, setField] = useState3();
|
|
875
|
-
const viewValues =
|
|
949
|
+
const viewValues = useMemo6(() => {
|
|
876
950
|
return {
|
|
877
951
|
name: view.name,
|
|
878
952
|
// TODO(burdon): Need to warn user of possible consequences of editing.
|
|
@@ -882,77 +956,81 @@ var ViewEditor = ({ classNames, schema, view, registry, readonly, showHeading =
|
|
|
882
956
|
}, [
|
|
883
957
|
view
|
|
884
958
|
]);
|
|
885
|
-
const handleViewUpdate =
|
|
959
|
+
const handleViewUpdate = useCallback4(({ name, typename }) => {
|
|
886
960
|
requestAnimationFrame(() => {
|
|
887
|
-
view.name
|
|
888
|
-
|
|
889
|
-
|
|
961
|
+
if (view.name !== name) {
|
|
962
|
+
view.name = name;
|
|
963
|
+
}
|
|
964
|
+
if (view.query.type !== typename) {
|
|
965
|
+
onTypenameChanged(typename);
|
|
966
|
+
}
|
|
890
967
|
});
|
|
891
968
|
}, [
|
|
892
969
|
view,
|
|
893
|
-
schema
|
|
970
|
+
schema,
|
|
971
|
+
onTypenameChanged
|
|
894
972
|
]);
|
|
895
|
-
const handleSelect =
|
|
973
|
+
const handleSelect = useCallback4((field2) => {
|
|
896
974
|
setField((f) => f === field2 ? void 0 : field2);
|
|
897
975
|
}, []);
|
|
898
|
-
const handleAdd =
|
|
976
|
+
const handleAdd = useCallback4(() => {
|
|
899
977
|
const field2 = projection.createFieldProjection();
|
|
900
978
|
setField(field2);
|
|
901
979
|
}, [
|
|
902
980
|
view
|
|
903
981
|
]);
|
|
904
|
-
const handleMove =
|
|
982
|
+
const handleMove = useCallback4((fromIndex, toIndex) => {
|
|
905
983
|
arrayMove(view.fields, fromIndex, toIndex);
|
|
906
984
|
}, [
|
|
907
985
|
view.fields
|
|
908
986
|
]);
|
|
909
|
-
const handleClose =
|
|
910
|
-
return /* @__PURE__ */
|
|
987
|
+
const handleClose = useCallback4(() => setField(void 0), []);
|
|
988
|
+
return /* @__PURE__ */ React12.createElement("div", {
|
|
911
989
|
role: "none",
|
|
912
|
-
className:
|
|
913
|
-
}, /* @__PURE__ */
|
|
990
|
+
className: mx6("flex flex-col w-full divide-y divide-separator", classNames)
|
|
991
|
+
}, /* @__PURE__ */ React12.createElement(Form, {
|
|
914
992
|
autoFocus: true,
|
|
915
993
|
autoSave: true,
|
|
916
994
|
schema: ViewMetaSchema,
|
|
917
995
|
values: viewValues,
|
|
918
996
|
onSave: handleViewUpdate
|
|
919
|
-
}), /* @__PURE__ */
|
|
997
|
+
}), /* @__PURE__ */ React12.createElement("div", null, /* @__PURE__ */ React12.createElement("div", {
|
|
920
998
|
role: "none",
|
|
921
999
|
className: "p-2"
|
|
922
|
-
}, /* @__PURE__ */
|
|
923
|
-
className:
|
|
924
|
-
}, t("fields label"))), /* @__PURE__ */
|
|
1000
|
+
}, /* @__PURE__ */ React12.createElement("label", {
|
|
1001
|
+
className: mx6(inputTextLabel)
|
|
1002
|
+
}, t("fields label"))), /* @__PURE__ */ React12.createElement(List.Root, {
|
|
925
1003
|
items: view.fields,
|
|
926
1004
|
isItem: S2.is(FieldSchema),
|
|
927
1005
|
getId: (field2) => field2.id,
|
|
928
1006
|
onMove: handleMove
|
|
929
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
1007
|
+
}, ({ items: fields }) => /* @__PURE__ */ React12.createElement(React12.Fragment, null, showHeading && /* @__PURE__ */ React12.createElement("div", {
|
|
930
1008
|
role: "heading",
|
|
931
1009
|
className: grid
|
|
932
|
-
}, /* @__PURE__ */
|
|
1010
|
+
}, /* @__PURE__ */ React12.createElement("div", null), /* @__PURE__ */ React12.createElement("div", {
|
|
933
1011
|
className: "flex items-center text-sm"
|
|
934
|
-
}, t("field path label"))), /* @__PURE__ */
|
|
1012
|
+
}, t("field path label"))), /* @__PURE__ */ React12.createElement("div", {
|
|
935
1013
|
role: "list",
|
|
936
1014
|
className: "flex flex-col w-full"
|
|
937
|
-
}, fields?.map((field2) => /* @__PURE__ */
|
|
1015
|
+
}, fields?.map((field2) => /* @__PURE__ */ React12.createElement(List.Item, {
|
|
938
1016
|
key: field2.id,
|
|
939
1017
|
item: field2,
|
|
940
|
-
classNames:
|
|
941
|
-
}, /* @__PURE__ */
|
|
1018
|
+
classNames: mx6(grid, ghostHover, "cursor-pointer")
|
|
1019
|
+
}, /* @__PURE__ */ React12.createElement(List.ItemDragHandle, null), /* @__PURE__ */ React12.createElement(List.ItemTitle, {
|
|
942
1020
|
onClick: () => handleSelect(field2)
|
|
943
|
-
}, field2.path), /* @__PURE__ */
|
|
1021
|
+
}, field2.path), /* @__PURE__ */ React12.createElement(List.ItemDeleteButton, {
|
|
944
1022
|
disabled: view.fields.length <= 1,
|
|
945
1023
|
onClick: () => onDelete(field2.id)
|
|
946
|
-
}))))))), field && /* @__PURE__ */
|
|
1024
|
+
}))))))), field && /* @__PURE__ */ React12.createElement(FieldEditor, {
|
|
947
1025
|
key: field.id,
|
|
948
1026
|
view,
|
|
949
1027
|
projection,
|
|
950
1028
|
field,
|
|
951
1029
|
registry,
|
|
952
1030
|
onSave: handleClose
|
|
953
|
-
}), !readonly && !field && /* @__PURE__ */
|
|
1031
|
+
}), !readonly && !field && /* @__PURE__ */ React12.createElement("div", {
|
|
954
1032
|
className: "flex p-2 justify-center"
|
|
955
|
-
}, /* @__PURE__ */
|
|
1033
|
+
}, /* @__PURE__ */ React12.createElement(IconButton3, {
|
|
956
1034
|
icon: "ph--plus--regular",
|
|
957
1035
|
label: t("button add property"),
|
|
958
1036
|
onClick: handleAdd,
|
|
@@ -1185,12 +1263,12 @@ export {
|
|
|
1185
1263
|
DeprecatedFormInput,
|
|
1186
1264
|
FieldEditor,
|
|
1187
1265
|
Form,
|
|
1188
|
-
|
|
1189
|
-
GeiPointInput,
|
|
1266
|
+
GeoPointInput,
|
|
1190
1267
|
InputHeader,
|
|
1191
1268
|
NumberInput,
|
|
1192
1269
|
SelectInput,
|
|
1193
1270
|
TextInput,
|
|
1271
|
+
TupleInput,
|
|
1194
1272
|
ViewEditor,
|
|
1195
1273
|
cellClassesForFieldType,
|
|
1196
1274
|
cellClassesForRowSelection,
|