@dxos/react-ui-form 0.8.4-main.74a063c4e0 → 0.8.4-main.765dc60934
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/LICENSE +102 -5
- package/dist/lib/browser/index.mjs +873 -446
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/translations.mjs +82 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +873 -446
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/translations.mjs +84 -0
- package/dist/lib/node-esm/translations.mjs.map +7 -0
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +63 -61
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +34 -12
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +73 -71
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormField.d.ts +5 -5
- package/dist/types/src/components/Form/FormField.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormFieldComponent.d.ts +8 -6
- package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormFieldSet.d.ts +5 -8
- package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/ArrayField.d.ts +4 -4
- package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/MarkdownField.d.ts +8 -1
- package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts +84 -0
- package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/RefField.d.ts +10 -4
- package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +63 -61
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TextField.d.ts +1 -1
- package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -1
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +9 -0
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
- package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
- package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +17 -3
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +63 -61
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
- package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +127 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts +2 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
- package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
- package/dist/types/src/components/Settings/Settings.d.ts +24 -12
- package/dist/types/src/components/Settings/Settings.d.ts.map +1 -1
- package/dist/types/src/components/Settings/Settings.stories.d.ts +64 -61
- package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -1
- package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +43 -0
- package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
- package/dist/types/src/components/Settings/SettingsItem.d.ts +16 -0
- package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
- package/dist/types/src/components/Settings/SettingsSelectField.d.ts +18 -0
- package/dist/types/src/components/Settings/SettingsSelectField.d.ts.map +1 -0
- package/dist/types/src/components/Settings/index.d.ts +2 -0
- package/dist/types/src/components/Settings/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +3 -4
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +63 -61
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +2 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +4 -4
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -1
- package/dist/types/src/hooks/useKeyHandler.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +0 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +63 -61
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/util/field-type.d.ts +19 -0
- package/dist/types/src/util/field-type.d.ts.map +1 -0
- package/dist/types/src/util/field.d.ts.map +1 -1
- package/dist/types/src/util/formatting.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -0
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/properties.d.ts.map +1 -1
- package/dist/types/src/util/refs.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +40 -38
- package/src/components/FieldEditor/FieldEditor.stories.tsx +2 -1
- package/src/components/FieldEditor/FieldEditor.tsx +3 -2
- package/src/components/Form/Form.stories.tsx +9 -19
- package/src/components/Form/Form.tsx +59 -7
- package/src/components/Form/FormField.tsx +12 -10
- package/src/components/Form/FormFieldComponent.tsx +6 -3
- package/src/components/Form/FormFieldSet.tsx +47 -31
- package/src/components/Form/fields/ArrayField.tsx +7 -6
- package/src/components/Form/fields/GeoPointField.tsx +3 -2
- package/src/components/Form/fields/MarkdownField.stories.tsx +206 -0
- package/src/components/Form/fields/MarkdownField.tsx +135 -45
- package/src/components/Form/fields/RefField.tsx +61 -30
- package/src/components/Form/fields/SelectOptionField.stories.tsx +8 -5
- package/src/components/Form/fields/SelectOptionField.tsx +6 -5
- package/src/components/Form/fields/TextField.tsx +2 -2
- package/src/components/ObjectForm/ObjectForm.tsx +114 -0
- package/src/components/ObjectForm/index.ts +5 -0
- package/src/components/ObjectPicker/ObjectPicker.stories.tsx +9 -6
- package/src/components/ObjectPicker/ObjectPicker.tsx +28 -12
- package/src/components/ObjectProperties/ObjectProperties.stories.tsx +362 -0
- package/src/components/ObjectProperties/ObjectProperties.test.tsx +101 -0
- package/src/components/ObjectProperties/ObjectProperties.tsx +141 -0
- package/src/components/ObjectProperties/index.ts +5 -0
- package/src/components/Settings/AUDIT.md +52 -0
- package/src/components/Settings/Settings.stories.tsx +50 -1
- package/src/components/Settings/Settings.tsx +7 -56
- package/src/components/Settings/SettingsFieldSet.tsx +257 -0
- package/src/components/Settings/SettingsItem.tsx +58 -0
- package/src/components/Settings/SettingsSelectField.tsx +59 -0
- package/src/components/Settings/index.ts +2 -0
- package/src/components/ViewEditor/ViewEditor.stories.tsx +10 -10
- package/src/components/ViewEditor/ViewEditor.tsx +19 -26
- package/src/components/index.ts +2 -0
- package/src/components/testing.tsx +20 -21
- package/src/index.ts +0 -4
- package/src/translations.ts +7 -3
- package/src/util/field-type.ts +60 -0
- package/src/util/index.ts +1 -0
|
@@ -1,88 +1,13 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
2
|
|
|
3
|
-
// src/translations.ts
|
|
4
|
-
var translationKey = "@dxos/react-ui-form";
|
|
5
|
-
var translations = [
|
|
6
|
-
{
|
|
7
|
-
"en-US": {
|
|
8
|
-
[translationKey]: {
|
|
9
|
-
"fields.label": "Fields",
|
|
10
|
-
"hidden-fields.label": "Hidden Fields",
|
|
11
|
-
"empty-readonly-ref-field.label": "(none)",
|
|
12
|
-
"add-property-button.label": "Add property",
|
|
13
|
-
"field-property.label": "Property",
|
|
14
|
-
"field-property.placeholder": "Property name",
|
|
15
|
-
"field-format.label": "Type",
|
|
16
|
-
"field-path.label": "Field path",
|
|
17
|
-
"add-field.button": "Add field",
|
|
18
|
-
"boolean-input-true.value": "Yes",
|
|
19
|
-
"boolean-input-false.value": "No",
|
|
20
|
-
"show-field.label": "Show field",
|
|
21
|
-
"hide-field.label": "Hide field",
|
|
22
|
-
"delete-field.label": "Delete field",
|
|
23
|
-
"ref-field-combobox-input.placeholder": "Search\u2026",
|
|
24
|
-
"ref-field.placeholder": "Select\u2026",
|
|
25
|
-
"ref-field.placeholder_one": "Select\u2026",
|
|
26
|
-
"ref-field.placeholder_other": "Select items\u2026",
|
|
27
|
-
"create-option.label": "Create",
|
|
28
|
-
"example.placeholder": "Example",
|
|
29
|
-
"latitude.placeholder": "Latitude (e.g., 40.7128)",
|
|
30
|
-
"longitude.placeholder": "Longitude (e.g., -74.0060)",
|
|
31
|
-
"cancel-button.label": "Cancel",
|
|
32
|
-
"save-button.label": "Save",
|
|
33
|
-
// TypeFormat
|
|
34
|
-
"format.boolean.label": "Boolean",
|
|
35
|
-
"format.currency.label": "Currency",
|
|
36
|
-
"format.date.label": "Date",
|
|
37
|
-
"format.date-time.label": "DateTime",
|
|
38
|
-
"format.did.label": "DID",
|
|
39
|
-
"format.duration.label": "Duration",
|
|
40
|
-
"format.dxn.label": "DXN",
|
|
41
|
-
"format.email.label": "Email",
|
|
42
|
-
"format.formula.label": "Formula",
|
|
43
|
-
"format.hostname.label": "Hostname",
|
|
44
|
-
"format.integer.label": "Integer",
|
|
45
|
-
"format.json.label": "JSON",
|
|
46
|
-
"format.lnglat.label": "Geopoint",
|
|
47
|
-
"format.markdown.label": "Markdown",
|
|
48
|
-
"format.percent.label": "Percent",
|
|
49
|
-
"format.ref.label": "Reference",
|
|
50
|
-
"format.regex.label": "RegExp",
|
|
51
|
-
"format.string.label": "String",
|
|
52
|
-
"format.single-select.label": "Select",
|
|
53
|
-
"format.multi-select.label": "Multi-select",
|
|
54
|
-
"format.text.label": "Long text",
|
|
55
|
-
"format.time.label": "Time",
|
|
56
|
-
"format.timestamp.label": "Timestamp",
|
|
57
|
-
"format.user.label": "User",
|
|
58
|
-
"format.number.label": "Number",
|
|
59
|
-
"format.uri.label": "URI",
|
|
60
|
-
"format.url.label": "URL",
|
|
61
|
-
"format.uuid.label": "UUID",
|
|
62
|
-
// GeoPointField.
|
|
63
|
-
"latitude.label": "Latitude",
|
|
64
|
-
"longitude.label": "Longitude",
|
|
65
|
-
// SelectOptionsField.
|
|
66
|
-
"select-option.label": "Label",
|
|
67
|
-
"select-option-label.placeholder": "Option label",
|
|
68
|
-
"select-option-delete.button": "Delete",
|
|
69
|
-
"select-option-add.button": "Add option",
|
|
70
|
-
// System schema message.
|
|
71
|
-
"system-schema.title": "System type",
|
|
72
|
-
"system-schema.description": "System type: cannot add or remove fields.",
|
|
73
|
-
"remove.button": "Remove"
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
];
|
|
78
|
-
|
|
79
3
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
80
|
-
import React17, { useCallback as useCallback14, useEffect as
|
|
81
|
-
import { Obj as
|
|
4
|
+
import React17, { useCallback as useCallback14, useEffect as useEffect5, useMemo as useMemo8, useState as useState6 } from "react";
|
|
5
|
+
import { Obj as Obj3 } from "@dxos/echo";
|
|
82
6
|
import { Format as Format4, FormatEnums, formatToType } from "@dxos/echo/internal";
|
|
83
7
|
import { log as log2 } from "@dxos/log";
|
|
84
|
-
import { useAsyncEffect, useTranslation as
|
|
8
|
+
import { useAsyncEffect, useTranslation as useTranslation9 } from "@dxos/react-ui";
|
|
85
9
|
import { formatToAdditionalPropertyAttributes, getFormatSchema } from "@dxos/schema";
|
|
10
|
+
import { translationKey as translationKey9 } from "#translations";
|
|
86
11
|
|
|
87
12
|
// src/util/field.ts
|
|
88
13
|
import { Format, GeoLocation, TypeEnum } from "@dxos/echo/internal";
|
|
@@ -205,6 +130,46 @@ var pathNotUniqueError = (path) => ({
|
|
|
205
130
|
message: `'${path}' is already present`
|
|
206
131
|
});
|
|
207
132
|
|
|
133
|
+
// src/util/field-type.ts
|
|
134
|
+
import * as SchemaAST from "effect/SchemaAST";
|
|
135
|
+
import { getAnnotation, isLiteralUnion } from "@dxos/effect";
|
|
136
|
+
var detectFieldType = (ast) => {
|
|
137
|
+
if (isLiteralUnion(ast)) {
|
|
138
|
+
return "select";
|
|
139
|
+
}
|
|
140
|
+
if (SchemaAST.isTypeLiteral(ast)) {
|
|
141
|
+
return "struct";
|
|
142
|
+
}
|
|
143
|
+
switch (ast._tag) {
|
|
144
|
+
case "BooleanKeyword":
|
|
145
|
+
return "boolean";
|
|
146
|
+
case "StringKeyword":
|
|
147
|
+
return "string";
|
|
148
|
+
case "NumberKeyword":
|
|
149
|
+
return "number";
|
|
150
|
+
}
|
|
151
|
+
return void 0;
|
|
152
|
+
};
|
|
153
|
+
var getSelectOptionsFromAst = (ast) => {
|
|
154
|
+
if (!isLiteralUnion(ast)) {
|
|
155
|
+
return void 0;
|
|
156
|
+
}
|
|
157
|
+
return ast.types.flatMap((literalNode) => {
|
|
158
|
+
const value3 = literalNode.literal;
|
|
159
|
+
if (typeof value3 !== "string" && typeof value3 !== "number") {
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
const title = getAnnotation(SchemaAST.TitleAnnotationId, false)(literalNode);
|
|
163
|
+
const label = title ?? (typeof value3 === "string" ? value3.charAt(0).toUpperCase() + value3.slice(1) : String(value3));
|
|
164
|
+
return [
|
|
165
|
+
{
|
|
166
|
+
value: value3,
|
|
167
|
+
label
|
|
168
|
+
}
|
|
169
|
+
];
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
|
|
208
173
|
// src/util/formatting.ts
|
|
209
174
|
import { format as formatDate } from "date-fns/format";
|
|
210
175
|
import { Format as Format2, GeoLocation as GeoLocation2, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
|
|
@@ -381,20 +346,24 @@ var getRefProps = (ast) => {
|
|
|
381
346
|
};
|
|
382
347
|
|
|
383
348
|
// src/components/Form/fields/ArrayField.tsx
|
|
384
|
-
import * as
|
|
385
|
-
import * as
|
|
349
|
+
import * as Option4 from "effect/Option";
|
|
350
|
+
import * as SchemaAST4 from "effect/SchemaAST";
|
|
386
351
|
import React5, { useCallback as useCallback3 } from "react";
|
|
387
352
|
import { findNode as findNode2, getArrayElementType as getArrayElementType2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2, isNestedType as isNestedType2 } from "@dxos/effect";
|
|
388
353
|
import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
354
|
+
import { translationKey as translationKey3 } from "#translations";
|
|
389
355
|
|
|
390
356
|
// src/components/Form/Form.tsx
|
|
391
357
|
import { createContext } from "@radix-ui/react-context";
|
|
358
|
+
import * as Option3 from "effect/Option";
|
|
392
359
|
import * as Schema2 from "effect/Schema";
|
|
393
|
-
import * as
|
|
360
|
+
import * as SchemaAST3 from "effect/SchemaAST";
|
|
394
361
|
import React4, { useEffect as useEffect2, useMemo as useMemo4, useRef } from "react";
|
|
362
|
+
import { Annotation as EchoAnnotation } from "@dxos/echo";
|
|
395
363
|
import { createJsonPath as createJsonPath3, getValue as getValue$2 } from "@dxos/effect";
|
|
396
364
|
import { IconButton, ScrollArea, useMergeRefs, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
397
|
-
import { composable, composableProps, mx } from "@dxos/ui-theme";
|
|
365
|
+
import { composable, composableProps, mx, withColumn } from "@dxos/ui-theme";
|
|
366
|
+
import { translationKey as translationKey2 } from "#translations";
|
|
398
367
|
|
|
399
368
|
// src/hooks/useFormHandler.ts
|
|
400
369
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
@@ -432,12 +401,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
432
401
|
log("validate", {
|
|
433
402
|
values: values2,
|
|
434
403
|
errors: errors2
|
|
435
|
-
}, {
|
|
436
|
-
F: __dxlog_file,
|
|
437
|
-
L: 155,
|
|
438
|
-
S: void 0,
|
|
439
|
-
C: (f, a) => f(...a)
|
|
440
|
-
});
|
|
404
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 42, S: void 0 });
|
|
441
405
|
if (errors2.length === 0 && onValidate) {
|
|
442
406
|
const validatedValues = values2;
|
|
443
407
|
errors2 = onValidate(validatedValues) ?? [];
|
|
@@ -525,12 +489,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
525
489
|
log("onValueChange", {
|
|
526
490
|
path,
|
|
527
491
|
value: value3
|
|
528
|
-
}, {
|
|
529
|
-
F: __dxlog_file,
|
|
530
|
-
L: 254,
|
|
531
|
-
S: void 0,
|
|
532
|
-
C: (f, a) => f(...a)
|
|
533
|
-
});
|
|
492
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 138, S: void 0 });
|
|
534
493
|
const jsonPath = createJsonPath(path);
|
|
535
494
|
const pathArray = path;
|
|
536
495
|
let parsedValue = value3;
|
|
@@ -539,12 +498,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
539
498
|
parsedValue = parseFloat(value3) || 0;
|
|
540
499
|
}
|
|
541
500
|
} catch (err) {
|
|
542
|
-
log.catch(err, void 0, {
|
|
543
|
-
F: __dxlog_file,
|
|
544
|
-
L: 264,
|
|
545
|
-
S: void 0,
|
|
546
|
-
C: (f, a) => f(...a)
|
|
547
|
-
});
|
|
501
|
+
log.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 150, S: void 0 });
|
|
548
502
|
parsedValue = void 0;
|
|
549
503
|
}
|
|
550
504
|
const newValues = mergeAtPath(values, pathArray, parsedValue);
|
|
@@ -690,7 +644,6 @@ import { inputTextLabel } from "@dxos/ui-theme";
|
|
|
690
644
|
var FormFieldLabel = ({ label, error, readonly, asChild }) => {
|
|
691
645
|
const Label = readonly || asChild ? "span" : Input.Label;
|
|
692
646
|
return /* @__PURE__ */ React.createElement("div", {
|
|
693
|
-
role: "none",
|
|
694
647
|
className: "flex items-center justify-between"
|
|
695
648
|
}, /* @__PURE__ */ React.createElement(Label, {
|
|
696
649
|
className: inputTextLabel
|
|
@@ -714,7 +667,6 @@ var FormFieldWrapper = (props) => {
|
|
|
714
667
|
}
|
|
715
668
|
const str = String(value3 ?? "");
|
|
716
669
|
return /* @__PURE__ */ React.createElement("div", {
|
|
717
|
-
role: "none",
|
|
718
670
|
className: "contents"
|
|
719
671
|
}, /* @__PURE__ */ React.createElement(Input.Root, {
|
|
720
672
|
validationValence: status
|
|
@@ -745,7 +697,7 @@ var FormFieldErrorBoundary = class extends Component {
|
|
|
745
697
|
return /* @__PURE__ */ React.createElement("div", {
|
|
746
698
|
className: "flex gap-2 border border-rose-fill font-mono text-sm"
|
|
747
699
|
}, /* @__PURE__ */ React.createElement("span", {
|
|
748
|
-
className: "bg-rose-fill text-
|
|
700
|
+
className: "bg-rose-fill text-base-foreground px-1 font-thin"
|
|
749
701
|
}, "ERROR"), String(this.props.path?.join(".")));
|
|
750
702
|
}
|
|
751
703
|
return this.props.children;
|
|
@@ -764,12 +716,13 @@ import React3, { useMemo as useMemo3 } from "react";
|
|
|
764
716
|
import * as Match from "effect/Match";
|
|
765
717
|
import * as Option2 from "effect/Option";
|
|
766
718
|
import * as Schema from "effect/Schema";
|
|
767
|
-
import * as
|
|
719
|
+
import * as SchemaAST2 from "effect/SchemaAST";
|
|
768
720
|
import * as String2 from "effect/String";
|
|
769
721
|
import React2, { useMemo as useMemo2 } from "react";
|
|
770
722
|
import { Format as Format3 } from "@dxos/echo";
|
|
771
|
-
import { createJsonPath as createJsonPath2, findNode, getAnnotation, getDiscriminatedType, isArrayType as isArrayType2, isDiscriminatedUnion, isLiteralUnion, isNestedType } from "@dxos/effect";
|
|
723
|
+
import { createJsonPath as createJsonPath2, findNode, getAnnotation as getAnnotation2, getDiscriminatedType, isArrayType as isArrayType2, isDiscriminatedUnion, isLiteralUnion as isLiteralUnion2, isNestedType } from "@dxos/effect";
|
|
772
724
|
import { useTranslation } from "@dxos/react-ui";
|
|
725
|
+
import { translationKey } from "#translations";
|
|
773
726
|
var FormField = (props) => {
|
|
774
727
|
const {
|
|
775
728
|
type,
|
|
@@ -785,16 +738,16 @@ var FormField = (props) => {
|
|
|
785
738
|
createOptionLabel,
|
|
786
739
|
createOptionIcon,
|
|
787
740
|
createInitialValuePath,
|
|
788
|
-
createFieldMap,
|
|
741
|
+
createFieldMap: createFieldMap3,
|
|
789
742
|
db,
|
|
790
|
-
schemaHook,
|
|
791
|
-
getOptions
|
|
743
|
+
useSchema: schemaHook,
|
|
744
|
+
getOptions,
|
|
792
745
|
onCreate
|
|
793
746
|
} = props;
|
|
794
747
|
const { t } = useTranslation(translationKey);
|
|
795
|
-
const title =
|
|
796
|
-
const description =
|
|
797
|
-
const examples =
|
|
748
|
+
const title = getAnnotation2(SchemaAST2.TitleAnnotationId)(type);
|
|
749
|
+
const description = getAnnotation2(SchemaAST2.DescriptionAnnotationId)(type);
|
|
750
|
+
const examples = getAnnotation2(SchemaAST2.ExamplesAnnotationId)(type);
|
|
798
751
|
const label = useMemo2(() => title ?? String2.capitalize(name), [
|
|
799
752
|
title,
|
|
800
753
|
name
|
|
@@ -812,6 +765,7 @@ var FormField = (props) => {
|
|
|
812
765
|
label,
|
|
813
766
|
placeholder,
|
|
814
767
|
layout,
|
|
768
|
+
db,
|
|
815
769
|
...fieldState
|
|
816
770
|
};
|
|
817
771
|
const jsonPath = createJsonPath2(path ?? []);
|
|
@@ -838,7 +792,7 @@ var FormField = (props) => {
|
|
|
838
792
|
if (Field) {
|
|
839
793
|
return /* @__PURE__ */ React2.createElement(Field, fieldProps);
|
|
840
794
|
}
|
|
841
|
-
const options =
|
|
795
|
+
const options = getSelectOptions(type);
|
|
842
796
|
if (options) {
|
|
843
797
|
const fieldProjections = projection?.getFieldProjections();
|
|
844
798
|
const fieldProjection = fieldProjections?.find((fp) => fp.field.path === name);
|
|
@@ -863,16 +817,16 @@ var FormField = (props) => {
|
|
|
863
817
|
createOptionLabel: isCreateTarget ? createOptionLabel : void 0,
|
|
864
818
|
createOptionIcon: isCreateTarget ? createOptionIcon : void 0,
|
|
865
819
|
createInitialValuePath: isCreateTarget ? createInitialValuePath : void 0,
|
|
866
|
-
createFieldMap: isCreateTarget ?
|
|
820
|
+
createFieldMap: isCreateTarget ? createFieldMap3 : void 0,
|
|
867
821
|
db,
|
|
868
|
-
schemaHook,
|
|
869
|
-
getOptions
|
|
822
|
+
useSchema: schemaHook,
|
|
823
|
+
getOptions,
|
|
870
824
|
onCreate
|
|
871
825
|
});
|
|
872
826
|
}
|
|
873
827
|
if (isNestedType(type)) {
|
|
874
828
|
const baseNode = findNode(type, isDiscriminatedUnion);
|
|
875
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type,
|
|
829
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST2.isTypeLiteral);
|
|
876
830
|
if (typeLiteral) {
|
|
877
831
|
const schema = Schema.make(typeLiteral);
|
|
878
832
|
return /* @__PURE__ */ React2.createElement(FormFieldSet, {
|
|
@@ -888,8 +842,8 @@ var FormField = (props) => {
|
|
|
888
842
|
createOptionIcon,
|
|
889
843
|
createInitialValuePath,
|
|
890
844
|
db,
|
|
891
|
-
schemaHook,
|
|
892
|
-
getOptions
|
|
845
|
+
useSchema: schemaHook,
|
|
846
|
+
getOptions,
|
|
893
847
|
onCreate
|
|
894
848
|
});
|
|
895
849
|
}
|
|
@@ -913,8 +867,8 @@ var getFormField = ({ type, format }) => {
|
|
|
913
867
|
return BooleanField;
|
|
914
868
|
}
|
|
915
869
|
};
|
|
916
|
-
var
|
|
917
|
-
if (
|
|
870
|
+
var getSelectOptions = (ast) => {
|
|
871
|
+
if (isLiteralUnion2(ast)) {
|
|
918
872
|
return ast.types.map((type) => type.literal).filter((v) => v !== null);
|
|
919
873
|
}
|
|
920
874
|
return Format3.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option2.getOrUndefined(annotation));
|
|
@@ -924,39 +878,13 @@ var getOptions = (ast) => {
|
|
|
924
878
|
var FORM_FIELDSET_NAME = "Form.FieldSet";
|
|
925
879
|
var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection, layout, ...props }) => {
|
|
926
880
|
const values = useFormValues(FORM_FIELDSET_NAME, path);
|
|
927
|
-
const properties =
|
|
928
|
-
if (!schema) {
|
|
929
|
-
return [];
|
|
930
|
-
}
|
|
931
|
-
const schemaProps = getFormProperties(schema.ast);
|
|
932
|
-
const filteredProps = exclude ? exclude(schemaProps) : schemaProps;
|
|
933
|
-
if (projection) {
|
|
934
|
-
const fieldProjections = projection.getFieldProjections();
|
|
935
|
-
const hiddenProperties = new Set(projection.getHiddenProperties());
|
|
936
|
-
const visibleProps = filteredProps.filter((prop) => !hiddenProperties.has(prop.name.toString()));
|
|
937
|
-
const orderedProps = [];
|
|
938
|
-
for (const fieldProjection of fieldProjections) {
|
|
939
|
-
const fieldPath = String(fieldProjection.field.path);
|
|
940
|
-
const prop = visibleProps.find((p) => p.name === fieldPath);
|
|
941
|
-
if (prop) {
|
|
942
|
-
orderedProps.push(prop);
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
|
|
946
|
-
const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
|
|
947
|
-
orderedProps.push(...remainingProps);
|
|
948
|
-
return orderedProps;
|
|
949
|
-
}
|
|
950
|
-
return sort ? [
|
|
951
|
-
...filteredProps
|
|
952
|
-
].sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filteredProps;
|
|
953
|
-
}, [
|
|
881
|
+
const properties = useFormFieldSetProperties({
|
|
954
882
|
schema,
|
|
955
883
|
values,
|
|
956
884
|
exclude,
|
|
957
885
|
sort,
|
|
958
886
|
projection
|
|
959
|
-
|
|
887
|
+
});
|
|
960
888
|
if ((readonly || layout === "static") && values == null) {
|
|
961
889
|
return null;
|
|
962
890
|
}
|
|
@@ -986,9 +914,49 @@ var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection,
|
|
|
986
914
|
}));
|
|
987
915
|
};
|
|
988
916
|
FormFieldSet.displayName = FORM_FIELDSET_NAME;
|
|
917
|
+
var useFormFieldSetProperties = ({ schema, exclude, projection, values, sort }) => {
|
|
918
|
+
return useMemo3(() => {
|
|
919
|
+
if (!schema) {
|
|
920
|
+
return [];
|
|
921
|
+
}
|
|
922
|
+
const schemaProps = getFormProperties(schema.ast);
|
|
923
|
+
const filteredProps = exclude ? exclude(schemaProps) : schemaProps;
|
|
924
|
+
if (projection) {
|
|
925
|
+
const fieldProjections = projection.getFieldProjections();
|
|
926
|
+
const hiddenProperties = new Set(projection.getHiddenProperties());
|
|
927
|
+
const visibleProps = filteredProps.filter((prop) => !hiddenProperties.has(prop.name.toString()));
|
|
928
|
+
const orderedProps = [];
|
|
929
|
+
for (const fieldProjection of fieldProjections) {
|
|
930
|
+
const fieldPath = String(fieldProjection.field.path);
|
|
931
|
+
const prop = visibleProps.find((prop2) => prop2.name === fieldPath);
|
|
932
|
+
if (prop) {
|
|
933
|
+
orderedProps.push(prop);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
|
|
937
|
+
const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
|
|
938
|
+
orderedProps.push(...remainingProps);
|
|
939
|
+
return orderedProps;
|
|
940
|
+
}
|
|
941
|
+
return sort ? [
|
|
942
|
+
...filteredProps
|
|
943
|
+
].sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filteredProps;
|
|
944
|
+
}, [
|
|
945
|
+
schema,
|
|
946
|
+
values,
|
|
947
|
+
exclude,
|
|
948
|
+
sort,
|
|
949
|
+
projection
|
|
950
|
+
]);
|
|
951
|
+
};
|
|
989
952
|
|
|
990
953
|
// src/components/Form/Form.tsx
|
|
991
954
|
var omitId = (schema) => schema.pipe(Schema2.omit("id"));
|
|
955
|
+
var omitHiddenFormFields = (schema) => {
|
|
956
|
+
const properties = SchemaAST3.getPropertySignatures(schema.ast);
|
|
957
|
+
const hidden = properties.filter((prop) => Option3.getOrElse(EchoAnnotation.FormInputAnnotation.getFromAst(prop.type), () => true) === false).map((prop) => prop.name);
|
|
958
|
+
return hidden.length === 0 ? schema : schema.pipe(Schema2.omit(...hidden));
|
|
959
|
+
};
|
|
992
960
|
var [FormContextProvider, useFormContext] = createContext("Form");
|
|
993
961
|
var useFormValues = (componentName, path, defaultValue) => {
|
|
994
962
|
const stablePath = useMemo4(() => path ?? [], [
|
|
@@ -1001,7 +969,7 @@ var useFormValues = (componentName, path, defaultValue) => {
|
|
|
1001
969
|
useEffect2(() => {
|
|
1002
970
|
if (value3 == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {
|
|
1003
971
|
lastAppliedPathRef.current = jsonPath;
|
|
1004
|
-
onValueChange(stablePath,
|
|
972
|
+
onValueChange(stablePath, SchemaAST3.stringKeyword, defaultValue());
|
|
1005
973
|
}
|
|
1006
974
|
}, [
|
|
1007
975
|
value3,
|
|
@@ -1068,7 +1036,7 @@ var FormContent = composable(({ children, ...props }, forwardedRef) => {
|
|
|
1068
1036
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1069
1037
|
...composableProps(props, {
|
|
1070
1038
|
role: "form",
|
|
1071
|
-
classNames: "flex flex-col w-full pb-form-gap"
|
|
1039
|
+
classNames: mx(withColumn.center(), "flex flex-col w-full pb-form-gap")
|
|
1072
1040
|
}),
|
|
1073
1041
|
"data-testid": testId,
|
|
1074
1042
|
ref: mergedRef
|
|
@@ -1087,14 +1055,13 @@ var FormFieldSet2 = (props) => {
|
|
|
1087
1055
|
FormFieldSet2.displayName = FORM_FIELDSET_NAME2;
|
|
1088
1056
|
var FORM_ACTIONS_NAME = "Form.Actions";
|
|
1089
1057
|
var FormActions = ({ classNames }) => {
|
|
1090
|
-
const { t } = useTranslation2(
|
|
1058
|
+
const { t } = useTranslation2(translationKey2);
|
|
1091
1059
|
const { form: { canSave, onSave, onCancel }, readonly, layout } = useFormContext(FORM_ACTIONS_NAME);
|
|
1092
1060
|
if (readonly || layout === "static") {
|
|
1093
1061
|
return null;
|
|
1094
1062
|
}
|
|
1095
1063
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1096
|
-
|
|
1097
|
-
className: mx("grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding", classNames)
|
|
1064
|
+
className: mx(withColumn.center(), "grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding", classNames)
|
|
1098
1065
|
}, onCancel && /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1099
1066
|
icon: "ph--x--regular",
|
|
1100
1067
|
iconEnd: true,
|
|
@@ -1113,15 +1080,28 @@ var FormActions = ({ classNames }) => {
|
|
|
1113
1080
|
}));
|
|
1114
1081
|
};
|
|
1115
1082
|
FormActions.displayName = FORM_ACTIONS_NAME;
|
|
1083
|
+
var FORM_SECTION_NAME = "Form.Section";
|
|
1084
|
+
var FormSection = composable(({ children, label, description, ...props }, forwardedRef) => {
|
|
1085
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
1086
|
+
...composableProps(props, {
|
|
1087
|
+
classNames: "flex flex-col pt-form-section-gap first:pt-0"
|
|
1088
|
+
}),
|
|
1089
|
+
ref: forwardedRef
|
|
1090
|
+
}, /* @__PURE__ */ React4.createElement("h2", {
|
|
1091
|
+
className: "text-lg"
|
|
1092
|
+
}, label), description && /* @__PURE__ */ React4.createElement("p", {
|
|
1093
|
+
className: "text-description"
|
|
1094
|
+
}, description), children);
|
|
1095
|
+
});
|
|
1096
|
+
FormSection.displayName = FORM_SECTION_NAME;
|
|
1116
1097
|
var FORM_SUBMIT_NAME = "Form.Submit";
|
|
1117
1098
|
var FormSubmit = ({ classNames, label, icon, disabled }) => {
|
|
1118
|
-
const { t } = useTranslation2(
|
|
1099
|
+
const { t } = useTranslation2(translationKey2);
|
|
1119
1100
|
const { form: { canSave, onSave }, readonly, layout } = useFormContext(FORM_SUBMIT_NAME);
|
|
1120
1101
|
if (readonly || layout === "static") {
|
|
1121
1102
|
return null;
|
|
1122
1103
|
}
|
|
1123
1104
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1124
|
-
role: "none",
|
|
1125
1105
|
className: mx("flex w-full pt-form-padding", classNames)
|
|
1126
1106
|
}, /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1127
1107
|
classNames: "w-full",
|
|
@@ -1139,6 +1119,7 @@ var Form = {
|
|
|
1139
1119
|
Root: FormRoot,
|
|
1140
1120
|
Viewport: FormViewport,
|
|
1141
1121
|
Content: FormContent,
|
|
1122
|
+
Section: FormSection,
|
|
1142
1123
|
FieldSet: FormFieldSet2,
|
|
1143
1124
|
Label: FormFieldLabel,
|
|
1144
1125
|
Actions: FormActions,
|
|
@@ -1147,18 +1128,18 @@ var Form = {
|
|
|
1147
1128
|
|
|
1148
1129
|
// src/components/Form/fields/ArrayField.tsx
|
|
1149
1130
|
var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps, ...props }) => {
|
|
1150
|
-
const { t } = useTranslation3(
|
|
1131
|
+
const { t } = useTranslation3(translationKey3);
|
|
1151
1132
|
const elementType = getArrayElementType2(type);
|
|
1152
1133
|
const { onValueChange } = inputProps;
|
|
1153
1134
|
const values = useFormValues(ArrayField.displayName, path, () => []);
|
|
1154
1135
|
const getDefaultObjectValue = (typeNode) => {
|
|
1155
1136
|
const baseNode = findNode2(typeNode, isDiscriminatedUnion2);
|
|
1156
|
-
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode,
|
|
1137
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST4.isTypeLiteral);
|
|
1157
1138
|
if (!typeLiteral) {
|
|
1158
1139
|
return {};
|
|
1159
1140
|
}
|
|
1160
1141
|
return Object.fromEntries(getFormProperties(typeLiteral).map((prop) => {
|
|
1161
|
-
const defaultValue =
|
|
1142
|
+
const defaultValue = SchemaAST4.getDefaultAnnotation(prop.type).pipe((annotation) => Option4.getOrUndefined(annotation));
|
|
1162
1143
|
return [
|
|
1163
1144
|
prop.name,
|
|
1164
1145
|
defaultValue
|
|
@@ -1192,13 +1173,11 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1192
1173
|
label,
|
|
1193
1174
|
asChild: true
|
|
1194
1175
|
}), /* @__PURE__ */ React5.createElement("div", {
|
|
1195
|
-
role: "none",
|
|
1196
1176
|
className: "flex flex-col gap-form-gap"
|
|
1197
1177
|
}, values?.map((_, index) => {
|
|
1198
1178
|
return /* @__PURE__ */ React5.createElement("div", {
|
|
1199
|
-
role: "none",
|
|
1200
1179
|
key: index,
|
|
1201
|
-
className: "
|
|
1180
|
+
className: "grid grid-cols-[1fr_min-content] gap-form-gap last:mb-form-gap items-center"
|
|
1202
1181
|
}, /* @__PURE__ */ React5.createElement(FormField, {
|
|
1203
1182
|
autoFocus: index === values.length - 1,
|
|
1204
1183
|
type: elementType,
|
|
@@ -1210,10 +1189,8 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1210
1189
|
layout: "inline",
|
|
1211
1190
|
...props
|
|
1212
1191
|
}), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement("div", {
|
|
1213
|
-
role: "none",
|
|
1214
1192
|
className: "flex flex-col h-full justify-end"
|
|
1215
1193
|
}, /* @__PURE__ */ React5.createElement("div", {
|
|
1216
|
-
role: "none",
|
|
1217
1194
|
className: "flex items-center h-[2rem]"
|
|
1218
1195
|
}, /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1219
1196
|
icon: "ph--x--regular",
|
|
@@ -1225,7 +1202,7 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1225
1202
|
})), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1226
1203
|
classNames: "flex w-full",
|
|
1227
1204
|
icon: "ph--plus--regular",
|
|
1228
|
-
label: t("add-
|
|
1205
|
+
label: t("add-item.button"),
|
|
1229
1206
|
onClick: handleAdd
|
|
1230
1207
|
}));
|
|
1231
1208
|
};
|
|
@@ -1277,8 +1254,9 @@ import React7, { useCallback as useCallback5, useEffect as useEffect3, useMemo a
|
|
|
1277
1254
|
import { GeoLocation as GeoLocation3 } from "@dxos/echo/internal";
|
|
1278
1255
|
import { Input as Input3, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
1279
1256
|
import { safeParseFloat } from "@dxos/util";
|
|
1257
|
+
import { translationKey as translationKey4 } from "#translations";
|
|
1280
1258
|
var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onValueChange, onBlur }) => {
|
|
1281
|
-
const { t } = useTranslation4(
|
|
1259
|
+
const { t } = useTranslation4(translationKey4);
|
|
1282
1260
|
const { status, error } = getStatus();
|
|
1283
1261
|
const geoPoint = useMemo5(() => getValue() ?? [
|
|
1284
1262
|
0,
|
|
@@ -1332,7 +1310,6 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
|
|
|
1332
1310
|
label,
|
|
1333
1311
|
asChild: true
|
|
1334
1312
|
}), layout === "static" ? /* @__PURE__ */ React7.createElement(LatLng, value3) : /* @__PURE__ */ React7.createElement("div", {
|
|
1335
|
-
role: "none",
|
|
1336
1313
|
className: "grid grid-cols-2 gap-form-gap"
|
|
1337
1314
|
}, /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement(Input3.Root, null, layout !== "inline" && /* @__PURE__ */ React7.createElement(Input3.Label, null, t("latitude.label")), /* @__PURE__ */ React7.createElement(Input3.TextInput, {
|
|
1338
1315
|
type: "number",
|
|
@@ -1369,56 +1346,141 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
|
|
|
1369
1346
|
};
|
|
1370
1347
|
|
|
1371
1348
|
// src/components/Form/fields/MarkdownField.tsx
|
|
1372
|
-
import
|
|
1373
|
-
import {
|
|
1374
|
-
|
|
1349
|
+
import { useAtomValue } from "@effect-atom/atom-react";
|
|
1350
|
+
import React8, { useCallback as useCallback6, useMemo as useMemo6 } from "react";
|
|
1351
|
+
import { Obj, Ref as Ref2 } from "@dxos/echo";
|
|
1352
|
+
import { AtomRef } from "@dxos/echo-atom";
|
|
1353
|
+
import { createDocAccessor } from "@dxos/echo-db";
|
|
1354
|
+
import { Button, Icon as Icon2, Input as Input4, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
1355
|
+
import { Editor, useBasicMarkdownExtensions } from "@dxos/react-ui-editor";
|
|
1356
|
+
import { Text } from "@dxos/schema";
|
|
1357
|
+
import { createDataExtensions } from "@dxos/ui-editor";
|
|
1358
|
+
import { translationKey as translationKey5 } from "#translations";
|
|
1359
|
+
var editorClassNames = "transition-colors bg-input-surface focus-within:bg-focus-surface border border-separator rounded-xs p-1 px-2";
|
|
1360
|
+
var MarkdownField = ({ type, readonly, label, placeholder, layout, db, getStatus, getValue, onValueChange }) => {
|
|
1375
1361
|
const { status, error } = getStatus();
|
|
1376
|
-
const
|
|
1377
|
-
const adjustHeight = useCallback6(() => {
|
|
1378
|
-
const textarea = textareaRef.current;
|
|
1379
|
-
if (textarea) {
|
|
1380
|
-
textarea.style.blockSize = "auto";
|
|
1381
|
-
textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
|
|
1382
|
-
}
|
|
1383
|
-
}, []);
|
|
1384
|
-
useEffect4(() => {
|
|
1385
|
-
adjustHeight();
|
|
1386
|
-
}, [
|
|
1387
|
-
adjustHeight
|
|
1388
|
-
]);
|
|
1389
|
-
useEffect4(() => {
|
|
1390
|
-
adjustHeight();
|
|
1391
|
-
}, [
|
|
1392
|
-
getValue(),
|
|
1393
|
-
adjustHeight
|
|
1394
|
-
]);
|
|
1395
|
-
const handleChange = useCallback6((event) => onValueChange(type, event.target.value), [
|
|
1396
|
-
type,
|
|
1397
|
-
onValueChange
|
|
1398
|
-
]);
|
|
1362
|
+
const isRef = Ref2.isRefType(type);
|
|
1399
1363
|
const value3 = getValue();
|
|
1400
|
-
if ((readonly || layout === "static") &&
|
|
1364
|
+
if ((readonly || layout === "static") && value3 == null) {
|
|
1401
1365
|
return null;
|
|
1402
1366
|
}
|
|
1367
|
+
const renderEditor = () => {
|
|
1368
|
+
if (isRef) {
|
|
1369
|
+
const reference = value3;
|
|
1370
|
+
if (reference) {
|
|
1371
|
+
return /* @__PURE__ */ React8.createElement(RefMarkdownEditor, {
|
|
1372
|
+
reference,
|
|
1373
|
+
placeholder
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
if (readonly) {
|
|
1377
|
+
return null;
|
|
1378
|
+
}
|
|
1379
|
+
return /* @__PURE__ */ React8.createElement(CreateTextButton, {
|
|
1380
|
+
db,
|
|
1381
|
+
disabled: !db,
|
|
1382
|
+
onCreate: (ref) => onValueChange(type, ref)
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
return /* @__PURE__ */ React8.createElement(StringMarkdownEditor, {
|
|
1386
|
+
value: value3 ?? "",
|
|
1387
|
+
placeholder,
|
|
1388
|
+
readonly: !!readonly,
|
|
1389
|
+
onChange: (next) => onValueChange(type, next)
|
|
1390
|
+
});
|
|
1391
|
+
};
|
|
1392
|
+
const renderStatic = () => {
|
|
1393
|
+
if (isRef) {
|
|
1394
|
+
const reference = value3;
|
|
1395
|
+
return reference ? /* @__PURE__ */ React8.createElement(RefStaticText, {
|
|
1396
|
+
reference
|
|
1397
|
+
}) : null;
|
|
1398
|
+
}
|
|
1399
|
+
return /* @__PURE__ */ React8.createElement("p", {
|
|
1400
|
+
className: "whitespace-pre-wrap"
|
|
1401
|
+
}, value3 ?? "");
|
|
1402
|
+
};
|
|
1403
1403
|
return /* @__PURE__ */ React8.createElement(Input4.Root, {
|
|
1404
1404
|
validationValence: status
|
|
1405
1405
|
}, layout !== "inline" && /* @__PURE__ */ React8.createElement(FormFieldLabel, {
|
|
1406
1406
|
error,
|
|
1407
1407
|
readonly,
|
|
1408
1408
|
label
|
|
1409
|
-
}), layout === "static" ?
|
|
1410
|
-
|
|
1411
|
-
|
|
1409
|
+
}), layout === "static" ? renderStatic() : renderEditor(), layout === "full" && /* @__PURE__ */ React8.createElement(Input4.Validation, null, error));
|
|
1410
|
+
};
|
|
1411
|
+
var RefStaticText = ({ reference }) => {
|
|
1412
|
+
const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
|
|
1413
|
+
reference
|
|
1414
|
+
]));
|
|
1415
|
+
if (!text?.content) {
|
|
1416
|
+
return null;
|
|
1417
|
+
}
|
|
1418
|
+
return /* @__PURE__ */ React8.createElement("p", {
|
|
1419
|
+
className: "whitespace-pre-wrap"
|
|
1420
|
+
}, text.content);
|
|
1421
|
+
};
|
|
1422
|
+
var RefMarkdownEditor = ({ reference, placeholder }) => {
|
|
1423
|
+
const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
|
|
1424
|
+
reference
|
|
1425
|
+
]));
|
|
1426
|
+
const dataExtensions = useMemo6(() => text ? [
|
|
1427
|
+
createDataExtensions({
|
|
1428
|
+
id: reference.dxn.toString(),
|
|
1429
|
+
text: createDocAccessor(text, [
|
|
1430
|
+
"content"
|
|
1431
|
+
])
|
|
1432
|
+
})
|
|
1433
|
+
] : [], [
|
|
1434
|
+
text,
|
|
1435
|
+
reference
|
|
1436
|
+
]);
|
|
1437
|
+
const extensions = useBasicMarkdownExtensions({
|
|
1412
1438
|
placeholder,
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
})
|
|
1439
|
+
extensions: dataExtensions
|
|
1440
|
+
});
|
|
1441
|
+
if (!text) {
|
|
1442
|
+
return null;
|
|
1443
|
+
}
|
|
1444
|
+
return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
|
|
1445
|
+
classNames: editorClassNames,
|
|
1446
|
+
extensions
|
|
1447
|
+
}));
|
|
1448
|
+
};
|
|
1449
|
+
var StringMarkdownEditor = ({ value: value3, placeholder, readonly, onChange }) => {
|
|
1450
|
+
const extensions = useBasicMarkdownExtensions({
|
|
1451
|
+
placeholder
|
|
1452
|
+
});
|
|
1453
|
+
const handleChange = useCallback6((next) => onChange(next), [
|
|
1454
|
+
onChange
|
|
1455
|
+
]);
|
|
1456
|
+
return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
|
|
1457
|
+
classNames: editorClassNames,
|
|
1458
|
+
extensions,
|
|
1459
|
+
value: value3,
|
|
1460
|
+
onChange: readonly ? void 0 : handleChange
|
|
1461
|
+
}));
|
|
1462
|
+
};
|
|
1463
|
+
var CreateTextButton = ({ db, disabled, onCreate }) => {
|
|
1464
|
+
const { t } = useTranslation5(translationKey5);
|
|
1465
|
+
const handleClick = useCallback6(() => {
|
|
1466
|
+
if (!db) {
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1469
|
+
const text = db.add(Obj.make(Text.Text, {
|
|
1470
|
+
content: ""
|
|
1471
|
+
}));
|
|
1472
|
+
onCreate(Ref2.make(text));
|
|
1473
|
+
}, [
|
|
1474
|
+
db,
|
|
1475
|
+
onCreate
|
|
1476
|
+
]);
|
|
1477
|
+
return /* @__PURE__ */ React8.createElement(Button, {
|
|
1478
|
+
onClick: handleClick,
|
|
1479
|
+
disabled
|
|
1480
|
+
}, /* @__PURE__ */ React8.createElement(Icon2, {
|
|
1481
|
+
icon: "ph--plus--regular",
|
|
1482
|
+
size: 4
|
|
1483
|
+
}), /* @__PURE__ */ React8.createElement("span", null, t("create-text.label")));
|
|
1422
1484
|
};
|
|
1423
1485
|
|
|
1424
1486
|
// src/components/Form/fields/NumberField.tsx
|
|
@@ -1444,31 +1506,33 @@ var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...prop
|
|
|
1444
1506
|
};
|
|
1445
1507
|
|
|
1446
1508
|
// src/components/Form/fields/RefField.tsx
|
|
1447
|
-
import React11, { useCallback as useCallback9, useMemo as
|
|
1509
|
+
import React11, { useCallback as useCallback9, useMemo as useMemo7, useState as useState4 } from "react";
|
|
1448
1510
|
import "@dxos/lit-ui/dx-tag-picker.pcss";
|
|
1449
|
-
import { Entity, Filter, Obj, Ref as
|
|
1450
|
-
import { useQuery, useSchema as
|
|
1511
|
+
import { Entity, Filter, Obj as Obj2, Ref as Ref3, Type } from "@dxos/echo";
|
|
1512
|
+
import { useQuery, useSchema as defaultUseSchema } from "@dxos/echo-react";
|
|
1451
1513
|
import { ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo/internal";
|
|
1452
1514
|
import { findAnnotation as findAnnotation2 } from "@dxos/effect";
|
|
1453
1515
|
import { DXN } from "@dxos/keys";
|
|
1454
1516
|
import { DxAnchor } from "@dxos/lit-ui/react";
|
|
1455
|
-
import { Button, Icon as
|
|
1517
|
+
import { Button as Button2, Icon as Icon3, Input as Input6, useTranslation as useTranslation7 } from "@dxos/react-ui";
|
|
1456
1518
|
import { ParentLabelAnnotationId } from "@dxos/schema";
|
|
1457
|
-
import {
|
|
1519
|
+
import { translationKey as translationKey7 } from "#translations";
|
|
1458
1520
|
|
|
1459
1521
|
// src/components/ObjectPicker/ObjectPicker.tsx
|
|
1460
1522
|
import React10, { forwardRef, useCallback as useCallback8, useState as useState3 } from "react";
|
|
1461
|
-
import { Popover, useTranslation as
|
|
1462
|
-
import { Combobox
|
|
1463
|
-
|
|
1464
|
-
|
|
1523
|
+
import { Popover, useTranslation as useTranslation6 } from "@dxos/react-ui";
|
|
1524
|
+
import { Combobox } from "@dxos/react-ui-list";
|
|
1525
|
+
import { useSearchListResults } from "@dxos/react-ui-search";
|
|
1526
|
+
import { translationKey as translationKey6 } from "#translations";
|
|
1527
|
+
var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, onSelect, onCreate, ...props }, forwardedRef) => {
|
|
1528
|
+
const { t } = useTranslation6(translationKey6);
|
|
1465
1529
|
const [showForm, setShowForm] = useState3(false);
|
|
1466
1530
|
const [formInitialValue, setFormInitialValue] = useState3("");
|
|
1467
|
-
const { results, handleSearch } = useSearchListResults({
|
|
1531
|
+
const { results, query, handleSearch } = useSearchListResults({
|
|
1468
1532
|
items: options
|
|
1469
1533
|
});
|
|
1470
|
-
const handleFormSave = useCallback8((values) => {
|
|
1471
|
-
onCreate?.(values);
|
|
1534
|
+
const handleFormSave = useCallback8(async (values) => {
|
|
1535
|
+
await onCreate?.(values);
|
|
1472
1536
|
setShowForm(false);
|
|
1473
1537
|
setFormInitialValue("");
|
|
1474
1538
|
}, [
|
|
@@ -1493,7 +1557,6 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
|
|
|
1493
1557
|
if (showForm && createSchema) {
|
|
1494
1558
|
return /* @__PURE__ */ React10.createElement(Combobox.Content, {
|
|
1495
1559
|
...props,
|
|
1496
|
-
onSearch: handleSearch,
|
|
1497
1560
|
onKeyDownCapture: handleKeyDown,
|
|
1498
1561
|
ref: forwardedRef
|
|
1499
1562
|
}, /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Root, {
|
|
@@ -1502,19 +1565,20 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
|
|
|
1502
1565
|
defaultValues: createInitialValuePath ? {
|
|
1503
1566
|
[createInitialValuePath]: formInitialValue
|
|
1504
1567
|
} : {},
|
|
1505
|
-
fieldMap:
|
|
1568
|
+
fieldMap: createFieldMap3,
|
|
1506
1569
|
onSave: handleFormSave,
|
|
1507
1570
|
onCancel: handleFormCancel
|
|
1508
1571
|
}, /* @__PURE__ */ React10.createElement(Form.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Content, null, /* @__PURE__ */ React10.createElement(Form.FieldSet, null), /* @__PURE__ */ React10.createElement(Form.Actions, null))))), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
|
|
1509
1572
|
}
|
|
1510
1573
|
return /* @__PURE__ */ React10.createElement(Combobox.Content, {
|
|
1511
1574
|
...props,
|
|
1512
|
-
onSearch: handleSearch,
|
|
1513
1575
|
onKeyDownCapture: handleKeyDown,
|
|
1514
1576
|
ref: forwardedRef
|
|
1515
1577
|
}, /* @__PURE__ */ React10.createElement(Combobox.Input, {
|
|
1516
1578
|
placeholder: t("ref-field-combobox-input.placeholder"),
|
|
1517
|
-
autoFocus: true
|
|
1579
|
+
autoFocus: true,
|
|
1580
|
+
value: query,
|
|
1581
|
+
onValueChange: handleSearch
|
|
1518
1582
|
}), /* @__PURE__ */ React10.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
|
|
1519
1583
|
key: option.id,
|
|
1520
1584
|
value: option.id,
|
|
@@ -1523,17 +1587,17 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, cr
|
|
|
1523
1587
|
onSelect: () => onSelect(option.id),
|
|
1524
1588
|
classNames: "flex items-center gap-2"
|
|
1525
1589
|
})), createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
|
|
1590
|
+
query,
|
|
1526
1591
|
createOptionLabel,
|
|
1527
1592
|
createOptionIcon: createOptionIcon ?? "ph--plus--regular",
|
|
1528
|
-
onCreateItemSelect: (
|
|
1529
|
-
setFormInitialValue(
|
|
1593
|
+
onCreateItemSelect: (currentQuery) => {
|
|
1594
|
+
setFormInitialValue(currentQuery);
|
|
1530
1595
|
setShowForm(true);
|
|
1531
1596
|
}
|
|
1532
1597
|
})), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
|
|
1533
1598
|
});
|
|
1534
|
-
var CreateItem = ({ createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
|
|
1535
|
-
const { t } =
|
|
1536
|
-
const { query } = useSearchListInput();
|
|
1599
|
+
var CreateItem = ({ query, createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
|
|
1600
|
+
const { t } = useTranslation6(translationKey6);
|
|
1537
1601
|
const label = createOptionLabel ? t(createOptionLabel[0], {
|
|
1538
1602
|
ns: createOptionLabel[1].ns,
|
|
1539
1603
|
text: query
|
|
@@ -1564,39 +1628,41 @@ var isRefSnapshot = (val) => {
|
|
|
1564
1628
|
};
|
|
1565
1629
|
var defaultGetOptions = (results, { parentLabel } = {}) => results.map((result) => {
|
|
1566
1630
|
const id = Entity.getDXN(result).toString();
|
|
1567
|
-
const parent = parentLabel ?
|
|
1631
|
+
const parent = parentLabel ? Obj2.getParent(result) : void 0;
|
|
1568
1632
|
const label = parent ? Entity.getLabel(parent) : Entity.getLabel(result);
|
|
1569
1633
|
return {
|
|
1570
1634
|
id,
|
|
1571
1635
|
label: label ?? id
|
|
1572
1636
|
};
|
|
1573
1637
|
});
|
|
1574
|
-
var
|
|
1638
|
+
var defaultUseResults = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Obj2.Unknown) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
|
|
1575
1639
|
var RefField = (props) => {
|
|
1576
|
-
const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap, db,
|
|
1577
|
-
const { t } =
|
|
1640
|
+
const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, db, useSchema = defaultUseSchema, useResults = defaultUseResults, getOptions = defaultGetOptions, onCreate, onValueChange } = props;
|
|
1641
|
+
const { t } = useTranslation7(translationKey7);
|
|
1578
1642
|
const { status, error } = getStatus();
|
|
1579
|
-
const typename =
|
|
1643
|
+
const typename = useMemo7(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
|
|
1580
1644
|
type
|
|
1581
1645
|
]);
|
|
1582
1646
|
const results = useResults(db, typename);
|
|
1583
|
-
const options =
|
|
1647
|
+
const options = useMemo7(() => {
|
|
1584
1648
|
const parentLabel = type ? findAnnotation2(type, ParentLabelAnnotationId) === true : false;
|
|
1585
|
-
return
|
|
1649
|
+
return getOptions(results, {
|
|
1586
1650
|
parentLabel
|
|
1587
1651
|
});
|
|
1588
1652
|
}, [
|
|
1589
1653
|
results,
|
|
1590
|
-
|
|
1654
|
+
getOptions,
|
|
1591
1655
|
type
|
|
1592
1656
|
]);
|
|
1593
1657
|
const handleGetValue = useCallback9(() => {
|
|
1594
1658
|
const formValue = getValue();
|
|
1659
|
+
const dxnToObjectId = (dxn) => dxn.split(":").pop() ?? dxn;
|
|
1595
1660
|
const unknownToRefOption = (value3) => {
|
|
1596
|
-
const isRef =
|
|
1661
|
+
const isRef = Ref3.isRef(value3);
|
|
1597
1662
|
if (isRef || isRefSnapshot(value3)) {
|
|
1598
1663
|
const dxnString = isRef ? value3.dxn.toString() : value3["/"];
|
|
1599
|
-
const
|
|
1664
|
+
const objectId = dxnToObjectId(dxnString);
|
|
1665
|
+
const matchingOption = options.find((option) => dxnToObjectId(option.id) === objectId);
|
|
1600
1666
|
if (matchingOption) {
|
|
1601
1667
|
return matchingOption;
|
|
1602
1668
|
}
|
|
@@ -1608,29 +1674,37 @@ var RefField = (props) => {
|
|
|
1608
1674
|
options,
|
|
1609
1675
|
getValue
|
|
1610
1676
|
]);
|
|
1611
|
-
const handleUpdate = useCallback9((id) => {
|
|
1612
|
-
const item2 = options.find((option) => option.id === id);
|
|
1613
|
-
const ref = item2 ? Ref2.fromDXN(DXN.parse(item2.id)) : void 0;
|
|
1614
|
-
onValueChange(type, ref);
|
|
1615
|
-
}, [
|
|
1616
|
-
options,
|
|
1617
|
-
type,
|
|
1618
|
-
onValueChange
|
|
1619
|
-
]);
|
|
1620
1677
|
const item = handleGetValue();
|
|
1621
|
-
const selectedIds =
|
|
1678
|
+
const selectedIds = useMemo7(() => item ? [
|
|
1622
1679
|
item.id
|
|
1623
1680
|
] : [], [
|
|
1624
1681
|
item
|
|
1625
1682
|
]);
|
|
1626
1683
|
const createSchema = useSchema(db, typename);
|
|
1627
|
-
const
|
|
1628
|
-
|
|
1629
|
-
|
|
1684
|
+
const [open, setOpen] = useState4(false);
|
|
1685
|
+
const handleCreate = useCallback9(async (values) => {
|
|
1686
|
+
if (!createSchema || !onCreate) {
|
|
1687
|
+
return;
|
|
1630
1688
|
}
|
|
1689
|
+
const newObject = await onCreate(createSchema, values);
|
|
1690
|
+
if (newObject) {
|
|
1691
|
+
onValueChange(type, Ref3.make(newObject));
|
|
1692
|
+
}
|
|
1693
|
+
setOpen(false);
|
|
1631
1694
|
}, [
|
|
1632
1695
|
createSchema,
|
|
1633
|
-
onCreate
|
|
1696
|
+
onCreate,
|
|
1697
|
+
type,
|
|
1698
|
+
onValueChange
|
|
1699
|
+
]);
|
|
1700
|
+
const handleUpdate = useCallback9((id) => {
|
|
1701
|
+
const item2 = options.find((option) => option.id === id);
|
|
1702
|
+
const ref = item2 ? Ref3.fromDXN(DXN.parse(item2.id)) : void 0;
|
|
1703
|
+
onValueChange(type, ref);
|
|
1704
|
+
}, [
|
|
1705
|
+
options,
|
|
1706
|
+
type,
|
|
1707
|
+
onValueChange
|
|
1634
1708
|
]);
|
|
1635
1709
|
const handleSelect = useCallback9((id) => {
|
|
1636
1710
|
if (item?.id === id) {
|
|
@@ -1652,12 +1726,15 @@ var RefField = (props) => {
|
|
|
1652
1726
|
readonly,
|
|
1653
1727
|
label
|
|
1654
1728
|
}), /* @__PURE__ */ React11.createElement("div", null, readonly ? !item ? /* @__PURE__ */ React11.createElement("p", {
|
|
1655
|
-
className:
|
|
1729
|
+
className: "text-description mb-2"
|
|
1656
1730
|
}, t("empty-readonly-ref-field.label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
|
|
1657
1731
|
key: item.id,
|
|
1658
1732
|
dxn: item.id,
|
|
1659
1733
|
rootclassname: "me-1"
|
|
1660
|
-
}, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root,
|
|
1734
|
+
}, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, {
|
|
1735
|
+
open,
|
|
1736
|
+
onOpenChange: setOpen
|
|
1737
|
+
}, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
|
|
1661
1738
|
asChild: true,
|
|
1662
1739
|
classNames: "p-0"
|
|
1663
1740
|
}, item ? /* @__PURE__ */ React11.createElement("div", {
|
|
@@ -1668,25 +1745,27 @@ var RefField = (props) => {
|
|
|
1668
1745
|
value: item.label,
|
|
1669
1746
|
readOnly: true,
|
|
1670
1747
|
classNames: "w-full"
|
|
1671
|
-
}))) : /* @__PURE__ */ React11.createElement(
|
|
1748
|
+
}))) : /* @__PURE__ */ React11.createElement(Button2, {
|
|
1672
1749
|
classNames: "w-full text-start gap-form-gap"
|
|
1673
1750
|
}, /* @__PURE__ */ React11.createElement("div", {
|
|
1674
|
-
role: "none",
|
|
1675
1751
|
className: "grow overflow-hidden"
|
|
1676
1752
|
}, /* @__PURE__ */ React11.createElement("span", {
|
|
1677
|
-
className: "
|
|
1678
|
-
}, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(
|
|
1753
|
+
className: "truncate text-description"
|
|
1754
|
+
}, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon3, {
|
|
1679
1755
|
size: 3,
|
|
1680
1756
|
icon: "ph--caret-down--bold"
|
|
1681
1757
|
}))), /* @__PURE__ */ React11.createElement(ObjectPicker.Portal, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
|
|
1682
1758
|
classNames: "dx-card-popover-width",
|
|
1683
1759
|
options,
|
|
1684
1760
|
selectedIds,
|
|
1685
|
-
|
|
1761
|
+
// Strip hidden (`FormInputAnnotation.set(false)`) fields so the
|
|
1762
|
+
// form's validator doesn't reject required-but-hidden fields
|
|
1763
|
+
// such as backing-object refs supplied by a `FactoryAnnotation`.
|
|
1764
|
+
createSchema: createSchema && omitHiddenFormFields(omitId(createSchema)),
|
|
1686
1765
|
createOptionLabel,
|
|
1687
1766
|
createOptionIcon,
|
|
1688
1767
|
createInitialValuePath,
|
|
1689
|
-
createFieldMap,
|
|
1768
|
+
createFieldMap: createFieldMap3,
|
|
1690
1769
|
onCreate: handleCreate,
|
|
1691
1770
|
onSelect: handleSelect
|
|
1692
1771
|
})))), layout === "full" && /* @__PURE__ */ React11.createElement(Input6.DescriptionAndValidation, null, error));
|
|
@@ -1728,20 +1807,21 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
|
|
|
1728
1807
|
};
|
|
1729
1808
|
|
|
1730
1809
|
// src/components/Form/fields/SelectOptionField.tsx
|
|
1731
|
-
import React13, { useCallback as useCallback11, useEffect as
|
|
1810
|
+
import React13, { useCallback as useCallback11, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
|
|
1732
1811
|
import { PublicKey } from "@dxos/keys";
|
|
1733
|
-
import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as
|
|
1812
|
+
import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as useTranslation8 } from "@dxos/react-ui";
|
|
1734
1813
|
import { List } from "@dxos/react-ui-list";
|
|
1735
1814
|
import { HuePicker } from "@dxos/react-ui-pickers";
|
|
1736
|
-
import { hues, osTranslations
|
|
1815
|
+
import { hues, osTranslations } from "@dxos/ui-theme";
|
|
1816
|
+
import { translationKey as translationKey8 } from "#translations";
|
|
1737
1817
|
var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueChange }) => {
|
|
1738
|
-
const { t } =
|
|
1818
|
+
const { t } = useTranslation8(translationKey8);
|
|
1739
1819
|
const { status, error } = getStatus();
|
|
1740
|
-
const [selected, setSelectedId] =
|
|
1741
|
-
const [isNewOption, setIsNewOption] =
|
|
1742
|
-
const inputRef =
|
|
1820
|
+
const [selected, setSelectedId] = useState5(null);
|
|
1821
|
+
const [isNewOption, setIsNewOption] = useState5(false);
|
|
1822
|
+
const inputRef = useRef2(null);
|
|
1743
1823
|
const options = getValue();
|
|
1744
|
-
|
|
1824
|
+
useEffect4(() => {
|
|
1745
1825
|
if (options === void 0) {
|
|
1746
1826
|
onValueChange(type, []);
|
|
1747
1827
|
}
|
|
@@ -1832,7 +1912,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1832
1912
|
type,
|
|
1833
1913
|
onValueChange
|
|
1834
1914
|
]);
|
|
1835
|
-
|
|
1915
|
+
useEffect4(() => {
|
|
1836
1916
|
if (selected && isNewOption && inputRef.current) {
|
|
1837
1917
|
inputRef.current.focus();
|
|
1838
1918
|
setIsNewOption(false);
|
|
@@ -1847,9 +1927,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1847
1927
|
error,
|
|
1848
1928
|
readonly,
|
|
1849
1929
|
label
|
|
1850
|
-
}), /* @__PURE__ */ React13.createElement("div", {
|
|
1851
|
-
role: "none"
|
|
1852
|
-
}, options && /* @__PURE__ */ React13.createElement(List.Root, {
|
|
1930
|
+
}), /* @__PURE__ */ React13.createElement("div", null, options && /* @__PURE__ */ React13.createElement(List.Root, {
|
|
1853
1931
|
items: options,
|
|
1854
1932
|
isItem: (_item) => true,
|
|
1855
1933
|
onMove: readonly ? void 0 : handleMove,
|
|
@@ -1862,10 +1940,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1862
1940
|
}, /* @__PURE__ */ React13.createElement(List.Item, {
|
|
1863
1941
|
role: "button",
|
|
1864
1942
|
item,
|
|
1865
|
-
classNames:
|
|
1866
|
-
subtleHover,
|
|
1867
|
-
"flex flex-col cursor-pointer rounded-xs"
|
|
1868
|
-
],
|
|
1943
|
+
classNames: "flex flex-col cursor-pointer rounded-xs dx-hover",
|
|
1869
1944
|
"aria-expanded": selected === item.id
|
|
1870
1945
|
}, /* @__PURE__ */ React13.createElement("div", {
|
|
1871
1946
|
className: "flex items-center"
|
|
@@ -1879,7 +1954,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1879
1954
|
}, item.title || "\u200B")), /* @__PURE__ */ React13.createElement(IconButton3, {
|
|
1880
1955
|
iconOnly: true,
|
|
1881
1956
|
variant: "ghost",
|
|
1882
|
-
label: t(selected === item.id ? "collapse
|
|
1957
|
+
label: t(selected === item.id ? "collapse.label" : "expand.label", {
|
|
1883
1958
|
ns: osTranslations
|
|
1884
1959
|
}),
|
|
1885
1960
|
icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
@@ -1921,7 +1996,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1921
1996
|
// src/components/Form/fields/TextField.tsx
|
|
1922
1997
|
import React14, { useCallback as useCallback12 } from "react";
|
|
1923
1998
|
import { Input as Input9 } from "@dxos/react-ui";
|
|
1924
|
-
var TextField = ({ type, readonly, placeholder,
|
|
1999
|
+
var TextField = ({ type, readonly, placeholder, onBlur, onValueChange, ...props }) => {
|
|
1925
2000
|
const handleChange = useCallback12((event) => onValueChange(type, event.target.value), [
|
|
1926
2001
|
type,
|
|
1927
2002
|
onValueChange
|
|
@@ -1934,8 +2009,8 @@ var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props
|
|
|
1934
2009
|
disabled: !!readonly,
|
|
1935
2010
|
placeholder,
|
|
1936
2011
|
value: value3,
|
|
1937
|
-
|
|
1938
|
-
|
|
2012
|
+
onBlur,
|
|
2013
|
+
onChange: handleChange
|
|
1939
2014
|
}));
|
|
1940
2015
|
};
|
|
1941
2016
|
|
|
@@ -1963,7 +2038,7 @@ var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...pr
|
|
|
1963
2038
|
// src/components/Form/fields/TupleField.tsx
|
|
1964
2039
|
import React16 from "react";
|
|
1965
2040
|
import { Input as Input11 } from "@dxos/react-ui";
|
|
1966
|
-
import { mx as
|
|
2041
|
+
import { mx as mx2 } from "@dxos/ui-theme";
|
|
1967
2042
|
import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
|
|
1968
2043
|
var gridCols = [
|
|
1969
2044
|
"grid-cols-1",
|
|
@@ -1981,7 +2056,7 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1981
2056
|
readonly,
|
|
1982
2057
|
label
|
|
1983
2058
|
}), /* @__PURE__ */ React16.createElement("div", {
|
|
1984
|
-
className:
|
|
2059
|
+
className: mx2("grid gap-form-gap", gridCols[binding.length - 1])
|
|
1985
2060
|
}, binding.map((prop) => /* @__PURE__ */ React16.createElement(Input11.TextInput, {
|
|
1986
2061
|
key: prop,
|
|
1987
2062
|
type: "number",
|
|
@@ -2000,13 +2075,13 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
2000
2075
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
2001
2076
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
2002
2077
|
var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }) => {
|
|
2003
|
-
const { t } =
|
|
2004
|
-
const [props, setProps] =
|
|
2005
|
-
|
|
2078
|
+
const { t } = useTranslation9(translationKey9);
|
|
2079
|
+
const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
|
|
2080
|
+
useEffect5(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
2006
2081
|
field,
|
|
2007
2082
|
projection
|
|
2008
2083
|
]);
|
|
2009
|
-
const [schemas, setSchemas] =
|
|
2084
|
+
const [schemas, setSchemas] = useState6([]);
|
|
2010
2085
|
useAsyncEffect(async () => {
|
|
2011
2086
|
if (!registry) {
|
|
2012
2087
|
return;
|
|
@@ -2020,17 +2095,17 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2020
2095
|
}, [
|
|
2021
2096
|
registry
|
|
2022
2097
|
]);
|
|
2023
|
-
const [referenceSchema, setReferenceSchema] =
|
|
2024
|
-
|
|
2098
|
+
const [referenceSchema, setReferenceSchema] = useState6();
|
|
2099
|
+
useEffect5(() => {
|
|
2025
2100
|
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
2026
2101
|
}, [
|
|
2027
2102
|
schemas,
|
|
2028
2103
|
props?.referenceSchema
|
|
2029
2104
|
]);
|
|
2030
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
2105
|
+
const [{ fieldSchema }, setFieldSchema] = useState6({
|
|
2031
2106
|
fieldSchema: getFormatSchema(props?.format)
|
|
2032
2107
|
});
|
|
2033
|
-
const fieldMap =
|
|
2108
|
+
const fieldMap = useMemo8(() => ({
|
|
2034
2109
|
["format"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
|
|
2035
2110
|
...props2,
|
|
2036
2111
|
options: FormatEnums.filter((value3) => value3 !== Format4.TypeFormat.None).map((value3) => ({
|
|
@@ -2109,7 +2184,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2109
2184
|
]);
|
|
2110
2185
|
const handleSave = useCallback14((props2) => {
|
|
2111
2186
|
if (view) {
|
|
2112
|
-
|
|
2187
|
+
Obj3.update(view, () => {
|
|
2113
2188
|
projection.setFieldProjection({
|
|
2114
2189
|
field,
|
|
2115
2190
|
props: props2
|
|
@@ -2137,12 +2212,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2137
2212
|
if (!fieldSchema) {
|
|
2138
2213
|
log2.warn("invalid format", {
|
|
2139
2214
|
props
|
|
2140
|
-
}, {
|
|
2141
|
-
F: __dxlog_file2,
|
|
2142
|
-
L: 172,
|
|
2143
|
-
S: void 0,
|
|
2144
|
-
C: (f, a) => f(...a)
|
|
2145
|
-
});
|
|
2215
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 156, S: void 0 });
|
|
2146
2216
|
return null;
|
|
2147
2217
|
}
|
|
2148
2218
|
return /* @__PURE__ */ React17.createElement(Form.Root, {
|
|
@@ -2164,99 +2234,487 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2164
2234
|
}, /* @__PURE__ */ React17.createElement(Form.Content, null, /* @__PURE__ */ React17.createElement(Form.FieldSet, null), /* @__PURE__ */ React17.createElement(Form.Actions, null)));
|
|
2165
2235
|
};
|
|
2166
2236
|
|
|
2237
|
+
// src/components/ObjectForm/ObjectForm.tsx
|
|
2238
|
+
import * as Schema3 from "effect/Schema";
|
|
2239
|
+
import React18, { useCallback as useCallback15, useMemo as useMemo9 } from "react";
|
|
2240
|
+
import { DXN as DXN2, Obj as Obj4, Ref as Ref4, Tag as Tag2, Type as Type2 } from "@dxos/echo";
|
|
2241
|
+
import { splitJsonPath } from "@dxos/echo/internal";
|
|
2242
|
+
import { invariant } from "@dxos/invariant";
|
|
2243
|
+
import { HuePicker as HuePicker2 } from "@dxos/react-ui-pickers";
|
|
2244
|
+
import { isNonNullable } from "@dxos/util";
|
|
2245
|
+
import { translationKey as translationKey10 } from "#translations";
|
|
2246
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectForm/ObjectForm.tsx";
|
|
2247
|
+
var createFieldMap = {
|
|
2248
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
2249
|
+
const handleChange = useCallback15((nextHue) => onValueChange(type, nextHue), [
|
|
2250
|
+
onValueChange,
|
|
2251
|
+
type
|
|
2252
|
+
]);
|
|
2253
|
+
const handleReset = useCallback15(() => onValueChange(type, void 0), [
|
|
2254
|
+
onValueChange,
|
|
2255
|
+
type
|
|
2256
|
+
]);
|
|
2257
|
+
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, layout !== "inline" && /* @__PURE__ */ React18.createElement(Form.Label, {
|
|
2258
|
+
label
|
|
2259
|
+
}), /* @__PURE__ */ React18.createElement(HuePicker2, {
|
|
2260
|
+
value: getValue(),
|
|
2261
|
+
onChange: handleChange,
|
|
2262
|
+
onReset: handleReset
|
|
2263
|
+
}));
|
|
2264
|
+
}
|
|
2265
|
+
};
|
|
2266
|
+
var ObjectForm = ({ object, schema }) => {
|
|
2267
|
+
const db = Obj4.getDatabase(object);
|
|
2268
|
+
const meta = Obj4.getMeta(object);
|
|
2269
|
+
const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN2.parse(tag))).filter(isNonNullable);
|
|
2270
|
+
const values = useMemo9(() => ({
|
|
2271
|
+
tags,
|
|
2272
|
+
...object
|
|
2273
|
+
}), [
|
|
2274
|
+
object,
|
|
2275
|
+
tags
|
|
2276
|
+
]);
|
|
2277
|
+
const formSchema = useMemo9(() => omitId(Schema3.Struct({
|
|
2278
|
+
tags: Schema3.Array(Ref4.Ref(Tag2.Tag)).pipe(Schema3.optional)
|
|
2279
|
+
}).pipe(Schema3.extend(schema))), [
|
|
2280
|
+
schema
|
|
2281
|
+
]);
|
|
2282
|
+
const handleCreate = useCallback15((schema2, values2) => {
|
|
2283
|
+
invariant(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 49, S: void 0, A: ["db", ""] });
|
|
2284
|
+
invariant(Type2.isObjectSchema(schema2), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 50, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
|
|
2285
|
+
const newObject = db.add(Obj4.make(schema2, values2));
|
|
2286
|
+
if (Obj4.instanceOf(Tag2.Tag, newObject)) {
|
|
2287
|
+
Obj4.update(object, (object2) => {
|
|
2288
|
+
Obj4.getMeta(object2).tags = [
|
|
2289
|
+
...Obj4.getMeta(object2).tags ?? [],
|
|
2290
|
+
Obj4.getDXN(newObject).toString()
|
|
2291
|
+
];
|
|
2292
|
+
});
|
|
2293
|
+
}
|
|
2294
|
+
}, []);
|
|
2295
|
+
const handleChange = useCallback15(({ tags: tags2, ...values2 }, { isValid, changed }) => {
|
|
2296
|
+
if (!isValid) {
|
|
2297
|
+
return;
|
|
2298
|
+
}
|
|
2299
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
2300
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath(path)[0] === "tags");
|
|
2301
|
+
if (hasTagsChange) {
|
|
2302
|
+
Obj4.update(object, (object2) => {
|
|
2303
|
+
Obj4.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
|
|
2304
|
+
});
|
|
2305
|
+
}
|
|
2306
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath(path)[0] !== "tags");
|
|
2307
|
+
if (nonTagPaths.length > 0) {
|
|
2308
|
+
Obj4.update(object, () => {
|
|
2309
|
+
for (const path of nonTagPaths) {
|
|
2310
|
+
const parts = splitJsonPath(path);
|
|
2311
|
+
const value3 = Obj4.getValue(values2, parts);
|
|
2312
|
+
Obj4.setValue(object, parts, value3);
|
|
2313
|
+
}
|
|
2314
|
+
});
|
|
2315
|
+
}
|
|
2316
|
+
}, [
|
|
2317
|
+
object
|
|
2318
|
+
]);
|
|
2319
|
+
return /* @__PURE__ */ React18.createElement(Form.Root, {
|
|
2320
|
+
schema: formSchema,
|
|
2321
|
+
defaultValues: values,
|
|
2322
|
+
createTypename: Type2.getTypename(Tag2.Tag),
|
|
2323
|
+
createOptionIcon: "ph--plus--regular",
|
|
2324
|
+
createOptionLabel: [
|
|
2325
|
+
"add-tag.label",
|
|
2326
|
+
{
|
|
2327
|
+
ns: translationKey10
|
|
2328
|
+
}
|
|
2329
|
+
],
|
|
2330
|
+
createInitialValuePath: "label",
|
|
2331
|
+
createFieldMap,
|
|
2332
|
+
db,
|
|
2333
|
+
onValuesChanged: handleChange,
|
|
2334
|
+
onCreate: handleCreate
|
|
2335
|
+
}, /* @__PURE__ */ React18.createElement(Form.Viewport, null, /* @__PURE__ */ React18.createElement(Form.Content, null, /* @__PURE__ */ React18.createElement(Form.FieldSet, null))));
|
|
2336
|
+
};
|
|
2337
|
+
|
|
2338
|
+
// src/components/ObjectProperties/ObjectProperties.tsx
|
|
2339
|
+
import * as Function from "effect/Function";
|
|
2340
|
+
import * as Option5 from "effect/Option";
|
|
2341
|
+
import * as Schema4 from "effect/Schema";
|
|
2342
|
+
import React19, { useCallback as useCallback16, useMemo as useMemo10 } from "react";
|
|
2343
|
+
import { DXN as DXN3, Obj as Obj5, Ref as Ref5, Tag as Tag3, Type as Type3 } from "@dxos/echo";
|
|
2344
|
+
import { splitJsonPath as splitJsonPath2 } from "@dxos/echo/internal";
|
|
2345
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2346
|
+
import { HuePicker as HuePicker3 } from "@dxos/react-ui-pickers";
|
|
2347
|
+
import { FactoryAnnotation } from "@dxos/schema";
|
|
2348
|
+
import { composable as composable2, composableProps as composableProps2 } from "@dxos/ui-theme";
|
|
2349
|
+
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
2350
|
+
import { translationKey as translationKey11 } from "#translations";
|
|
2351
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectProperties/ObjectProperties.tsx";
|
|
2352
|
+
var ObjectProperties = composable2(({ children, object, ...props }, forwardedRef) => {
|
|
2353
|
+
const db = Obj5.getDatabase(object);
|
|
2354
|
+
const meta = Obj5.getMeta(object);
|
|
2355
|
+
const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN3.parse(tag))).filter(isNonNullable2);
|
|
2356
|
+
const values = useMemo10(() => ({
|
|
2357
|
+
tags,
|
|
2358
|
+
...object
|
|
2359
|
+
}), [
|
|
2360
|
+
object,
|
|
2361
|
+
tags
|
|
2362
|
+
]);
|
|
2363
|
+
const formSchema = useMemo10(() => {
|
|
2364
|
+
return Function.pipe(Obj5.getSchema(object), Option5.fromNullable, Option5.map((schema) => omitId(BaseSchema.pipe(Schema4.extend(schema)))), Option5.getOrUndefined);
|
|
2365
|
+
}, [
|
|
2366
|
+
object
|
|
2367
|
+
]);
|
|
2368
|
+
const handleCreate = useCallback16((schema, values2) => {
|
|
2369
|
+
invariant2(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 45, S: void 0, A: ["db", ""] });
|
|
2370
|
+
invariant2(Type3.isObjectSchema(schema), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 46, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
|
|
2371
|
+
const factory = Option5.getOrUndefined(FactoryAnnotation.get(schema));
|
|
2372
|
+
const newObject = factory ? factory(values2) : Obj5.make(schema, values2);
|
|
2373
|
+
return db.add(newObject);
|
|
2374
|
+
}, [
|
|
2375
|
+
db
|
|
2376
|
+
]);
|
|
2377
|
+
const handleChange = useCallback16(({ tags: tags2, ...values2 }, { isValid, changed }) => {
|
|
2378
|
+
if (!isValid) {
|
|
2379
|
+
return;
|
|
2380
|
+
}
|
|
2381
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
2382
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath2(path)[0] === "tags");
|
|
2383
|
+
if (hasTagsChange) {
|
|
2384
|
+
Obj5.update(object, (object2) => {
|
|
2385
|
+
Obj5.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
|
|
2386
|
+
});
|
|
2387
|
+
}
|
|
2388
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath2(path)[0] !== "tags");
|
|
2389
|
+
if (nonTagPaths.length > 0) {
|
|
2390
|
+
Obj5.update(object, () => {
|
|
2391
|
+
for (const path of nonTagPaths) {
|
|
2392
|
+
const parts = splitJsonPath2(path);
|
|
2393
|
+
const value3 = Obj5.getValue(values2, parts);
|
|
2394
|
+
Obj5.setValue(object, parts, value3);
|
|
2395
|
+
}
|
|
2396
|
+
});
|
|
2397
|
+
}
|
|
2398
|
+
}, [
|
|
2399
|
+
object
|
|
2400
|
+
]);
|
|
2401
|
+
if (!formSchema) {
|
|
2402
|
+
return null;
|
|
2403
|
+
}
|
|
2404
|
+
return /* @__PURE__ */ React19.createElement(Form.Root, {
|
|
2405
|
+
schema: formSchema,
|
|
2406
|
+
defaultValues: values,
|
|
2407
|
+
createTypename: Type3.getTypename(Tag3.Tag),
|
|
2408
|
+
createOptionIcon: "ph--plus--regular",
|
|
2409
|
+
createOptionLabel: [
|
|
2410
|
+
"add-tag.label",
|
|
2411
|
+
{
|
|
2412
|
+
ns: translationKey11
|
|
2413
|
+
}
|
|
2414
|
+
],
|
|
2415
|
+
createInitialValuePath: "label",
|
|
2416
|
+
createFieldMap: createFieldMap2,
|
|
2417
|
+
db,
|
|
2418
|
+
onValuesChanged: handleChange,
|
|
2419
|
+
onCreate: handleCreate
|
|
2420
|
+
}, /* @__PURE__ */ React19.createElement(Form.Viewport, {
|
|
2421
|
+
...composableProps2(props),
|
|
2422
|
+
ref: forwardedRef
|
|
2423
|
+
}, /* @__PURE__ */ React19.createElement(Form.Content, null, /* @__PURE__ */ React19.createElement(Form.FieldSet, null), children)));
|
|
2424
|
+
});
|
|
2425
|
+
var createFieldMap2 = {
|
|
2426
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
2427
|
+
const handleChange = useCallback16((nextHue) => onValueChange(type, nextHue), [
|
|
2428
|
+
onValueChange,
|
|
2429
|
+
type
|
|
2430
|
+
]);
|
|
2431
|
+
const handleReset = useCallback16(() => onValueChange(type, void 0), [
|
|
2432
|
+
onValueChange,
|
|
2433
|
+
type
|
|
2434
|
+
]);
|
|
2435
|
+
return /* @__PURE__ */ React19.createElement(React19.Fragment, null, layout !== "inline" && /* @__PURE__ */ React19.createElement(Form.Label, {
|
|
2436
|
+
label
|
|
2437
|
+
}), /* @__PURE__ */ React19.createElement(HuePicker3, {
|
|
2438
|
+
value: getValue(),
|
|
2439
|
+
onChange: handleChange,
|
|
2440
|
+
onReset: handleReset
|
|
2441
|
+
}));
|
|
2442
|
+
}
|
|
2443
|
+
};
|
|
2444
|
+
var BaseSchema = Schema4.Struct({
|
|
2445
|
+
tags: Schema4.Array(Ref5.Ref(Tag3.Tag)).pipe(Schema4.optional)
|
|
2446
|
+
});
|
|
2447
|
+
|
|
2448
|
+
// src/components/Settings/Settings.tsx
|
|
2449
|
+
import React22 from "react";
|
|
2450
|
+
import { ScrollArea as ScrollArea2, toLocalizedString as toLocalizedString2, useTranslation as useTranslation11 } from "@dxos/react-ui";
|
|
2451
|
+
import { composable as composable3, composableProps as composableProps3, mx as mx4 } from "@dxos/ui-theme";
|
|
2452
|
+
import { translationKey as translationKey13 } from "#translations";
|
|
2453
|
+
|
|
2454
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
2455
|
+
import * as SchemaAST5 from "effect/SchemaAST";
|
|
2456
|
+
import * as String3 from "effect/String";
|
|
2457
|
+
import React21, { useCallback as useCallback17, useMemo as useMemo11 } from "react";
|
|
2458
|
+
import { getAnnotation as getAnnotation3 } from "@dxos/effect";
|
|
2459
|
+
import { Input as Input13, Select as Select2 } from "@dxos/react-ui";
|
|
2460
|
+
|
|
2461
|
+
// src/components/Settings/SettingsItem.tsx
|
|
2462
|
+
import React20 from "react";
|
|
2463
|
+
import { Input as Input12, toLocalizedString, useTranslation as useTranslation10 } from "@dxos/react-ui";
|
|
2464
|
+
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2465
|
+
import { translationKey as translationKey12 } from "#translations";
|
|
2466
|
+
var SETTINGS_PANEL_NAME = "Settings.Panel";
|
|
2467
|
+
var SETTINGS_ITEM_NAME = "Settings.Item";
|
|
2468
|
+
var SettingsPanel = ({ classNames, children }) => {
|
|
2469
|
+
return /* @__PURE__ */ React20.createElement("div", {
|
|
2470
|
+
className: mx3("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
|
|
2471
|
+
}, children);
|
|
2472
|
+
};
|
|
2473
|
+
SettingsPanel.displayName = SETTINGS_PANEL_NAME;
|
|
2474
|
+
var SettingsItem = ({ title, description = "", children }) => {
|
|
2475
|
+
const { t } = useTranslation10(translationKey12);
|
|
2476
|
+
return /* @__PURE__ */ React20.createElement(Input12.Root, null, /* @__PURE__ */ React20.createElement(SettingsPanel, {
|
|
2477
|
+
classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
|
|
2478
|
+
}, /* @__PURE__ */ React20.createElement(Input12.Label, {
|
|
2479
|
+
classNames: "pb-trim-md text-base-foreground text-lg md:col-span-2"
|
|
2480
|
+
}, toLocalizedString(title, t)), /* @__PURE__ */ React20.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React20.createElement(Input12.Description, {
|
|
2481
|
+
classNames: "text-base text-description"
|
|
2482
|
+
}, toLocalizedString(description, t))), /* @__PURE__ */ React20.createElement("div", {
|
|
2483
|
+
className: "text-end py-1"
|
|
2484
|
+
}, children)));
|
|
2485
|
+
};
|
|
2486
|
+
SettingsItem.displayName = SETTINGS_ITEM_NAME;
|
|
2487
|
+
|
|
2488
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
2489
|
+
var SettingsFieldSet = ({ schema, values, onValuesChanged, readonly, fieldMap, visible, sort, pathPrefix = "" }) => {
|
|
2490
|
+
const properties = useMemo11(() => {
|
|
2491
|
+
const props = getFormProperties(schema.ast);
|
|
2492
|
+
if (!sort) {
|
|
2493
|
+
return props;
|
|
2494
|
+
}
|
|
2495
|
+
const rank = (name) => {
|
|
2496
|
+
const idx = sort.indexOf(name);
|
|
2497
|
+
return idx === -1 ? Number.POSITIVE_INFINITY : idx;
|
|
2498
|
+
};
|
|
2499
|
+
return [
|
|
2500
|
+
...props
|
|
2501
|
+
].sort(({ name: a }, { name: b }) => rank(a.toString()) - rank(b.toString()));
|
|
2502
|
+
}, [
|
|
2503
|
+
schema,
|
|
2504
|
+
sort
|
|
2505
|
+
]);
|
|
2506
|
+
const handleChange = useCallback17((name, value3) => {
|
|
2507
|
+
onValuesChanged?.({
|
|
2508
|
+
...values,
|
|
2509
|
+
[name]: value3
|
|
2510
|
+
});
|
|
2511
|
+
}, [
|
|
2512
|
+
values,
|
|
2513
|
+
onValuesChanged
|
|
2514
|
+
]);
|
|
2515
|
+
return /* @__PURE__ */ React21.createElement(React21.Fragment, null, properties.map((property) => {
|
|
2516
|
+
const name = property.name.toString();
|
|
2517
|
+
const path = pathPrefix ? `${pathPrefix}.${name}` : name;
|
|
2518
|
+
if (visible && !visible(path, values)) {
|
|
2519
|
+
return null;
|
|
2520
|
+
}
|
|
2521
|
+
const entry = fieldMap?.[name];
|
|
2522
|
+
return /* @__PURE__ */ React21.createElement(SettingsFieldItem, {
|
|
2523
|
+
key: name,
|
|
2524
|
+
path,
|
|
2525
|
+
property,
|
|
2526
|
+
value: values[name],
|
|
2527
|
+
onChange: (value3) => handleChange(name, value3),
|
|
2528
|
+
readonly,
|
|
2529
|
+
customField: typeof entry === "function" ? entry : void 0,
|
|
2530
|
+
nestedFieldMap: typeof entry === "object" ? entry : void 0,
|
|
2531
|
+
visible,
|
|
2532
|
+
sort
|
|
2533
|
+
});
|
|
2534
|
+
}));
|
|
2535
|
+
};
|
|
2536
|
+
SettingsFieldSet.displayName = "Settings.FieldSet";
|
|
2537
|
+
var SettingsFieldItem = ({ property, path, value: value3, onChange, readonly, customField, nestedFieldMap, visible, sort }) => {
|
|
2538
|
+
const { type } = property;
|
|
2539
|
+
const name = property.name.toString();
|
|
2540
|
+
const title = getAnnotation3(SchemaAST5.TitleAnnotationId)(type) ?? String3.capitalize(name);
|
|
2541
|
+
const description = getAnnotation3(SchemaAST5.DescriptionAnnotationId)(type);
|
|
2542
|
+
if (customField) {
|
|
2543
|
+
const CustomField = customField;
|
|
2544
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2545
|
+
title,
|
|
2546
|
+
description
|
|
2547
|
+
}, /* @__PURE__ */ React21.createElement(CustomField, {
|
|
2548
|
+
value: value3,
|
|
2549
|
+
onChange,
|
|
2550
|
+
readonly
|
|
2551
|
+
}));
|
|
2552
|
+
}
|
|
2553
|
+
const fieldType = detectFieldType(type);
|
|
2554
|
+
switch (fieldType) {
|
|
2555
|
+
case "struct":
|
|
2556
|
+
return /* @__PURE__ */ React21.createElement(SettingsFieldSet, {
|
|
2557
|
+
schema: {
|
|
2558
|
+
ast: type
|
|
2559
|
+
},
|
|
2560
|
+
values: value3 ?? {},
|
|
2561
|
+
onValuesChanged: onChange,
|
|
2562
|
+
readonly,
|
|
2563
|
+
fieldMap: nestedFieldMap,
|
|
2564
|
+
visible,
|
|
2565
|
+
sort,
|
|
2566
|
+
pathPrefix: path
|
|
2567
|
+
});
|
|
2568
|
+
case "boolean":
|
|
2569
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2570
|
+
title,
|
|
2571
|
+
description
|
|
2572
|
+
}, /* @__PURE__ */ React21.createElement(Input13.Switch, {
|
|
2573
|
+
disabled: readonly,
|
|
2574
|
+
checked: !!value3,
|
|
2575
|
+
onCheckedChange: (checked) => onChange(!!checked)
|
|
2576
|
+
}));
|
|
2577
|
+
case "select": {
|
|
2578
|
+
const options = getSelectOptionsFromAst(type) ?? [];
|
|
2579
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2580
|
+
title,
|
|
2581
|
+
description
|
|
2582
|
+
}, /* @__PURE__ */ React21.createElement(Select2.Root, {
|
|
2583
|
+
disabled: readonly,
|
|
2584
|
+
value: value3 == null ? "" : globalThis.String(value3),
|
|
2585
|
+
onValueChange: (selected) => {
|
|
2586
|
+
const matched = options.find((option) => globalThis.String(option.value) === selected);
|
|
2587
|
+
onChange(matched?.value ?? selected);
|
|
2588
|
+
}
|
|
2589
|
+
}, /* @__PURE__ */ React21.createElement(Select2.TriggerButton, {
|
|
2590
|
+
disabled: readonly
|
|
2591
|
+
}), /* @__PURE__ */ React21.createElement(Select2.Portal, null, /* @__PURE__ */ React21.createElement(Select2.Content, null, /* @__PURE__ */ React21.createElement(Select2.Viewport, null, options.map((option) => /* @__PURE__ */ React21.createElement(Select2.Option, {
|
|
2592
|
+
key: globalThis.String(option.value),
|
|
2593
|
+
value: globalThis.String(option.value)
|
|
2594
|
+
}, option.label ?? globalThis.String(option.value)))), /* @__PURE__ */ React21.createElement(Select2.Arrow, null)))));
|
|
2595
|
+
}
|
|
2596
|
+
case "string":
|
|
2597
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2598
|
+
title,
|
|
2599
|
+
description
|
|
2600
|
+
}, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
|
|
2601
|
+
disabled: readonly,
|
|
2602
|
+
value: value3 ?? "",
|
|
2603
|
+
onChange: (event) => onChange(event.target.value)
|
|
2604
|
+
}));
|
|
2605
|
+
case "number":
|
|
2606
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2607
|
+
title,
|
|
2608
|
+
description
|
|
2609
|
+
}, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
|
|
2610
|
+
disabled: readonly,
|
|
2611
|
+
type: "number",
|
|
2612
|
+
value: value3 ?? "",
|
|
2613
|
+
onChange: (event) => {
|
|
2614
|
+
if (event.target.value === "") {
|
|
2615
|
+
onChange(void 0);
|
|
2616
|
+
return;
|
|
2617
|
+
}
|
|
2618
|
+
const parsed = Number(event.target.value);
|
|
2619
|
+
onChange(Number.isNaN(parsed) ? void 0 : parsed);
|
|
2620
|
+
}
|
|
2621
|
+
}));
|
|
2622
|
+
default:
|
|
2623
|
+
return null;
|
|
2624
|
+
}
|
|
2625
|
+
};
|
|
2626
|
+
|
|
2167
2627
|
// src/components/Settings/Settings.tsx
|
|
2168
|
-
import React18 from "react";
|
|
2169
|
-
import { Input as Input12, ScrollArea as ScrollArea2, toLocalizedString, useTranslation as useTranslation9 } from "@dxos/react-ui";
|
|
2170
|
-
import { composable as composable2, composableProps as composableProps2, mx as mx4 } from "@dxos/ui-theme";
|
|
2171
2628
|
var SETTINGS_ROOT_NAME = "Settings.Root";
|
|
2172
2629
|
var SETTINGS_VIEWPORT_NAME = "Settings.Viewport";
|
|
2173
2630
|
var SETTINGS_SECTION_NAME = "Settings.Section";
|
|
2174
|
-
var SETTINGS_PANEL_NAME = "Settings.Panel";
|
|
2175
|
-
var SETTINGS_ITEM_NAME = "Settings.Item";
|
|
2176
2631
|
var SettingsRoot = ({ children, classNames }) => {
|
|
2177
|
-
return /* @__PURE__ */
|
|
2632
|
+
return /* @__PURE__ */ React22.createElement("div", {
|
|
2178
2633
|
className: mx4("flex flex-col gap-2", classNames)
|
|
2179
2634
|
}, children);
|
|
2180
2635
|
};
|
|
2181
2636
|
SettingsRoot.displayName = SETTINGS_ROOT_NAME;
|
|
2182
|
-
var SettingsViewport =
|
|
2183
|
-
return /* @__PURE__ */
|
|
2184
|
-
...
|
|
2637
|
+
var SettingsViewport = composable3(({ children, ...props }, forwardedRef) => {
|
|
2638
|
+
return /* @__PURE__ */ React22.createElement(ScrollArea2.Root, {
|
|
2639
|
+
...composableProps3(props),
|
|
2185
2640
|
orientation: "vertical",
|
|
2186
2641
|
centered: true,
|
|
2187
2642
|
thin: true,
|
|
2188
2643
|
ref: forwardedRef
|
|
2189
|
-
}, /* @__PURE__ */
|
|
2644
|
+
}, /* @__PURE__ */ React22.createElement(ScrollArea2.Viewport, {
|
|
2190
2645
|
classNames: "px-4 pointer-coarse:px-2"
|
|
2191
|
-
}, /* @__PURE__ */
|
|
2192
|
-
role: "none",
|
|
2646
|
+
}, /* @__PURE__ */ React22.createElement("div", {
|
|
2193
2647
|
className: "dx-document flex flex-col gap-2 py-4"
|
|
2194
2648
|
}, children)));
|
|
2195
2649
|
});
|
|
2196
2650
|
SettingsViewport.displayName = SETTINGS_VIEWPORT_NAME;
|
|
2197
2651
|
var SettingsSection = ({ title, description, children }) => {
|
|
2198
|
-
const { t } =
|
|
2199
|
-
return /* @__PURE__ */
|
|
2652
|
+
const { t } = useTranslation11(translationKey13);
|
|
2653
|
+
return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("h2", {
|
|
2200
2654
|
className: "px-trim-md mt-trim-md text-xl"
|
|
2201
|
-
},
|
|
2655
|
+
}, toLocalizedString2(title, t)), description && /* @__PURE__ */ React22.createElement("p", {
|
|
2202
2656
|
className: "px-trim-md text-description"
|
|
2203
|
-
},
|
|
2657
|
+
}, toLocalizedString2(description, t)), /* @__PURE__ */ React22.createElement("div", {
|
|
2204
2658
|
className: "w-full pt-trim-md space-y-trim-md"
|
|
2205
2659
|
}, children));
|
|
2206
2660
|
};
|
|
2207
2661
|
SettingsSection.displayName = SETTINGS_SECTION_NAME;
|
|
2208
|
-
var SettingsPanel = ({ classNames, children }) => {
|
|
2209
|
-
return /* @__PURE__ */ React18.createElement("div", {
|
|
2210
|
-
role: "none",
|
|
2211
|
-
className: mx4("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
|
|
2212
|
-
}, children);
|
|
2213
|
-
};
|
|
2214
|
-
SettingsPanel.displayName = SETTINGS_PANEL_NAME;
|
|
2215
|
-
var SettingsItem = ({ title, description = "", children }) => {
|
|
2216
|
-
const { t } = useTranslation9(translationKey);
|
|
2217
|
-
return /* @__PURE__ */ React18.createElement(Input12.Root, null, /* @__PURE__ */ React18.createElement(SettingsPanel, {
|
|
2218
|
-
classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
|
|
2219
|
-
}, /* @__PURE__ */ React18.createElement(Input12.Label, {
|
|
2220
|
-
classNames: "pb-trim-md text-base-surface-text text-lg md:col-span-2"
|
|
2221
|
-
}, toLocalizedString(title, t)), /* @__PURE__ */ React18.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React18.createElement(Input12.Description, {
|
|
2222
|
-
classNames: "text-base text-description"
|
|
2223
|
-
}, toLocalizedString(description, t))), /* @__PURE__ */ React18.createElement("div", {
|
|
2224
|
-
role: "none",
|
|
2225
|
-
className: "text-end py-1"
|
|
2226
|
-
}, children)));
|
|
2227
|
-
};
|
|
2228
|
-
SettingsItem.displayName = SETTINGS_ITEM_NAME;
|
|
2229
2662
|
var Settings = {
|
|
2230
2663
|
Root: SettingsRoot,
|
|
2231
2664
|
Viewport: SettingsViewport,
|
|
2232
2665
|
Section: SettingsSection,
|
|
2233
2666
|
Panel: SettingsPanel,
|
|
2234
|
-
Item: SettingsItem
|
|
2667
|
+
Item: SettingsItem,
|
|
2668
|
+
FieldSet: SettingsFieldSet
|
|
2669
|
+
};
|
|
2670
|
+
|
|
2671
|
+
// src/components/Settings/SettingsSelectField.tsx
|
|
2672
|
+
import React23 from "react";
|
|
2673
|
+
import { Select as Select3 } from "@dxos/react-ui";
|
|
2674
|
+
var createSelectField = ({ options, defaultLabel = "Default" }) => {
|
|
2675
|
+
const normalized = options.map((option) => typeof option === "string" ? {
|
|
2676
|
+
value: option,
|
|
2677
|
+
label: option
|
|
2678
|
+
} : option);
|
|
2679
|
+
const hasDefault = defaultLabel !== null;
|
|
2680
|
+
const sentinel = hasDefault ? `__default__${Math.random().toString(36).slice(2)}` : "";
|
|
2681
|
+
return ({ value: value3, onChange, readonly }) => /* @__PURE__ */ React23.createElement(Select3.Root, {
|
|
2682
|
+
disabled: readonly,
|
|
2683
|
+
value: value3 ?? sentinel,
|
|
2684
|
+
onValueChange: (next) => onChange(hasDefault && next === sentinel ? void 0 : next)
|
|
2685
|
+
}, /* @__PURE__ */ React23.createElement(Select3.TriggerButton, {
|
|
2686
|
+
disabled: readonly
|
|
2687
|
+
}), /* @__PURE__ */ React23.createElement(Select3.Portal, null, /* @__PURE__ */ React23.createElement(Select3.Content, null, /* @__PURE__ */ React23.createElement(Select3.Viewport, null, hasDefault && /* @__PURE__ */ React23.createElement(Select3.Option, {
|
|
2688
|
+
value: sentinel
|
|
2689
|
+
}, defaultLabel), normalized.map((option) => /* @__PURE__ */ React23.createElement(Select3.Option, {
|
|
2690
|
+
key: option.value,
|
|
2691
|
+
value: option.value
|
|
2692
|
+
}, option.label ?? option.value))), /* @__PURE__ */ React23.createElement(Select3.Arrow, null))));
|
|
2235
2693
|
};
|
|
2236
2694
|
|
|
2237
2695
|
// src/components/ViewEditor/ViewEditor.tsx
|
|
2238
2696
|
import { RegistryContext } from "@effect-atom/atom-react";
|
|
2239
|
-
import * as
|
|
2697
|
+
import * as Array4 from "effect/Array";
|
|
2240
2698
|
import * as Match2 from "effect/Match";
|
|
2241
|
-
import * as
|
|
2242
|
-
import * as
|
|
2243
|
-
import
|
|
2244
|
-
import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as
|
|
2245
|
-
import { View } from "@dxos/echo";
|
|
2699
|
+
import * as Option6 from "effect/Option";
|
|
2700
|
+
import * as Schema5 from "effect/Schema";
|
|
2701
|
+
import React24, { forwardRef as forwardRef2, useCallback as useCallback18, useContext, useImperativeHandle, useMemo as useMemo12, useState as useState7 } from "react";
|
|
2702
|
+
import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as Obj6, Query, QueryAST, Ref as Ref6, View } from "@dxos/echo";
|
|
2246
2703
|
import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
|
|
2247
|
-
import { invariant } from "@dxos/invariant";
|
|
2704
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
2248
2705
|
import { useObject, useQuery as useQuery2 } from "@dxos/react-client/echo";
|
|
2249
|
-
import { IconButton as IconButton4, Input as
|
|
2706
|
+
import { IconButton as IconButton4, Input as Input14, Message, useTranslation as useTranslation12 } from "@dxos/react-ui";
|
|
2250
2707
|
import { QueryForm } from "@dxos/react-ui-components";
|
|
2251
2708
|
import { List as List2 } from "@dxos/react-ui-list";
|
|
2252
2709
|
import { ParentLabelAnnotation, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
|
|
2253
|
-
import { mx as mx5, osTranslations as osTranslations2
|
|
2254
|
-
|
|
2710
|
+
import { mx as mx5, osTranslations as osTranslations2 } from "@dxos/ui-theme";
|
|
2711
|
+
import { translationKey as translationKey14 } from "#translations";
|
|
2712
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
|
|
2255
2713
|
var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
|
|
2256
2714
|
const atomRegistry = useContext(RegistryContext);
|
|
2257
2715
|
const schemaReadonly = !isMutable(schema);
|
|
2258
|
-
const { t } =
|
|
2259
|
-
const projectionModel =
|
|
2716
|
+
const { t } = useTranslation12(translationKey14);
|
|
2717
|
+
const projectionModel = useMemo12(() => {
|
|
2260
2718
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2261
2719
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2262
2720
|
const model = new ProjectionModel({
|
|
@@ -2280,21 +2738,21 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
|
|
|
2280
2738
|
if (from._tag !== "scope") {
|
|
2281
2739
|
return void 0;
|
|
2282
2740
|
}
|
|
2283
|
-
return
|
|
2741
|
+
return Option6.fromNullable(from.scope.feeds).pipe(Option6.flatMap((feeds2) => Array4.head(feeds2)), Option6.map(String), Option6.getOrUndefined);
|
|
2284
2742
|
}), Match2.orElse(() => void 0));
|
|
2285
2743
|
const feeds = useQuery2(db, Filter2.type(Feed.Feed));
|
|
2286
|
-
const targetRef =
|
|
2744
|
+
const targetRef = useMemo12(() => {
|
|
2287
2745
|
if (!queueTarget) {
|
|
2288
2746
|
return void 0;
|
|
2289
2747
|
}
|
|
2290
2748
|
const feed = feeds.find((feed2) => Feed.getQueueDxn(feed2)?.toString() === queueTarget);
|
|
2291
|
-
return feed ?
|
|
2749
|
+
return feed ? Ref6.fromDXN(Entity2.getDXN(feed)) : void 0;
|
|
2292
2750
|
}, [
|
|
2293
2751
|
queueTarget,
|
|
2294
2752
|
feeds
|
|
2295
2753
|
]);
|
|
2296
|
-
const viewSchema =
|
|
2297
|
-
const base =
|
|
2754
|
+
const viewSchema = useMemo12(() => {
|
|
2755
|
+
const base = Schema5.Struct({
|
|
2298
2756
|
query: mode === "schema" ? Format5.URL.annotations({
|
|
2299
2757
|
title: "Record type"
|
|
2300
2758
|
}) : QueryAST.Query.annotations({
|
|
@@ -2302,19 +2760,19 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
|
|
|
2302
2760
|
})
|
|
2303
2761
|
});
|
|
2304
2762
|
if (mode === "tag") {
|
|
2305
|
-
return
|
|
2763
|
+
return Schema5.Struct({
|
|
2306
2764
|
...base.fields,
|
|
2307
2765
|
// TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
|
|
2308
|
-
target:
|
|
2766
|
+
target: Ref6.Ref(Feed.Feed).pipe(Schema5.annotations({
|
|
2309
2767
|
title: "Target Feed"
|
|
2310
|
-
}), ParentLabelAnnotation.set(true),
|
|
2311
|
-
}).pipe(
|
|
2768
|
+
}), ParentLabelAnnotation.set(true), Schema5.optional)
|
|
2769
|
+
}).pipe(Schema5.mutable);
|
|
2312
2770
|
}
|
|
2313
|
-
return base.pipe(
|
|
2771
|
+
return base.pipe(Schema5.mutable);
|
|
2314
2772
|
}, [
|
|
2315
2773
|
mode
|
|
2316
2774
|
]);
|
|
2317
|
-
const viewValues =
|
|
2775
|
+
const viewValues = useMemo12(() => ({
|
|
2318
2776
|
query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
|
|
2319
2777
|
target: targetRef
|
|
2320
2778
|
}), [
|
|
@@ -2322,7 +2780,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
|
|
|
2322
2780
|
view.query.ast,
|
|
2323
2781
|
targetRef
|
|
2324
2782
|
]);
|
|
2325
|
-
const fieldMap =
|
|
2783
|
+
const fieldMap = useMemo12(() => mode === "tag" ? customFields({
|
|
2326
2784
|
types,
|
|
2327
2785
|
tags
|
|
2328
2786
|
}) : void 0, [
|
|
@@ -2330,54 +2788,45 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
|
|
|
2330
2788
|
types,
|
|
2331
2789
|
tags
|
|
2332
2790
|
]);
|
|
2333
|
-
const handleUpdate =
|
|
2791
|
+
const handleUpdate = useCallback18((values) => {
|
|
2334
2792
|
const targetValue = values.target;
|
|
2335
|
-
let
|
|
2336
|
-
if (
|
|
2337
|
-
const
|
|
2338
|
-
const feed = feeds.find((feed2) =>
|
|
2793
|
+
let feedDXN;
|
|
2794
|
+
if (Ref6.isRef(targetValue)) {
|
|
2795
|
+
const targetDXN = targetValue.dxn.toString();
|
|
2796
|
+
const feed = feeds.find((feed2) => Obj6.getDXN(feed2).toString() === targetDXN);
|
|
2339
2797
|
if (feed) {
|
|
2340
|
-
|
|
2798
|
+
feedDXN = Feed.getQueueDxn(feed)?.toString();
|
|
2341
2799
|
}
|
|
2342
2800
|
}
|
|
2343
2801
|
const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : JSON.parse(JSON.stringify(values.query));
|
|
2344
|
-
onQueryChanged?.(query,
|
|
2802
|
+
onQueryChanged?.(query, feedDXN);
|
|
2345
2803
|
}, [
|
|
2346
2804
|
onQueryChanged,
|
|
2347
2805
|
mode,
|
|
2348
2806
|
feeds
|
|
2349
2807
|
]);
|
|
2350
|
-
const handleDelete =
|
|
2351
|
-
|
|
2352
|
-
F: __dxlog_file3,
|
|
2353
|
-
L: 185,
|
|
2354
|
-
S: void 0,
|
|
2355
|
-
A: [
|
|
2356
|
-
"!readonly",
|
|
2357
|
-
""
|
|
2358
|
-
]
|
|
2359
|
-
});
|
|
2808
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2809
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 126, S: void 0, A: ["!readonly", ""] });
|
|
2360
2810
|
onDelete?.(fieldId);
|
|
2361
2811
|
}, [
|
|
2362
2812
|
onDelete,
|
|
2363
2813
|
readonly
|
|
2364
2814
|
]);
|
|
2365
|
-
return /* @__PURE__ */
|
|
2366
|
-
role: "none",
|
|
2815
|
+
return /* @__PURE__ */ React24.createElement("div", {
|
|
2367
2816
|
className: mx5(classNames)
|
|
2368
|
-
}, schemaReadonly && !readonly && /* @__PURE__ */
|
|
2817
|
+
}, schemaReadonly && !readonly && /* @__PURE__ */ React24.createElement(Message.Root, {
|
|
2369
2818
|
valence: "info",
|
|
2370
2819
|
classNames: "my-form-padding"
|
|
2371
|
-
}, /* @__PURE__ */
|
|
2820
|
+
}, /* @__PURE__ */ React24.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React24.createElement(Form.Root, {
|
|
2372
2821
|
schema: viewSchema,
|
|
2373
2822
|
values: viewValues,
|
|
2374
2823
|
fieldMap,
|
|
2375
2824
|
db,
|
|
2376
2825
|
onValuesChanged: handleUpdate
|
|
2377
|
-
}, /* @__PURE__ */
|
|
2826
|
+
}, /* @__PURE__ */ React24.createElement(Form.FieldSet, null), /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2378
2827
|
label: t("fields.label"),
|
|
2379
2828
|
asChild: true
|
|
2380
|
-
}), /* @__PURE__ */
|
|
2829
|
+
}), /* @__PURE__ */ React24.createElement(FieldList, {
|
|
2381
2830
|
schema,
|
|
2382
2831
|
view,
|
|
2383
2832
|
registry,
|
|
@@ -2389,9 +2838,9 @@ var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode =
|
|
|
2389
2838
|
var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDelete }) => {
|
|
2390
2839
|
const atomRegistry = useContext(RegistryContext);
|
|
2391
2840
|
const schemaReadonly = !isMutable(schema);
|
|
2392
|
-
const { t } =
|
|
2841
|
+
const { t } = useTranslation12(translationKey14);
|
|
2393
2842
|
const [viewSnapshot] = useObject(view);
|
|
2394
|
-
const projectionModel =
|
|
2843
|
+
const projectionModel = useMemo12(() => {
|
|
2395
2844
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2396
2845
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2397
2846
|
const model = new ProjectionModel({
|
|
@@ -2406,38 +2855,22 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2406
2855
|
schema,
|
|
2407
2856
|
view
|
|
2408
2857
|
]);
|
|
2409
|
-
const [expandedField, setExpandedField] =
|
|
2410
|
-
const handleAdd =
|
|
2411
|
-
|
|
2412
|
-
F: __dxlog_file3,
|
|
2413
|
-
L: 250,
|
|
2414
|
-
S: void 0,
|
|
2415
|
-
A: [
|
|
2416
|
-
"!readonly",
|
|
2417
|
-
""
|
|
2418
|
-
]
|
|
2419
|
-
});
|
|
2858
|
+
const [expandedField, setExpandedField] = useState7();
|
|
2859
|
+
const handleAdd = useCallback18(() => {
|
|
2860
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 181, S: void 0, A: ["!readonly", ""] });
|
|
2420
2861
|
const field = projectionModel.createFieldProjection();
|
|
2421
2862
|
setExpandedField(field.id);
|
|
2422
2863
|
}, [
|
|
2423
2864
|
projectionModel,
|
|
2424
2865
|
readonly
|
|
2425
2866
|
]);
|
|
2426
|
-
const handleToggleField =
|
|
2867
|
+
const handleToggleField = useCallback18((field) => {
|
|
2427
2868
|
setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
|
|
2428
2869
|
}, [
|
|
2429
2870
|
readonly
|
|
2430
2871
|
]);
|
|
2431
|
-
const handleDelete =
|
|
2432
|
-
|
|
2433
|
-
F: __dxlog_file3,
|
|
2434
|
-
L: 264,
|
|
2435
|
-
S: void 0,
|
|
2436
|
-
A: [
|
|
2437
|
-
"!readonly",
|
|
2438
|
-
""
|
|
2439
|
-
]
|
|
2440
|
-
});
|
|
2872
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2873
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 194, S: void 0, A: ["!readonly", ""] });
|
|
2441
2874
|
if (fieldId === expandedField) {
|
|
2442
2875
|
setExpandedField(void 0);
|
|
2443
2876
|
}
|
|
@@ -2447,36 +2880,28 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2447
2880
|
onDelete,
|
|
2448
2881
|
readonly
|
|
2449
2882
|
]);
|
|
2450
|
-
const handleMove =
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
L: 276,
|
|
2454
|
-
S: void 0,
|
|
2455
|
-
A: [
|
|
2456
|
-
"!readonly",
|
|
2457
|
-
""
|
|
2458
|
-
]
|
|
2459
|
-
});
|
|
2460
|
-
Obj3.change(view, (obj) => {
|
|
2883
|
+
const handleMove = useCallback18((fromIndex, toIndex) => {
|
|
2884
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 205, S: void 0, A: ["!readonly", ""] });
|
|
2885
|
+
Obj6.update(view, (view2) => {
|
|
2461
2886
|
const fields = [
|
|
2462
|
-
...
|
|
2887
|
+
...view2.projection.fields
|
|
2463
2888
|
];
|
|
2464
2889
|
const [moved] = fields.splice(fromIndex, 1);
|
|
2465
2890
|
fields.splice(toIndex, 0, moved);
|
|
2466
|
-
|
|
2891
|
+
view2.projection.fields = fields;
|
|
2467
2892
|
});
|
|
2468
2893
|
}, [
|
|
2469
2894
|
view,
|
|
2470
2895
|
readonly
|
|
2471
2896
|
]);
|
|
2472
|
-
const handleClose =
|
|
2473
|
-
const handleHide =
|
|
2897
|
+
const handleClose = useCallback18(() => setExpandedField(void 0), []);
|
|
2898
|
+
const handleHide = useCallback18((fieldId) => {
|
|
2474
2899
|
setExpandedField(void 0);
|
|
2475
2900
|
projectionModel.hideFieldProjection(fieldId);
|
|
2476
2901
|
}, [
|
|
2477
2902
|
projectionModel
|
|
2478
2903
|
]);
|
|
2479
|
-
const handleShow =
|
|
2904
|
+
const handleShow = useCallback18((property) => {
|
|
2480
2905
|
setExpandedField(void 0);
|
|
2481
2906
|
projectionModel.showFieldProjection(property);
|
|
2482
2907
|
}, [
|
|
@@ -2485,46 +2910,45 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2485
2910
|
if (!viewSnapshot) {
|
|
2486
2911
|
return null;
|
|
2487
2912
|
}
|
|
2488
|
-
return /* @__PURE__ */
|
|
2913
|
+
return /* @__PURE__ */ React24.createElement(List2.Root, {
|
|
2489
2914
|
items: viewSnapshot.projection.fields,
|
|
2490
|
-
isItem:
|
|
2915
|
+
isItem: Schema5.is(View.FieldSchema),
|
|
2491
2916
|
getId: (field) => field.id,
|
|
2492
2917
|
onMove: readonly ? void 0 : handleMove,
|
|
2493
2918
|
readonly
|
|
2494
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
2919
|
+
}, ({ items: fields }) => /* @__PURE__ */ React24.createElement(React24.Fragment, null, showHeading && /* @__PURE__ */ React24.createElement("h3", {
|
|
2495
2920
|
className: "text-sm"
|
|
2496
|
-
}, t("field-path.label")), /* @__PURE__ */
|
|
2921
|
+
}, t("field-path.label")), /* @__PURE__ */ React24.createElement("div", {
|
|
2497
2922
|
role: "list",
|
|
2498
2923
|
className: "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]"
|
|
2499
2924
|
}, fields?.map((field) => {
|
|
2500
2925
|
const hidden = field.visible === false;
|
|
2501
|
-
return /* @__PURE__ */
|
|
2926
|
+
return /* @__PURE__ */ React24.createElement(List2.Item, {
|
|
2502
2927
|
key: field.id,
|
|
2503
2928
|
item: field,
|
|
2504
2929
|
classNames: "grid grid-cols-subgrid col-span-5",
|
|
2505
2930
|
"aria-expanded": expandedField === field.id
|
|
2506
|
-
}, /* @__PURE__ */
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
}, /* @__PURE__ */ React19.createElement(List2.ItemDragHandle, {
|
|
2931
|
+
}, /* @__PURE__ */ React24.createElement("div", {
|
|
2932
|
+
className: "grid grid-cols-subgrid col-span-5 rounded-xs cursor-pointer min-h-10 dx-hover"
|
|
2933
|
+
}, /* @__PURE__ */ React24.createElement(List2.ItemDragHandle, {
|
|
2510
2934
|
disabled: readonly || schemaReadonly
|
|
2511
|
-
}), /* @__PURE__ */
|
|
2935
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemTitle, {
|
|
2512
2936
|
classNames: hidden && "text-subdued",
|
|
2513
2937
|
onClick: () => handleToggleField(field)
|
|
2514
|
-
}, field.path), /* @__PURE__ */
|
|
2515
|
-
label: t(hidden ? "show
|
|
2938
|
+
}, field.path), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2939
|
+
label: t(hidden ? "show-field.label" : "hide-field.label"),
|
|
2516
2940
|
"data-testid": hidden ? "show-field-button" : "hide-field-button",
|
|
2517
2941
|
icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
|
|
2518
2942
|
autoHide: false,
|
|
2519
2943
|
disabled: readonly || !hidden && projectionModel.getFields().length <= 1,
|
|
2520
2944
|
onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
|
|
2521
|
-
}), !readonly && /* @__PURE__ */
|
|
2945
|
+
}), !readonly && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(List2.ItemDeleteButton, {
|
|
2522
2946
|
label: t("delete-field.label"),
|
|
2523
2947
|
autoHide: false,
|
|
2524
2948
|
disabled: readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1,
|
|
2525
2949
|
onClick: () => handleDelete(field.id),
|
|
2526
2950
|
"data-testid": "field.delete"
|
|
2527
|
-
}), /* @__PURE__ */
|
|
2951
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2528
2952
|
iconOnly: true,
|
|
2529
2953
|
variant: "ghost",
|
|
2530
2954
|
label: t("toggle-expand.label", {
|
|
@@ -2533,20 +2957,18 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2533
2957
|
icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
2534
2958
|
onClick: () => handleToggleField(field),
|
|
2535
2959
|
"data-testid": "field.toggle"
|
|
2536
|
-
}))), expandedField === field.id && !readonly && /* @__PURE__ */
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
}, /* @__PURE__ */ React19.createElement(FieldEditor, {
|
|
2960
|
+
}))), expandedField === field.id && !readonly && /* @__PURE__ */ React24.createElement("div", {
|
|
2961
|
+
className: "col-span-full mt-1 mb-1 border border-separator rounded-md"
|
|
2962
|
+
}, /* @__PURE__ */ React24.createElement(FieldEditor, {
|
|
2540
2963
|
readonly: readonly || schemaReadonly,
|
|
2541
2964
|
registry,
|
|
2542
2965
|
projection: projectionModel,
|
|
2543
2966
|
field,
|
|
2544
2967
|
onSave: handleClose
|
|
2545
2968
|
})));
|
|
2546
|
-
})), !readonly && !expandedField && /* @__PURE__ */
|
|
2547
|
-
role: "none",
|
|
2969
|
+
})), !readonly && !expandedField && /* @__PURE__ */ React24.createElement("div", {
|
|
2548
2970
|
className: "my-form-padding"
|
|
2549
|
-
}, /* @__PURE__ */
|
|
2971
|
+
}, /* @__PURE__ */ React24.createElement(IconButton4, {
|
|
2550
2972
|
icon: "ph--plus--regular",
|
|
2551
2973
|
label: t("add-property-button.label"),
|
|
2552
2974
|
onClick: handleAdd,
|
|
@@ -2556,13 +2978,13 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2556
2978
|
};
|
|
2557
2979
|
var customFields = ({ types, tags }) => ({
|
|
2558
2980
|
query: ({ type, readonly, label, getValue, onValueChange }) => {
|
|
2559
|
-
const handleChange =
|
|
2981
|
+
const handleChange = useCallback18((query) => onValueChange(type, query.ast), [
|
|
2560
2982
|
onValueChange
|
|
2561
2983
|
]);
|
|
2562
|
-
return /* @__PURE__ */
|
|
2984
|
+
return /* @__PURE__ */ React24.createElement(Input14.Root, null, /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2563
2985
|
readonly,
|
|
2564
2986
|
label
|
|
2565
|
-
}), /* @__PURE__ */
|
|
2987
|
+
}), /* @__PURE__ */ React24.createElement(QueryForm, {
|
|
2566
2988
|
initialQuery: getValue(),
|
|
2567
2989
|
types,
|
|
2568
2990
|
tags,
|
|
@@ -2581,7 +3003,9 @@ export {
|
|
|
2581
3003
|
GeoPointField,
|
|
2582
3004
|
MarkdownField,
|
|
2583
3005
|
NumberField,
|
|
3006
|
+
ObjectForm,
|
|
2584
3007
|
ObjectPicker,
|
|
3008
|
+
ObjectProperties,
|
|
2585
3009
|
RefField,
|
|
2586
3010
|
SelectField,
|
|
2587
3011
|
SelectOptionField,
|
|
@@ -2591,15 +3015,18 @@ export {
|
|
|
2591
3015
|
TupleField,
|
|
2592
3016
|
ViewEditor,
|
|
2593
3017
|
cellClassesForFieldType,
|
|
3018
|
+
createSelectField,
|
|
3019
|
+
detectFieldType,
|
|
2594
3020
|
formatForDisplay,
|
|
2595
3021
|
formatForEditing,
|
|
2596
3022
|
getDefaultValue,
|
|
2597
3023
|
getFormProperties,
|
|
2598
3024
|
getRefProps,
|
|
3025
|
+
getSelectOptionsFromAst,
|
|
3026
|
+
omitHiddenFormFields,
|
|
2599
3027
|
omitId,
|
|
2600
3028
|
parseValue,
|
|
2601
3029
|
pathNotUniqueError,
|
|
2602
|
-
translations,
|
|
2603
3030
|
useFormContext,
|
|
2604
3031
|
useFormFieldState,
|
|
2605
3032
|
useFormHandler,
|