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