@dxos/react-ui-form 0.8.4-main.d05673bc65 → 0.8.4-main.d9fc60f731
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 +2008 -840
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/translations.mjs +83 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +2008 -840
- 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 +85 -0
- package/dist/lib/node-esm/translations.mjs.map +7 -0
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +2 -2
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +64 -61
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +71 -17
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +148 -86
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormField.d.ts +24 -8
- package/dist/types/src/components/Form/FormField.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormFieldComponent.d.ts +26 -13
- 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 +11 -9
- package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormTooltipsContext.d.ts +19 -0
- package/dist/types/src/components/Form/FormTooltipsContext.d.ts.map +1 -0
- package/dist/types/src/components/Form/Layout/FormLayout.d.ts +50 -0
- package/dist/types/src/components/Form/Layout/FormLayout.d.ts.map +1 -0
- package/dist/types/src/components/Form/Layout/FormLayout.stories.d.ts +119 -0
- package/dist/types/src/components/Form/Layout/FormLayout.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/Layout/FormLayout.stories.test.d.ts +2 -0
- package/dist/types/src/components/Form/Layout/FormLayout.stories.test.d.ts.map +1 -0
- package/dist/types/src/components/Form/Layout/FormLayout.test.d.ts +2 -0
- package/dist/types/src/components/Form/Layout/FormLayout.test.d.ts.map +1 -0
- package/dist/types/src/components/Form/Layout/annotation.d.ts +30 -0
- package/dist/types/src/components/Form/Layout/annotation.d.ts.map +1 -0
- package/dist/types/src/components/Form/Layout/index.d.ts +4 -0
- package/dist/types/src/components/Form/Layout/index.d.ts.map +1 -0
- package/dist/types/src/components/Form/Layout/parser.d.ts +31 -0
- package/dist/types/src/components/Form/Layout/parser.d.ts.map +1 -0
- package/dist/types/src/components/Form/Layout/parser.test.d.ts +2 -0
- package/dist/types/src/components/Form/Layout/parser.test.d.ts.map +1 -0
- 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/DateField.d.ts +4 -0
- package/dist/types/src/components/Form/fields/DateField.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/GeoPointField.d.ts +1 -1
- package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/InlineRefField.d.ts +13 -0
- package/dist/types/src/components/Form/fields/InlineRefField.d.ts.map +1 -0
- 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 +85 -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 +12 -6
- package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectField.d.ts +4 -1
- package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts +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 +64 -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 +1 -1
- package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/index.d.ts +2 -0
- package/dist/types/src/components/Form/fields/index.d.ts.map +1 -1
- package/dist/types/src/components/Form/index.d.ts +3 -0
- package/dist/types/src/components/Form/index.d.ts.map +1 -1
- package/dist/types/src/components/Form/meta-tags.d.ts +30 -0
- package/dist/types/src/components/Form/meta-tags.d.ts.map +1 -0
- package/dist/types/src/components/Form/meta-tags.test.d.ts +2 -0
- package/dist/types/src/components/Form/meta-tags.test.d.ts.map +1 -0
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +8 -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 +28 -6
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +64 -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 +128 -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/ObjectTree/ObjectTree.d.ts +9 -0
- package/dist/types/src/components/ObjectTree/ObjectTree.d.ts.map +1 -0
- package/dist/types/src/components/ObjectTree/ObjectTree.stories.d.ts +87 -0
- package/dist/types/src/components/ObjectTree/ObjectTree.stories.d.ts.map +1 -0
- package/dist/types/src/components/ObjectTree/index.d.ts +2 -0
- package/dist/types/src/components/ObjectTree/index.d.ts.map +1 -0
- package/dist/types/src/components/Settings/Settings.d.ts +28 -33
- package/dist/types/src/components/Settings/Settings.d.ts.map +1 -1
- package/dist/types/src/components/Settings/Settings.stories.d.ts +65 -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 +9 -11
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +68 -66
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +3 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +13 -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 +2 -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 +64 -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 +18 -1
- package/dist/types/src/util/properties.d.ts.map +1 -1
- package/dist/types/src/util/properties.test.d.ts +2 -0
- package/dist/types/src/util/properties.test.d.ts.map +1 -0
- package/dist/types/src/util/refs.d.ts +1 -0
- package/dist/types/src/util/refs.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +48 -41
- package/src/components/FieldEditor/FieldEditor.stories.tsx +4 -4
- package/src/components/FieldEditor/FieldEditor.test.tsx +4 -2
- package/src/components/FieldEditor/FieldEditor.tsx +23 -17
- package/src/components/Form/AUDIT.md +17 -0
- package/src/components/Form/Form.stories.tsx +46 -65
- package/src/components/Form/Form.tsx +176 -60
- package/src/components/Form/FormField.tsx +107 -38
- package/src/components/Form/FormFieldComponent.tsx +77 -20
- package/src/components/Form/FormFieldSet.tsx +128 -78
- package/src/components/Form/FormTooltipsContext.ts +25 -0
- package/src/components/Form/Layout/FormLayout.stories.test.tsx +51 -0
- package/src/components/Form/Layout/FormLayout.stories.tsx +422 -0
- package/src/components/Form/Layout/FormLayout.test.ts +59 -0
- package/src/components/Form/Layout/FormLayout.tsx +251 -0
- package/src/components/Form/Layout/annotation.ts +38 -0
- package/src/components/Form/Layout/index.ts +7 -0
- package/src/components/Form/Layout/parser.test.ts +120 -0
- package/src/components/Form/Layout/parser.ts +167 -0
- package/src/components/Form/fields/ArrayField.tsx +64 -35
- package/src/components/Form/fields/DateField.tsx +101 -0
- package/src/components/Form/fields/GeoPointField.tsx +12 -8
- package/src/components/Form/fields/InlineRefField.tsx +146 -0
- 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 +83 -42
- package/src/components/Form/fields/SelectField.tsx +17 -5
- package/src/components/Form/fields/SelectOptionField.stories.tsx +8 -6
- package/src/components/Form/fields/SelectOptionField.tsx +14 -13
- package/src/components/Form/fields/TextAreaField.tsx +1 -1
- package/src/components/Form/fields/TextField.tsx +2 -2
- package/src/components/Form/fields/TupleField.tsx +3 -2
- package/src/components/Form/fields/index.ts +2 -0
- package/src/components/Form/index.ts +3 -0
- package/src/components/Form/meta-tags.test.ts +47 -0
- package/src/components/Form/meta-tags.ts +33 -0
- package/src/components/ObjectForm/ObjectForm.tsx +109 -0
- package/src/components/ObjectForm/index.ts +5 -0
- package/src/components/ObjectPicker/ObjectPicker.stories.tsx +13 -11
- package/src/components/ObjectPicker/ObjectPicker.tsx +93 -66
- package/src/components/ObjectProperties/ObjectProperties.stories.tsx +350 -0
- package/src/components/ObjectProperties/ObjectProperties.test.tsx +111 -0
- package/src/components/ObjectProperties/ObjectProperties.tsx +144 -0
- package/src/components/ObjectProperties/index.ts +5 -0
- package/src/components/ObjectTree/ObjectTree.stories.tsx +134 -0
- package/src/components/ObjectTree/ObjectTree.tsx +190 -0
- package/src/components/ObjectTree/index.ts +5 -0
- package/src/components/Settings/AUDIT.md +51 -0
- package/src/components/Settings/Settings.stories.tsx +69 -21
- package/src/components/Settings/Settings.tsx +32 -181
- 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 +45 -51
- package/src/components/ViewEditor/ViewEditor.test.tsx +11 -9
- package/src/components/ViewEditor/ViewEditor.tsx +45 -55
- package/src/components/index.ts +3 -0
- package/src/components/testing.tsx +19 -11
- package/src/hooks/useKeyHandler.tsx +7 -7
- package/src/index.ts +0 -4
- package/src/translations.ts +67 -63
- package/src/util/field-type.ts +60 -0
- package/src/util/index.ts +1 -0
- package/src/util/properties.test.ts +121 -0
- package/src/util/properties.ts +47 -4
- package/src/util/refs.ts +7 -3
- package/src/vite-env.d.ts +10 -0
|
@@ -1,87 +1,11 @@
|
|
|
1
|
-
// src/translations.ts
|
|
2
|
-
var translationKey = "@dxos/react-ui-form";
|
|
3
|
-
var translations = [
|
|
4
|
-
{
|
|
5
|
-
"en-US": {
|
|
6
|
-
[translationKey]: {
|
|
7
|
-
"fields label": "Fields",
|
|
8
|
-
"hidden fields label": "Hidden Fields",
|
|
9
|
-
"empty readonly ref field label": "(none)",
|
|
10
|
-
// TODO(burdon): Standardize field/property.
|
|
11
|
-
"add property button label": "Add property",
|
|
12
|
-
"field property label": "Property",
|
|
13
|
-
"field property placeholder": "Property name",
|
|
14
|
-
"field format label": "Type",
|
|
15
|
-
"field path label": "Field path",
|
|
16
|
-
"add field": "Add field",
|
|
17
|
-
"delete field": "Delete field",
|
|
18
|
-
"field limit reached": "Maximum number of fields reached",
|
|
19
|
-
"boolean input true value": "Yes",
|
|
20
|
-
"boolean input false value": "No",
|
|
21
|
-
"show field label": "Show field",
|
|
22
|
-
"hide field label": "Hide field",
|
|
23
|
-
"delete field label": "Delete field",
|
|
24
|
-
"ref field combobox input placeholder": "Search\u2026",
|
|
25
|
-
"ref field placeholder_one": "Select\u2026",
|
|
26
|
-
"ref field placeholder_other": "Select items\u2026",
|
|
27
|
-
"example placeholder": "Example",
|
|
28
|
-
"latitude placeholder": "Latitude (e.g., 40.7128)",
|
|
29
|
-
"longitude placeholder": "Longitude (e.g., -74.0060)",
|
|
30
|
-
"cancel button label": "Cancel",
|
|
31
|
-
"save button label": "Save",
|
|
32
|
-
// FormatEnum
|
|
33
|
-
"format boolean": "Boolean",
|
|
34
|
-
"format currency": "Currency",
|
|
35
|
-
"format date": "Date",
|
|
36
|
-
"format date-time": "DateTime",
|
|
37
|
-
"format did": "DID",
|
|
38
|
-
"format duration": "Duration",
|
|
39
|
-
"format dxn": "DXN",
|
|
40
|
-
"format email": "Email",
|
|
41
|
-
"format formula": "Formula",
|
|
42
|
-
"format hostname": "Hostname",
|
|
43
|
-
"format integer": "Integer",
|
|
44
|
-
"format json": "JSON",
|
|
45
|
-
"format lnglat": "Geopoint",
|
|
46
|
-
"format markdown": "Markdown",
|
|
47
|
-
"format percent": "Percent",
|
|
48
|
-
"format ref": "Reference",
|
|
49
|
-
"format regex": "RegExp",
|
|
50
|
-
"format string": "String",
|
|
51
|
-
"format single-select": "Select",
|
|
52
|
-
"format multi-select": "Multi-select",
|
|
53
|
-
"format text": "Long text",
|
|
54
|
-
"format time": "Time",
|
|
55
|
-
"format timestamp": "Timestamp",
|
|
56
|
-
"format user": "User",
|
|
57
|
-
"format number": "Number",
|
|
58
|
-
"format uri": "URI",
|
|
59
|
-
"format url": "URL",
|
|
60
|
-
"format uuid": "UUID",
|
|
61
|
-
// GeoPointField.
|
|
62
|
-
"latitude label": "Latitude",
|
|
63
|
-
"longitude label": "Longitude",
|
|
64
|
-
// SelectOptionsField.
|
|
65
|
-
"select option label": "Label",
|
|
66
|
-
"select option label placeholder": "Option label",
|
|
67
|
-
"select option color": "Color",
|
|
68
|
-
"select option delete": "Delete",
|
|
69
|
-
"select option add": "Add option",
|
|
70
|
-
// System schema message.
|
|
71
|
-
"system schema title": "System type",
|
|
72
|
-
"system schema description": "System type: cannot add or remove fields."
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
];
|
|
77
|
-
|
|
78
1
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
79
|
-
import
|
|
80
|
-
import { Obj as
|
|
81
|
-
import { Format as
|
|
2
|
+
import React20, { useCallback as useCallback16, useEffect as useEffect5, useMemo as useMemo10, useState as useState6 } from "react";
|
|
3
|
+
import { Filter as Filter2, Obj as Obj4, Type as Type4 } from "@dxos/echo";
|
|
4
|
+
import { Format as Format6, FormatEnums, formatToType } from "@dxos/echo/internal";
|
|
82
5
|
import { log as log2 } from "@dxos/log";
|
|
83
|
-
import { useAsyncEffect, useTranslation as
|
|
6
|
+
import { useAsyncEffect, useTranslation as useTranslation10 } from "@dxos/react-ui";
|
|
84
7
|
import { formatToAdditionalPropertyAttributes, getFormatSchema } from "@dxos/schema";
|
|
8
|
+
import { translationKey as translationKey10 } from "#translations";
|
|
85
9
|
|
|
86
10
|
// src/util/field.ts
|
|
87
11
|
import { Format, GeoLocation, TypeEnum } from "@dxos/echo/internal";
|
|
@@ -204,6 +128,46 @@ var pathNotUniqueError = (path) => ({
|
|
|
204
128
|
message: `'${path}' is already present`
|
|
205
129
|
});
|
|
206
130
|
|
|
131
|
+
// src/util/field-type.ts
|
|
132
|
+
import * as SchemaAST from "effect/SchemaAST";
|
|
133
|
+
import { getAnnotation, isLiteralUnion } from "@dxos/effect";
|
|
134
|
+
var detectFieldType = (ast) => {
|
|
135
|
+
if (isLiteralUnion(ast)) {
|
|
136
|
+
return "select";
|
|
137
|
+
}
|
|
138
|
+
if (SchemaAST.isTypeLiteral(ast)) {
|
|
139
|
+
return "struct";
|
|
140
|
+
}
|
|
141
|
+
switch (ast._tag) {
|
|
142
|
+
case "BooleanKeyword":
|
|
143
|
+
return "boolean";
|
|
144
|
+
case "StringKeyword":
|
|
145
|
+
return "string";
|
|
146
|
+
case "NumberKeyword":
|
|
147
|
+
return "number";
|
|
148
|
+
}
|
|
149
|
+
return void 0;
|
|
150
|
+
};
|
|
151
|
+
var getSelectOptionsFromAst = (ast) => {
|
|
152
|
+
if (!isLiteralUnion(ast)) {
|
|
153
|
+
return void 0;
|
|
154
|
+
}
|
|
155
|
+
return ast.types.flatMap((literalNode) => {
|
|
156
|
+
const value3 = literalNode.literal;
|
|
157
|
+
if (typeof value3 !== "string" && typeof value3 !== "number") {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
const title = getAnnotation(SchemaAST.TitleAnnotationId, false)(literalNode);
|
|
161
|
+
const label = title ?? (typeof value3 === "string" ? value3.charAt(0).toUpperCase() + value3.slice(1) : String(value3));
|
|
162
|
+
return [
|
|
163
|
+
{
|
|
164
|
+
value: value3,
|
|
165
|
+
label
|
|
166
|
+
}
|
|
167
|
+
];
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
|
|
207
171
|
// src/util/formatting.ts
|
|
208
172
|
import { format as formatDate } from "date-fns/format";
|
|
209
173
|
import { Format as Format2, GeoLocation as GeoLocation2, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
|
|
@@ -344,51 +308,85 @@ var formatForEditing = ({ type, format, value: value3, locale = void 0 }) => {
|
|
|
344
308
|
|
|
345
309
|
// src/util/properties.ts
|
|
346
310
|
import * as Option from "effect/Option";
|
|
311
|
+
import * as SchemaAST2 from "effect/SchemaAST";
|
|
347
312
|
import { Annotation } from "@dxos/echo";
|
|
348
|
-
import { getProperties } from "@dxos/effect";
|
|
313
|
+
import { getProperties, isArrayType, isNestedType } from "@dxos/effect";
|
|
314
|
+
var unwrapOptional = (prop) => {
|
|
315
|
+
if (!prop.isOptional || !SchemaAST2.isUnion(prop.type)) {
|
|
316
|
+
return prop.type;
|
|
317
|
+
}
|
|
318
|
+
const defined = prop.type.types.filter((type) => type._tag !== "UndefinedKeyword");
|
|
319
|
+
if (defined.length === 0) {
|
|
320
|
+
return prop.type;
|
|
321
|
+
}
|
|
322
|
+
return defined.length === 1 ? defined[0] : SchemaAST2.Union.make(defined, prop.type.annotations);
|
|
323
|
+
};
|
|
349
324
|
var getFormProperties = (ast) => {
|
|
350
|
-
|
|
325
|
+
const signatures = SchemaAST2.getPropertySignatures(ast);
|
|
326
|
+
const rawByName = new Map(signatures.map((prop) => [
|
|
327
|
+
prop.name,
|
|
328
|
+
unwrapOptional(prop)
|
|
329
|
+
]));
|
|
330
|
+
const hidden = new Set(signatures.filter((prop) => Annotation.FormInputAnnotation.getFromAst(unwrapOptional(prop)).pipe(Option.getOrElse(() => true)) === false).map((prop) => prop.name));
|
|
331
|
+
return getProperties(ast).filter((prop) => !hidden.has(prop.name)).map((prop) => {
|
|
332
|
+
const raw = rawByName.get(prop.name);
|
|
333
|
+
return raw && (isNestedType(raw) || isArrayType(raw)) ? {
|
|
334
|
+
...prop,
|
|
335
|
+
type: raw
|
|
336
|
+
} : prop;
|
|
337
|
+
});
|
|
351
338
|
};
|
|
352
339
|
|
|
353
340
|
// src/util/refs.ts
|
|
354
341
|
import { Ref } from "@dxos/echo";
|
|
355
|
-
import {
|
|
342
|
+
import { ReferenceAnnotationId } from "@dxos/echo/internal";
|
|
343
|
+
import { findAnnotation, getArrayElementType, isArrayType as isArrayType2 } from "@dxos/effect";
|
|
356
344
|
var getRefProps = (ast) => {
|
|
357
|
-
if (
|
|
345
|
+
if (isArrayType2(ast)) {
|
|
358
346
|
const elementType = getArrayElementType(ast);
|
|
359
347
|
if (elementType) {
|
|
360
348
|
if (Ref.isRefType(elementType)) {
|
|
349
|
+
const typename = findAnnotation(elementType, ReferenceAnnotationId)?.typename;
|
|
361
350
|
return {
|
|
362
351
|
ast: elementType,
|
|
363
|
-
isArray: true
|
|
352
|
+
isArray: true,
|
|
353
|
+
typename
|
|
364
354
|
};
|
|
365
355
|
}
|
|
366
356
|
}
|
|
367
357
|
}
|
|
368
358
|
if (Ref.isRefType(ast)) {
|
|
359
|
+
const typename = findAnnotation(ast, ReferenceAnnotationId)?.typename;
|
|
369
360
|
return {
|
|
370
361
|
ast,
|
|
371
|
-
isArray: false
|
|
362
|
+
isArray: false,
|
|
363
|
+
typename
|
|
372
364
|
};
|
|
373
365
|
}
|
|
374
366
|
return void 0;
|
|
375
367
|
};
|
|
376
368
|
|
|
377
369
|
// src/components/Form/fields/ArrayField.tsx
|
|
378
|
-
import * as
|
|
379
|
-
import * as
|
|
380
|
-
import
|
|
381
|
-
import {
|
|
382
|
-
import {
|
|
370
|
+
import * as Option6 from "effect/Option";
|
|
371
|
+
import * as SchemaAST6 from "effect/SchemaAST";
|
|
372
|
+
import React6, { useCallback as useCallback3 } from "react";
|
|
373
|
+
import { Ref as Ref2 } from "@dxos/echo";
|
|
374
|
+
import { createJsonPath as createJsonPath6, findNode as findNode3, getArrayElementType as getArrayElementType2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2, isNestedType as isNestedType3 } from "@dxos/effect";
|
|
375
|
+
import { useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
376
|
+
import { translationKey as translationKey3 } from "#translations";
|
|
383
377
|
|
|
384
378
|
// src/components/Form/Form.tsx
|
|
385
|
-
import { createContext } from "@radix-ui/react-context";
|
|
386
|
-
import * as
|
|
387
|
-
import * as
|
|
388
|
-
import
|
|
389
|
-
import {
|
|
390
|
-
import {
|
|
391
|
-
import {
|
|
379
|
+
import { createContext as createContext2 } from "@radix-ui/react-context";
|
|
380
|
+
import * as Option5 from "effect/Option";
|
|
381
|
+
import * as Schema3 from "effect/Schema";
|
|
382
|
+
import * as SchemaAST5 from "effect/SchemaAST";
|
|
383
|
+
import React5, { useEffect as useEffect2, useMemo as useMemo5, useRef } from "react";
|
|
384
|
+
import { Annotation as EchoAnnotation, Type } from "@dxos/echo";
|
|
385
|
+
import { createJsonPath as createJsonPath5, getValue as getValue$2 } from "@dxos/effect";
|
|
386
|
+
import { Column, IconButton as IconButton2, Input as Input3, ScrollArea, useMergeRefs, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
387
|
+
import { composable, composableProps, withColumn } from "@dxos/react-ui";
|
|
388
|
+
import { mx as mx3 } from "@dxos/ui-theme";
|
|
389
|
+
import { translationKey as translationKey2 } from "#translations";
|
|
392
390
|
|
|
393
391
|
// src/hooks/useFormHandler.ts
|
|
394
392
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
@@ -426,12 +424,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
426
424
|
log("validate", {
|
|
427
425
|
values: values2,
|
|
428
426
|
errors: errors2
|
|
429
|
-
}, {
|
|
430
|
-
F: __dxlog_file,
|
|
431
|
-
L: 155,
|
|
432
|
-
S: void 0,
|
|
433
|
-
C: (f, a) => f(...a)
|
|
434
|
-
});
|
|
427
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 42, S: void 0 });
|
|
435
428
|
if (errors2.length === 0 && onValidate) {
|
|
436
429
|
const validatedValues = values2;
|
|
437
430
|
errors2 = onValidate(validatedValues) ?? [];
|
|
@@ -519,12 +512,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
519
512
|
log("onValueChange", {
|
|
520
513
|
path,
|
|
521
514
|
value: value3
|
|
522
|
-
}, {
|
|
523
|
-
F: __dxlog_file,
|
|
524
|
-
L: 254,
|
|
525
|
-
S: void 0,
|
|
526
|
-
C: (f, a) => f(...a)
|
|
527
|
-
});
|
|
515
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 138, S: void 0 });
|
|
528
516
|
const jsonPath = createJsonPath(path);
|
|
529
517
|
const pathArray = path;
|
|
530
518
|
let parsedValue = value3;
|
|
@@ -533,12 +521,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
533
521
|
parsedValue = parseFloat(value3) || 0;
|
|
534
522
|
}
|
|
535
523
|
} catch (err) {
|
|
536
|
-
log.catch(err, void 0, {
|
|
537
|
-
F: __dxlog_file,
|
|
538
|
-
L: 264,
|
|
539
|
-
S: void 0,
|
|
540
|
-
C: (f, a) => f(...a)
|
|
541
|
-
});
|
|
524
|
+
log.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 150, S: void 0 });
|
|
542
525
|
parsedValue = void 0;
|
|
543
526
|
}
|
|
544
527
|
const newValues = mergeAtPath(values, pathArray, parsedValue);
|
|
@@ -622,18 +605,18 @@ var mergeAtPath = (obj, path, value3) => {
|
|
|
622
605
|
if (path.length === 0) {
|
|
623
606
|
return value3;
|
|
624
607
|
}
|
|
625
|
-
const [
|
|
626
|
-
const child = rest.length === 0 ? value3 : mergeAtPath(obj?.[
|
|
608
|
+
const [head, ...rest] = path;
|
|
609
|
+
const child = rest.length === 0 ? value3 : mergeAtPath(obj?.[head], rest, value3);
|
|
627
610
|
if (Array.isArray(obj)) {
|
|
628
611
|
const copy = [
|
|
629
612
|
...obj
|
|
630
613
|
];
|
|
631
|
-
copy[
|
|
614
|
+
copy[head] = child;
|
|
632
615
|
return copy;
|
|
633
616
|
}
|
|
634
617
|
return {
|
|
635
618
|
...obj,
|
|
636
|
-
[
|
|
619
|
+
[head]: child
|
|
637
620
|
};
|
|
638
621
|
};
|
|
639
622
|
var flatMap = (errors) => {
|
|
@@ -647,9 +630,9 @@ var flatMap = (errors) => {
|
|
|
647
630
|
};
|
|
648
631
|
|
|
649
632
|
// src/hooks/useKeyHandler.tsx
|
|
650
|
-
import { useCallback as useCallback2,
|
|
633
|
+
import { useCallback as useCallback2, useLayoutEffect } from "react";
|
|
651
634
|
import { addEventListener } from "@dxos/async";
|
|
652
|
-
var useKeyHandler = (
|
|
635
|
+
var useKeyHandler = (elRef, form) => {
|
|
653
636
|
const handleKeyDown = useCallback2((event) => {
|
|
654
637
|
switch (event.key) {
|
|
655
638
|
case "Enter": {
|
|
@@ -665,29 +648,45 @@ var useKeyHandler = (formElement, form) => {
|
|
|
665
648
|
form.onSave,
|
|
666
649
|
form.autoSave
|
|
667
650
|
]);
|
|
668
|
-
|
|
669
|
-
|
|
651
|
+
useLayoutEffect(() => {
|
|
652
|
+
const el = elRef.current;
|
|
653
|
+
if (!el) {
|
|
670
654
|
return;
|
|
671
655
|
}
|
|
672
|
-
return addEventListener(
|
|
656
|
+
return addEventListener(el, "keydown", handleKeyDown);
|
|
673
657
|
}, [
|
|
674
|
-
|
|
658
|
+
elRef,
|
|
675
659
|
handleKeyDown
|
|
676
660
|
]);
|
|
677
661
|
};
|
|
678
662
|
|
|
679
663
|
// src/components/Form/FormFieldComponent.tsx
|
|
664
|
+
import { format as formatDate2 } from "date-fns";
|
|
680
665
|
import React, { Component } from "react";
|
|
666
|
+
import { Format as Format3 } from "@dxos/echo";
|
|
681
667
|
import { Icon, Input, Tooltip } from "@dxos/react-ui";
|
|
682
|
-
import { inputTextLabel } from "@dxos/ui
|
|
683
|
-
|
|
668
|
+
import { inputTextLabel } from "@dxos/react-ui";
|
|
669
|
+
import { mx } from "@dxos/ui-theme";
|
|
670
|
+
|
|
671
|
+
// src/components/Form/FormTooltipsContext.ts
|
|
672
|
+
import { createContext, useContext } from "react";
|
|
673
|
+
var FormTooltipsContext = createContext(true);
|
|
674
|
+
var useFormTooltips = () => useContext(FormTooltipsContext);
|
|
675
|
+
|
|
676
|
+
// src/components/Form/FormFieldComponent.tsx
|
|
677
|
+
var FormFieldLabel = ({ label, error, readonly, asChild, path }) => {
|
|
678
|
+
const tooltips = useFormTooltips();
|
|
684
679
|
const Label = readonly || asChild ? "span" : Input.Label;
|
|
680
|
+
const labelNode = /* @__PURE__ */ React.createElement(Label, {
|
|
681
|
+
className: mx(inputTextLabel, "text-sm")
|
|
682
|
+
}, label);
|
|
685
683
|
return /* @__PURE__ */ React.createElement("div", {
|
|
686
|
-
role: "none",
|
|
687
684
|
className: "flex items-center justify-between"
|
|
688
|
-
}, /* @__PURE__ */ React.createElement(
|
|
689
|
-
|
|
690
|
-
|
|
685
|
+
}, tooltips && path ? /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
|
|
686
|
+
asChild: true,
|
|
687
|
+
content: path,
|
|
688
|
+
side: "bottom"
|
|
689
|
+
}, labelNode) : labelNode, error && /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
|
|
691
690
|
asChild: true,
|
|
692
691
|
content: error,
|
|
693
692
|
side: "bottom"
|
|
@@ -698,26 +697,48 @@ var FormFieldLabel = ({ label, error, readonly, asChild }) => {
|
|
|
698
697
|
})));
|
|
699
698
|
};
|
|
700
699
|
FormFieldLabel.displayName = "Form.FieldLabel";
|
|
700
|
+
var formatStaticValue = (value3, format) => {
|
|
701
|
+
if (value3 == null) {
|
|
702
|
+
return "";
|
|
703
|
+
}
|
|
704
|
+
switch (format) {
|
|
705
|
+
case Format3.TypeFormat.DateTime:
|
|
706
|
+
case Format3.TypeFormat.Date:
|
|
707
|
+
case Format3.TypeFormat.Time: {
|
|
708
|
+
const date = new Date(value3);
|
|
709
|
+
if (Number.isNaN(date.getTime())) {
|
|
710
|
+
return String(value3);
|
|
711
|
+
}
|
|
712
|
+
const pattern = format === Format3.TypeFormat.DateTime ? "PPp" : format === Format3.TypeFormat.Date ? "PP" : "p";
|
|
713
|
+
return formatDate2(date, pattern);
|
|
714
|
+
}
|
|
715
|
+
default:
|
|
716
|
+
return String(value3);
|
|
717
|
+
}
|
|
718
|
+
};
|
|
701
719
|
var FormFieldWrapper = (props) => {
|
|
702
|
-
const { children, readonly, layout, label, getStatus, getValue } = props;
|
|
720
|
+
const { children, readonly, layout, label, jsonPath, format, getStatus, getValue } = props;
|
|
703
721
|
const { status, error } = getStatus();
|
|
704
722
|
const value3 = getValue();
|
|
705
723
|
if (layout === "static" && value3 == null) {
|
|
706
724
|
return null;
|
|
707
725
|
}
|
|
708
|
-
const str =
|
|
726
|
+
const str = formatStaticValue(value3, format);
|
|
709
727
|
return /* @__PURE__ */ React.createElement("div", {
|
|
710
|
-
role: "none",
|
|
711
728
|
className: "contents"
|
|
712
729
|
}, /* @__PURE__ */ React.createElement(Input.Root, {
|
|
713
730
|
validationValence: status
|
|
714
731
|
}, layout !== "inline" && /* @__PURE__ */ React.createElement(FormFieldLabel, {
|
|
715
732
|
error,
|
|
716
733
|
readonly,
|
|
717
|
-
label
|
|
718
|
-
|
|
734
|
+
label,
|
|
735
|
+
path: jsonPath
|
|
736
|
+
}), layout === "static" ? /* @__PURE__ */ React.createElement("p", {
|
|
737
|
+
className: "truncate min-w-0",
|
|
738
|
+
title: str
|
|
739
|
+
}, str) : children ? children({
|
|
719
740
|
value: value3
|
|
720
|
-
}) : null, layout === "full" && /* @__PURE__ */ React.createElement(Input.DescriptionAndValidation, null, /* @__PURE__ */ React.createElement(Input.Validation, null, error))));
|
|
741
|
+
}) : null, layout === "full" && error && /* @__PURE__ */ React.createElement(Input.DescriptionAndValidation, null, /* @__PURE__ */ React.createElement(Input.Validation, null, error))));
|
|
721
742
|
};
|
|
722
743
|
var FormFieldErrorBoundary = class extends Component {
|
|
723
744
|
static getDerivedStateFromError(error) {
|
|
@@ -736,9 +757,9 @@ var FormFieldErrorBoundary = class extends Component {
|
|
|
736
757
|
render() {
|
|
737
758
|
if (this.state.error) {
|
|
738
759
|
return /* @__PURE__ */ React.createElement("div", {
|
|
739
|
-
className: "flex gap-2 border border-rose-
|
|
760
|
+
className: "flex gap-2 border border-rose-bg font-mono text-sm"
|
|
740
761
|
}, /* @__PURE__ */ React.createElement("span", {
|
|
741
|
-
className: "bg-rose-
|
|
762
|
+
className: "bg-rose-bg text-base-fg px-1 font-thin"
|
|
742
763
|
}, "ERROR"), String(this.props.path?.join(".")));
|
|
743
764
|
}
|
|
744
765
|
return this.props.children;
|
|
@@ -751,20 +772,22 @@ var FormFieldErrorBoundary = class extends Component {
|
|
|
751
772
|
};
|
|
752
773
|
|
|
753
774
|
// src/components/Form/FormFieldSet.tsx
|
|
754
|
-
import
|
|
755
|
-
import {
|
|
756
|
-
import {
|
|
775
|
+
import * as Option4 from "effect/Option";
|
|
776
|
+
import React4, { useMemo as useMemo4 } from "react";
|
|
777
|
+
import { createJsonPath as createJsonPath4 } from "@dxos/effect";
|
|
757
778
|
|
|
758
779
|
// src/components/Form/FormField.tsx
|
|
759
780
|
import * as Match from "effect/Match";
|
|
760
781
|
import * as Option2 from "effect/Option";
|
|
761
782
|
import * as Schema from "effect/Schema";
|
|
762
|
-
import * as
|
|
783
|
+
import * as SchemaAST3 from "effect/SchemaAST";
|
|
763
784
|
import * as String2 from "effect/String";
|
|
764
785
|
import React2, { useMemo as useMemo2 } from "react";
|
|
765
|
-
import { Format as
|
|
766
|
-
import { createJsonPath as createJsonPath2, findNode, getAnnotation, getDiscriminatedType, isArrayType as
|
|
767
|
-
import { useTranslation } from "@dxos/react-ui";
|
|
786
|
+
import { Annotation as Annotation2, Format as Format4 } from "@dxos/echo";
|
|
787
|
+
import { createJsonPath as createJsonPath2, findNode, getAnnotation as getAnnotation2, getDiscriminatedType, isArrayType as isArrayType3, isDiscriminatedUnion, isLiteralUnion as isLiteralUnion2, isNestedType as isNestedType2 } from "@dxos/effect";
|
|
788
|
+
import { IconButton, useTranslation } from "@dxos/react-ui";
|
|
789
|
+
import { mx as mx2 } from "@dxos/ui-theme";
|
|
790
|
+
import { translationKey } from "#translations";
|
|
768
791
|
var FormField = (props) => {
|
|
769
792
|
const {
|
|
770
793
|
type,
|
|
@@ -776,51 +799,58 @@ var FormField = (props) => {
|
|
|
776
799
|
readonly,
|
|
777
800
|
layout,
|
|
778
801
|
// RefFieldProps
|
|
802
|
+
createTypename,
|
|
779
803
|
createOptionLabel,
|
|
780
804
|
createOptionIcon,
|
|
781
805
|
createInitialValuePath,
|
|
806
|
+
createFieldMap: createFieldMap3,
|
|
782
807
|
db,
|
|
783
|
-
schemaHook,
|
|
784
|
-
getOptions
|
|
808
|
+
useType: schemaHook,
|
|
809
|
+
getOptions,
|
|
785
810
|
onCreate
|
|
786
811
|
} = props;
|
|
787
812
|
const { t } = useTranslation(translationKey);
|
|
788
|
-
const title =
|
|
789
|
-
const description =
|
|
790
|
-
const examples =
|
|
791
|
-
const label = useMemo2(() => title ?? String2.capitalize(name), [
|
|
813
|
+
const title = getAnnotation2(SchemaAST3.TitleAnnotationId)(type);
|
|
814
|
+
const description = getAnnotation2(SchemaAST3.DescriptionAnnotationId)(type);
|
|
815
|
+
const examples = getAnnotation2(SchemaAST3.ExamplesAnnotationId)(type);
|
|
816
|
+
const label = useMemo2(() => title ?? (name == null ? "" : String2.capitalize(name)), [
|
|
792
817
|
title,
|
|
793
818
|
name
|
|
794
819
|
]);
|
|
795
|
-
const placeholder = useMemo2(() => examples?.length ? `${t("example
|
|
820
|
+
const placeholder = useMemo2(() => examples?.length ? `${t("example.placeholder")}: ${examples[0]}` : description ?? label, [
|
|
796
821
|
examples,
|
|
797
822
|
description,
|
|
798
823
|
label
|
|
799
824
|
]);
|
|
800
825
|
const fieldState = useFormFieldState(FormField.displayName, path);
|
|
826
|
+
const jsonPath = createJsonPath2(path ?? []);
|
|
801
827
|
const fieldProps = {
|
|
802
828
|
type,
|
|
803
|
-
format:
|
|
829
|
+
format: Format4.FormatAnnotation.getFromAst(type).pipe((annotation) => Option2.getOrUndefined(annotation)),
|
|
804
830
|
readonly,
|
|
805
831
|
label,
|
|
832
|
+
jsonPath,
|
|
806
833
|
placeholder,
|
|
807
834
|
layout,
|
|
835
|
+
db,
|
|
808
836
|
...fieldState
|
|
809
837
|
};
|
|
810
|
-
|
|
838
|
+
if (readonly && fieldState.getValue() == null) {
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
811
841
|
const CustomField = fieldMap?.[jsonPath];
|
|
812
842
|
if (CustomField) {
|
|
813
843
|
return /* @__PURE__ */ React2.createElement(CustomField, fieldProps);
|
|
814
844
|
}
|
|
815
845
|
const component = fieldProvider?.({
|
|
816
846
|
schema: Schema.make(type),
|
|
817
|
-
prop: name,
|
|
847
|
+
prop: name ?? "",
|
|
818
848
|
fieldProps
|
|
819
849
|
});
|
|
820
850
|
if (component) {
|
|
821
851
|
return component;
|
|
822
852
|
}
|
|
823
|
-
if (
|
|
853
|
+
if (isArrayType3(type)) {
|
|
824
854
|
return /* @__PURE__ */ React2.createElement(ArrayField, {
|
|
825
855
|
fieldProps: fieldState,
|
|
826
856
|
label,
|
|
@@ -831,7 +861,7 @@ var FormField = (props) => {
|
|
|
831
861
|
if (Field) {
|
|
832
862
|
return /* @__PURE__ */ React2.createElement(Field, fieldProps);
|
|
833
863
|
}
|
|
834
|
-
const options =
|
|
864
|
+
const options = getSelectOptions(type);
|
|
835
865
|
if (options) {
|
|
836
866
|
const fieldProjections = projection?.getFieldProjections();
|
|
837
867
|
const fieldProjection = fieldProjections?.find((fp) => fp.field.path === name);
|
|
@@ -849,24 +879,36 @@ var FormField = (props) => {
|
|
|
849
879
|
}
|
|
850
880
|
const refProps = getRefProps(type);
|
|
851
881
|
if (refProps) {
|
|
882
|
+
const inline = Annotation2.FormInlineAnnotation.getFromAst(refProps.ast).pipe(Option2.getOrElse(() => false));
|
|
883
|
+
if (inline && !refProps.isArray) {
|
|
884
|
+
return /* @__PURE__ */ React2.createElement(InlineRefField, {
|
|
885
|
+
...fieldProps,
|
|
886
|
+
...refProps,
|
|
887
|
+
db,
|
|
888
|
+
useType: schemaHook,
|
|
889
|
+
onCreate
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
const isCreateTarget = !createTypename || refProps.typename === createTypename;
|
|
852
893
|
return /* @__PURE__ */ React2.createElement(RefField, {
|
|
853
894
|
...fieldProps,
|
|
854
895
|
...refProps,
|
|
855
|
-
createOptionLabel,
|
|
856
|
-
createOptionIcon,
|
|
857
|
-
createInitialValuePath,
|
|
896
|
+
createOptionLabel: isCreateTarget ? createOptionLabel : void 0,
|
|
897
|
+
createOptionIcon: isCreateTarget ? createOptionIcon : void 0,
|
|
898
|
+
createInitialValuePath: isCreateTarget ? createInitialValuePath : void 0,
|
|
899
|
+
createFieldMap: isCreateTarget ? createFieldMap3 : void 0,
|
|
858
900
|
db,
|
|
859
|
-
schemaHook,
|
|
860
|
-
getOptions
|
|
901
|
+
useType: schemaHook,
|
|
902
|
+
getOptions,
|
|
861
903
|
onCreate
|
|
862
904
|
});
|
|
863
905
|
}
|
|
864
|
-
if (
|
|
906
|
+
if (isNestedType2(type)) {
|
|
865
907
|
const baseNode = findNode(type, isDiscriminatedUnion);
|
|
866
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type,
|
|
908
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST3.isTypeLiteral);
|
|
867
909
|
if (typeLiteral) {
|
|
868
910
|
const schema = Schema.make(typeLiteral);
|
|
869
|
-
return /* @__PURE__ */ React2.createElement(FormFieldSet, {
|
|
911
|
+
return /* @__PURE__ */ React2.createElement(Nesting, null, /* @__PURE__ */ React2.createElement(FormFieldSet, {
|
|
870
912
|
schema,
|
|
871
913
|
path,
|
|
872
914
|
readonly,
|
|
@@ -879,17 +921,33 @@ var FormField = (props) => {
|
|
|
879
921
|
createOptionIcon,
|
|
880
922
|
createInitialValuePath,
|
|
881
923
|
db,
|
|
882
|
-
schemaHook,
|
|
883
|
-
getOptions
|
|
924
|
+
useType: schemaHook,
|
|
925
|
+
getOptions,
|
|
884
926
|
onCreate
|
|
885
|
-
});
|
|
927
|
+
}));
|
|
886
928
|
}
|
|
887
929
|
}
|
|
888
930
|
return null;
|
|
889
931
|
};
|
|
890
932
|
FormField.displayName = "Form.FormField";
|
|
933
|
+
var Nesting = ({ children }) => /* @__PURE__ */ React2.createElement("div", {
|
|
934
|
+
className: "px-2 border border-subdued-separator rounded-sm mt-2"
|
|
935
|
+
}, /* @__PURE__ */ React2.createElement("div", {
|
|
936
|
+
className: "pb-2"
|
|
937
|
+
}, children));
|
|
938
|
+
var IconBlock = ({ inline, ...props }) => {
|
|
939
|
+
return /* @__PURE__ */ React2.createElement("div", {
|
|
940
|
+
className: mx2("h-full flex px-1", inline ? "items-center" : "flex-col pt-2.5")
|
|
941
|
+
}, /* @__PURE__ */ React2.createElement(IconButton, {
|
|
942
|
+
variant: "ghost",
|
|
943
|
+
density: "xs",
|
|
944
|
+
square: true,
|
|
945
|
+
iconOnly: true,
|
|
946
|
+
...props
|
|
947
|
+
}));
|
|
948
|
+
};
|
|
891
949
|
var getFormField = ({ type, format }) => {
|
|
892
|
-
const formatField = Match.value(format).pipe(Match.withReturnType(), Match.when(
|
|
950
|
+
const formatField = Match.value(format).pipe(Match.withReturnType(), Match.when(Format4.TypeFormat.Date, () => DateField), Match.when(Format4.TypeFormat.DateTime, () => DateField), Match.when(Format4.TypeFormat.GeoPoint, () => GeoPointField), Match.when(Format4.TypeFormat.Markdown, () => MarkdownField), Match.when(Format4.TypeFormat.Text, () => TextAreaField), Match.when(Format4.TypeFormat.Time, () => DateField), Match.orElse(() => void 0));
|
|
893
951
|
if (formatField) {
|
|
894
952
|
return formatField;
|
|
895
953
|
}
|
|
@@ -904,67 +962,327 @@ var getFormField = ({ type, format }) => {
|
|
|
904
962
|
return BooleanField;
|
|
905
963
|
}
|
|
906
964
|
};
|
|
907
|
-
var
|
|
908
|
-
if (
|
|
965
|
+
var getSelectOptions = (ast) => {
|
|
966
|
+
if (isLiteralUnion2(ast)) {
|
|
909
967
|
return ast.types.map((type) => type.literal).filter((v) => v !== null);
|
|
910
968
|
}
|
|
911
|
-
return
|
|
969
|
+
return Format4.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option2.getOrUndefined(annotation));
|
|
912
970
|
};
|
|
913
971
|
|
|
914
|
-
// src/components/Form/
|
|
915
|
-
|
|
916
|
-
var
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
972
|
+
// src/components/Form/Layout/annotation.ts
|
|
973
|
+
import { createAnnotationHelper } from "@dxos/echo/internal";
|
|
974
|
+
var FormLayoutAnnotationId = /* @__PURE__ */ Symbol.for("@dxos/react-ui-form/annotation/Layout");
|
|
975
|
+
var FormLayoutAnnotation = createAnnotationHelper(FormLayoutAnnotationId);
|
|
976
|
+
var DEFAULT_LAYOUT_NAME = "default";
|
|
977
|
+
|
|
978
|
+
// src/components/Form/Layout/FormLayout.tsx
|
|
979
|
+
import * as Option3 from "effect/Option";
|
|
980
|
+
import * as Schema2 from "effect/Schema";
|
|
981
|
+
import * as SchemaAST4 from "effect/SchemaAST";
|
|
982
|
+
import * as String3 from "effect/String";
|
|
983
|
+
import React3, { Fragment, useMemo as useMemo3 } from "react";
|
|
984
|
+
import { Annotation as Annotation3 } from "@dxos/echo";
|
|
985
|
+
import { createJsonPath as createJsonPath3, findNode as findNode2, getAnnotation as getAnnotation3, getBaseType } from "@dxos/effect";
|
|
986
|
+
import { Input as Input2 } from "@dxos/react-ui";
|
|
987
|
+
|
|
988
|
+
// src/components/Form/Layout/parser.ts
|
|
989
|
+
var LayoutParseError = class extends Error {
|
|
990
|
+
position;
|
|
991
|
+
_tag = "LayoutParseError";
|
|
992
|
+
constructor(message, position) {
|
|
993
|
+
super(position !== void 0 ? `${message} (at position ${position})` : message), this.position = position;
|
|
994
|
+
}
|
|
995
|
+
};
|
|
996
|
+
var TAG_RE = /<\s*(\/?)\s*(\w+)([^>]*?)(\/?)\s*>/g;
|
|
997
|
+
var ATTR_RE = /([\w-]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|(\d+))/g;
|
|
998
|
+
var parseAttrs = (raw) => {
|
|
999
|
+
const attrs = {};
|
|
1000
|
+
ATTR_RE.lastIndex = 0;
|
|
1001
|
+
let match;
|
|
1002
|
+
while ((match = ATTR_RE.exec(raw)) !== null) {
|
|
1003
|
+
const [, key, doubleQuoted, singleQuoted, bare] = match;
|
|
1004
|
+
attrs[key] = doubleQuoted ?? singleQuoted ?? bare;
|
|
1005
|
+
}
|
|
1006
|
+
return attrs;
|
|
1007
|
+
};
|
|
1008
|
+
var tokenize = (input) => {
|
|
1009
|
+
const tokens = [];
|
|
1010
|
+
TAG_RE.lastIndex = 0;
|
|
1011
|
+
let match;
|
|
1012
|
+
let cursor = 0;
|
|
1013
|
+
while ((match = TAG_RE.exec(input)) !== null) {
|
|
1014
|
+
const between = input.slice(cursor, match.index);
|
|
1015
|
+
if (between.trim().length > 0) {
|
|
1016
|
+
throw new LayoutParseError(`unexpected text content: ${JSON.stringify(between.trim())}`, cursor);
|
|
1017
|
+
}
|
|
1018
|
+
const [, slash, name, attrsRaw, selfSlash] = match;
|
|
1019
|
+
if (slash) {
|
|
1020
|
+
tokens.push({
|
|
1021
|
+
type: "close",
|
|
1022
|
+
name,
|
|
1023
|
+
position: match.index
|
|
1024
|
+
});
|
|
1025
|
+
} else {
|
|
1026
|
+
tokens.push({
|
|
1027
|
+
type: "open",
|
|
1028
|
+
name,
|
|
1029
|
+
attrs: parseAttrs(attrsRaw),
|
|
1030
|
+
selfClosing: selfSlash === "/",
|
|
1031
|
+
position: match.index
|
|
1032
|
+
});
|
|
921
1033
|
}
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
1034
|
+
cursor = match.index + match[0].length;
|
|
1035
|
+
}
|
|
1036
|
+
const trailing = input.slice(cursor);
|
|
1037
|
+
if (trailing.trim().length > 0) {
|
|
1038
|
+
throw new LayoutParseError(`unexpected text content: ${JSON.stringify(trailing.trim())}`, cursor);
|
|
1039
|
+
}
|
|
1040
|
+
return tokens;
|
|
1041
|
+
};
|
|
1042
|
+
var requireAttr = (attrs, key, tag, position) => {
|
|
1043
|
+
const value3 = attrs[key];
|
|
1044
|
+
if (value3 === void 0) {
|
|
1045
|
+
throw new LayoutParseError(`<${tag}> missing required attribute "${key}"`, position);
|
|
1046
|
+
}
|
|
1047
|
+
return value3;
|
|
1048
|
+
};
|
|
1049
|
+
var parseInteger = (value3, attr, tag, position) => {
|
|
1050
|
+
if (!/^\d+$/.test(value3)) {
|
|
1051
|
+
throw new LayoutParseError(`<${tag}> attribute "${attr}" expects an integer, got ${JSON.stringify(value3)}`, position);
|
|
1052
|
+
}
|
|
1053
|
+
return Number.parseInt(value3, 10);
|
|
1054
|
+
};
|
|
1055
|
+
var parseLayout = (template) => {
|
|
1056
|
+
const tokens = tokenize(template);
|
|
1057
|
+
if (tokens.length === 0) {
|
|
1058
|
+
throw new LayoutParseError("empty template");
|
|
1059
|
+
}
|
|
1060
|
+
let index = 0;
|
|
1061
|
+
const parseNode = () => {
|
|
1062
|
+
const token = tokens[index];
|
|
1063
|
+
if (!token || token.type !== "open") {
|
|
1064
|
+
throw new LayoutParseError(`expected an opening tag, got ${JSON.stringify(token)}`, token?.position);
|
|
1065
|
+
}
|
|
1066
|
+
if (token.name === "field") {
|
|
1067
|
+
if (!token.selfClosing) {
|
|
1068
|
+
throw new LayoutParseError('<field> must be self-closing (e.g. <field name="x"/>)', token.position);
|
|
934
1069
|
}
|
|
935
|
-
const
|
|
936
|
-
const
|
|
937
|
-
|
|
938
|
-
|
|
1070
|
+
const name = requireAttr(token.attrs, "name", "field", token.position);
|
|
1071
|
+
const spanRaw = token.attrs.span;
|
|
1072
|
+
const span = spanRaw !== void 0 ? parseInteger(spanRaw, "span", "field", token.position) : void 0;
|
|
1073
|
+
index += 1;
|
|
1074
|
+
return {
|
|
1075
|
+
kind: "field",
|
|
1076
|
+
name,
|
|
1077
|
+
span
|
|
1078
|
+
};
|
|
939
1079
|
}
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1080
|
+
if (token.name === "grid") {
|
|
1081
|
+
if (token.selfClosing) {
|
|
1082
|
+
throw new LayoutParseError("<grid> must wrap children (cannot self-close)", token.position);
|
|
1083
|
+
}
|
|
1084
|
+
const cols = parseInteger(requireAttr(token.attrs, "cols", "grid", token.position), "cols", "grid", token.position);
|
|
1085
|
+
index += 1;
|
|
1086
|
+
const children = [];
|
|
1087
|
+
while (index < tokens.length && !(tokens[index].type === "close" && tokens[index].name === "grid")) {
|
|
1088
|
+
children.push(parseNode());
|
|
1089
|
+
}
|
|
1090
|
+
const closing = tokens[index];
|
|
1091
|
+
if (!closing || closing.type !== "close" || closing.name !== "grid") {
|
|
1092
|
+
throw new LayoutParseError("<grid> not closed", token.position);
|
|
1093
|
+
}
|
|
1094
|
+
index += 1;
|
|
1095
|
+
return {
|
|
1096
|
+
kind: "grid",
|
|
1097
|
+
cols,
|
|
1098
|
+
children
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
throw new LayoutParseError(`unknown element <${token.name}>`, token.position);
|
|
1102
|
+
};
|
|
1103
|
+
const root = parseNode();
|
|
1104
|
+
if (index !== tokens.length) {
|
|
1105
|
+
const trailing = tokens[index];
|
|
1106
|
+
throw new LayoutParseError(`unexpected trailing tag <${trailing.type === "open" ? "" : "/"}${trailing.name}>`, trailing.position);
|
|
1107
|
+
}
|
|
1108
|
+
if (root.kind !== "grid") {
|
|
1109
|
+
throw new LayoutParseError("root element must be <grid>");
|
|
1110
|
+
}
|
|
1111
|
+
return root;
|
|
1112
|
+
};
|
|
1113
|
+
|
|
1114
|
+
// src/components/Form/Layout/FormLayout.tsx
|
|
1115
|
+
var FORM_LAYOUT_NAME = "Form.Layout";
|
|
1116
|
+
var FormLayout = ({ schema, template, name = DEFAULT_LAYOUT_NAME, path, readonly, layout, projection, ...props }) => {
|
|
1117
|
+
const annotated = Option3.getOrUndefined(FormLayoutAnnotation.get(schema));
|
|
1118
|
+
const source = template ?? annotated?.[name];
|
|
1119
|
+
if (source === void 0) {
|
|
1120
|
+
throw new LayoutParseError(annotated ? `no layout named "${name}" on schema (available: ${Object.keys(annotated).join(", ") || "\u2205"})` : `no template provided and schema has no FormLayoutAnnotation`);
|
|
1121
|
+
}
|
|
1122
|
+
const tree = useMemo3(() => parseLayout(source), [
|
|
1123
|
+
source
|
|
1124
|
+
]);
|
|
1125
|
+
return /* @__PURE__ */ React3.createElement(RenderNode, {
|
|
1126
|
+
node: tree,
|
|
1127
|
+
schema,
|
|
1128
|
+
basePath: path ?? [],
|
|
1129
|
+
readonly,
|
|
1130
|
+
layout,
|
|
1131
|
+
projection,
|
|
1132
|
+
...props
|
|
1133
|
+
});
|
|
1134
|
+
};
|
|
1135
|
+
FormLayout.displayName = FORM_LAYOUT_NAME;
|
|
1136
|
+
var RenderNode = ({ node, schema, basePath, ...props }) => {
|
|
1137
|
+
if (node.kind === "grid") {
|
|
1138
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
|
1139
|
+
className: "grid gap-x-form-gap",
|
|
1140
|
+
style: {
|
|
1141
|
+
gridTemplateColumns: `repeat(${node.cols}, minmax(0, 1fr))`
|
|
1142
|
+
}
|
|
1143
|
+
}, node.children.map((child, index) => /* @__PURE__ */ React3.createElement(Fragment, {
|
|
1144
|
+
key: index
|
|
1145
|
+
}, /* @__PURE__ */ React3.createElement(RenderNode, {
|
|
1146
|
+
node: child,
|
|
1147
|
+
schema,
|
|
1148
|
+
basePath,
|
|
1149
|
+
...props
|
|
1150
|
+
}))));
|
|
1151
|
+
}
|
|
1152
|
+
const resolved = resolveLayoutField(schema, node.name);
|
|
1153
|
+
if (!resolved) {
|
|
1154
|
+
throw new LayoutParseError(`field "${node.name}" not found on schema`);
|
|
1155
|
+
}
|
|
1156
|
+
const { type, segments, leafName, title, labelType } = resolved;
|
|
1157
|
+
const path = [
|
|
1158
|
+
...basePath,
|
|
1159
|
+
...segments
|
|
1160
|
+
];
|
|
1161
|
+
const span = node.span ? {
|
|
1162
|
+
gridColumn: `span ${node.span} / span ${node.span}`
|
|
1163
|
+
} : void 0;
|
|
1164
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
|
1165
|
+
className: "min-w-0",
|
|
1166
|
+
style: span
|
|
1167
|
+
}, /* @__PURE__ */ React3.createElement(FormFieldErrorBoundary, {
|
|
1168
|
+
path
|
|
1169
|
+
}, labelType ? /* @__PURE__ */ React3.createElement(LabelField, {
|
|
1170
|
+
schema: Schema2.make(labelType),
|
|
1171
|
+
label: title ?? String3.capitalize(leafName),
|
|
1172
|
+
path,
|
|
1173
|
+
layout: props.layout
|
|
1174
|
+
}) : /* @__PURE__ */ React3.createElement(FormField, {
|
|
1175
|
+
type,
|
|
1176
|
+
name: leafName,
|
|
1177
|
+
path,
|
|
1178
|
+
...props
|
|
1179
|
+
})));
|
|
1180
|
+
};
|
|
1181
|
+
var resolvePropertySignature = (ast, segments) => {
|
|
1182
|
+
let node = ast;
|
|
1183
|
+
for (let index = 0; index < segments.length; index++) {
|
|
1184
|
+
const typeLiteral = findNode2(node, SchemaAST4.isTypeLiteral);
|
|
1185
|
+
if (!typeLiteral) {
|
|
1186
|
+
return void 0;
|
|
1187
|
+
}
|
|
1188
|
+
const prop = SchemaAST4.getPropertySignatures(typeLiteral).find((p) => globalThis.String(p.name) === segments[index]);
|
|
1189
|
+
if (!prop) {
|
|
1190
|
+
return void 0;
|
|
1191
|
+
}
|
|
1192
|
+
if (index === segments.length - 1) {
|
|
1193
|
+
return prop;
|
|
1194
|
+
}
|
|
1195
|
+
node = prop.type;
|
|
1196
|
+
}
|
|
1197
|
+
return void 0;
|
|
1198
|
+
};
|
|
1199
|
+
var resolveLayoutField = (schema, name) => {
|
|
1200
|
+
const segments = name.split(".");
|
|
1201
|
+
const prop = resolvePropertySignature(schema.ast, segments);
|
|
1202
|
+
if (!prop) {
|
|
1203
|
+
return void 0;
|
|
1204
|
+
}
|
|
1205
|
+
const { type: baseType } = getBaseType(prop);
|
|
1206
|
+
const type = prop.annotations && Reflect.ownKeys(prop.annotations).length > 0 ? {
|
|
1207
|
+
...baseType,
|
|
1208
|
+
annotations: {
|
|
1209
|
+
...baseType.annotations,
|
|
1210
|
+
...prop.annotations
|
|
1211
|
+
}
|
|
1212
|
+
} : baseType;
|
|
1213
|
+
const title = getAnnotation3(SchemaAST4.TitleAnnotationId)(type);
|
|
1214
|
+
const labelType = findNode2(prop.type, SchemaAST4.isTypeLiteral);
|
|
1215
|
+
const labelled = labelType != null && Option3.isSome(Annotation3.LabelAnnotation.getFromAst(labelType));
|
|
1216
|
+
return {
|
|
1217
|
+
type,
|
|
1218
|
+
segments,
|
|
1219
|
+
leafName: segments[segments.length - 1],
|
|
1220
|
+
title,
|
|
1221
|
+
labelType: labelled ? labelType : void 0
|
|
1222
|
+
};
|
|
1223
|
+
};
|
|
1224
|
+
var LabelField = ({ schema, label, path, layout }) => {
|
|
1225
|
+
const { getValue } = useFormFieldState(FORM_LAYOUT_NAME, path);
|
|
1226
|
+
const value3 = getValue();
|
|
1227
|
+
const text = value3 == null ? void 0 : Annotation3.getLabelWithSchema(schema, value3);
|
|
1228
|
+
if (text == null || text.trim().length === 0) {
|
|
1229
|
+
return null;
|
|
1230
|
+
}
|
|
1231
|
+
return /* @__PURE__ */ React3.createElement("div", {
|
|
1232
|
+
className: "contents"
|
|
1233
|
+
}, /* @__PURE__ */ React3.createElement(Input2.Root, null, layout !== "inline" && /* @__PURE__ */ React3.createElement(FormFieldLabel, {
|
|
1234
|
+
readonly: true,
|
|
1235
|
+
label,
|
|
1236
|
+
path: createJsonPath3(path)
|
|
1237
|
+
}), /* @__PURE__ */ React3.createElement("p", {
|
|
1238
|
+
className: "truncate min-w-0",
|
|
1239
|
+
title: text
|
|
1240
|
+
}, text)));
|
|
1241
|
+
};
|
|
1242
|
+
|
|
1243
|
+
// src/components/Form/FormFieldSet.tsx
|
|
1244
|
+
var FORM_FIELDSET_NAME = "Form.FieldSet";
|
|
1245
|
+
var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection, layout, layoutName = DEFAULT_LAYOUT_NAME, ...props }) => {
|
|
1246
|
+
const values = useFormValues(FORM_FIELDSET_NAME, path);
|
|
1247
|
+
const properties = useFormFieldSetProperties({
|
|
943
1248
|
schema,
|
|
944
1249
|
values,
|
|
945
1250
|
exclude,
|
|
946
1251
|
sort,
|
|
947
|
-
projection
|
|
948
|
-
|
|
1252
|
+
projection
|
|
1253
|
+
});
|
|
949
1254
|
if ((readonly || layout === "static") && values == null) {
|
|
950
1255
|
return null;
|
|
951
1256
|
}
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1257
|
+
const layouts = schema ? Option4.getOrUndefined(FormLayoutAnnotation.get(schema)) : void 0;
|
|
1258
|
+
if (layouts?.[layoutName] !== void 0 && schema) {
|
|
1259
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, layout !== "inline" && label && /* @__PURE__ */ React4.createElement(FormFieldLabel, {
|
|
1260
|
+
label,
|
|
1261
|
+
path: createJsonPath4(path ?? []),
|
|
1262
|
+
asChild: true
|
|
1263
|
+
}), /* @__PURE__ */ React4.createElement(FormLayout, {
|
|
1264
|
+
schema,
|
|
1265
|
+
name: layoutName,
|
|
1266
|
+
path,
|
|
1267
|
+
readonly,
|
|
1268
|
+
layout,
|
|
1269
|
+
projection,
|
|
1270
|
+
...props
|
|
1271
|
+
}));
|
|
1272
|
+
}
|
|
1273
|
+
return /* @__PURE__ */ React4.createElement(React4.Fragment, null, layout !== "inline" && label && /* @__PURE__ */ React4.createElement(FormFieldLabel, {
|
|
957
1274
|
label,
|
|
1275
|
+
path: createJsonPath4(path ?? []),
|
|
958
1276
|
asChild: true
|
|
959
1277
|
}), properties.map((property) => {
|
|
960
1278
|
const name = property.name.toString();
|
|
961
|
-
return /* @__PURE__ */
|
|
1279
|
+
return /* @__PURE__ */ React4.createElement(FormFieldErrorBoundary, {
|
|
962
1280
|
key: name,
|
|
963
1281
|
path: [
|
|
964
1282
|
...path ?? [],
|
|
965
1283
|
name
|
|
966
1284
|
]
|
|
967
|
-
}, /* @__PURE__ */
|
|
1285
|
+
}, /* @__PURE__ */ React4.createElement(FormField, {
|
|
968
1286
|
type: property.type,
|
|
969
1287
|
name,
|
|
970
1288
|
path: [
|
|
@@ -976,25 +1294,68 @@ var FormFieldSet = /* @__PURE__ */ forwardRef(({ label, schema, readonly, path,
|
|
|
976
1294
|
projection,
|
|
977
1295
|
...props
|
|
978
1296
|
}));
|
|
979
|
-
})
|
|
980
|
-
}
|
|
1297
|
+
}));
|
|
1298
|
+
};
|
|
981
1299
|
FormFieldSet.displayName = FORM_FIELDSET_NAME;
|
|
1300
|
+
var useFormFieldSetProperties = ({ schema, exclude, projection, values, sort }) => {
|
|
1301
|
+
return useMemo4(() => {
|
|
1302
|
+
if (!schema) {
|
|
1303
|
+
return [];
|
|
1304
|
+
}
|
|
1305
|
+
const schemaProps = getFormProperties(schema.ast);
|
|
1306
|
+
const filteredProps = exclude ? exclude(schemaProps) : schemaProps;
|
|
1307
|
+
if (projection) {
|
|
1308
|
+
const fieldProjections = projection.getFieldProjections();
|
|
1309
|
+
const hiddenProperties = new Set(projection.getHiddenProperties());
|
|
1310
|
+
const visibleProps = filteredProps.filter((prop) => !hiddenProperties.has(prop.name.toString()));
|
|
1311
|
+
const orderedProps = [];
|
|
1312
|
+
for (const fieldProjection of fieldProjections) {
|
|
1313
|
+
const fieldPath = String(fieldProjection.field.path);
|
|
1314
|
+
const prop = visibleProps.find((prop2) => prop2.name === fieldPath);
|
|
1315
|
+
if (prop) {
|
|
1316
|
+
orderedProps.push(prop);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
|
|
1320
|
+
const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
|
|
1321
|
+
orderedProps.push(...remainingProps);
|
|
1322
|
+
return orderedProps;
|
|
1323
|
+
}
|
|
1324
|
+
return sort ? [
|
|
1325
|
+
...filteredProps
|
|
1326
|
+
].sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filteredProps;
|
|
1327
|
+
}, [
|
|
1328
|
+
schema,
|
|
1329
|
+
values,
|
|
1330
|
+
exclude,
|
|
1331
|
+
sort,
|
|
1332
|
+
projection
|
|
1333
|
+
]);
|
|
1334
|
+
};
|
|
982
1335
|
|
|
983
1336
|
// src/components/Form/Form.tsx
|
|
984
|
-
var omitId = (
|
|
985
|
-
|
|
1337
|
+
var omitId = (schemaOrType) => {
|
|
1338
|
+
const schema = Type.isType(schemaOrType) ? Type.getSchema(schemaOrType) : schemaOrType;
|
|
1339
|
+
return schema.pipe(Schema3.omit("id"));
|
|
1340
|
+
};
|
|
1341
|
+
var omitHiddenFormFields = (schema) => {
|
|
1342
|
+
const properties = SchemaAST5.getPropertySignatures(schema.ast);
|
|
1343
|
+
const hidden = properties.filter((prop) => Option5.getOrElse(EchoAnnotation.FormInputAnnotation.getFromAst(prop.type), () => true) === false).map((prop) => prop.name);
|
|
1344
|
+
return hidden.length === 0 ? schema : schema.pipe(Schema3.omit(...hidden));
|
|
1345
|
+
};
|
|
1346
|
+
var [FormContextProvider, useFormContext] = createContext2("Form");
|
|
986
1347
|
var useFormValues = (componentName, path, defaultValue) => {
|
|
987
|
-
const stablePath =
|
|
1348
|
+
const stablePath = useMemo5(() => path ?? [], [
|
|
988
1349
|
path ? path.join(".") : void 0
|
|
989
1350
|
]);
|
|
990
|
-
const jsonPath =
|
|
1351
|
+
const jsonPath = createJsonPath5(stablePath);
|
|
991
1352
|
const { form: { values, onValueChange } } = useFormContext(componentName);
|
|
992
1353
|
const value3 = getValue$2(values, jsonPath);
|
|
993
1354
|
const lastAppliedPathRef = useRef(null);
|
|
994
|
-
|
|
1355
|
+
useEffect2(() => {
|
|
995
1356
|
if (value3 == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {
|
|
996
1357
|
lastAppliedPathRef.current = jsonPath;
|
|
997
|
-
onValueChange(stablePath,
|
|
1358
|
+
onValueChange(stablePath, SchemaAST5.stringKeyword, defaultValue());
|
|
998
1359
|
}
|
|
999
1360
|
}, [
|
|
1000
1361
|
value3,
|
|
@@ -1006,11 +1367,11 @@ var useFormValues = (componentName, path, defaultValue) => {
|
|
|
1006
1367
|
return value3;
|
|
1007
1368
|
};
|
|
1008
1369
|
var useFormFieldState = (componentName, path = []) => {
|
|
1009
|
-
const stablePath =
|
|
1370
|
+
const stablePath = useMemo5(() => path, [
|
|
1010
1371
|
Array.isArray(path) ? path.join(".") : path
|
|
1011
1372
|
]);
|
|
1012
1373
|
const { form: { getStatus, getValue, onBlur, onValueChange } } = useFormContext(componentName);
|
|
1013
|
-
return
|
|
1374
|
+
return useMemo5(() => ({
|
|
1014
1375
|
getStatus: () => getStatus(stablePath),
|
|
1015
1376
|
getValue: () => getValue(stablePath),
|
|
1016
1377
|
onBlur: () => onBlur(stablePath),
|
|
@@ -1031,121 +1392,188 @@ var FormRoot = ({ children, schema, values, onSave, onCancel, ...props }) => {
|
|
|
1031
1392
|
onCancel,
|
|
1032
1393
|
...props
|
|
1033
1394
|
});
|
|
1034
|
-
return /* @__PURE__ */
|
|
1395
|
+
return /* @__PURE__ */ React5.createElement(FormTooltipsContext.Provider, {
|
|
1396
|
+
value: props.tooltips ?? true
|
|
1397
|
+
}, /* @__PURE__ */ React5.createElement(FormContextProvider, {
|
|
1035
1398
|
form,
|
|
1036
1399
|
...props
|
|
1037
|
-
}, children);
|
|
1400
|
+
}, children));
|
|
1038
1401
|
};
|
|
1039
1402
|
FormRoot.displayName = "Form.Root";
|
|
1040
1403
|
var FORM_VIEWPORT_NAME = "Form.Viewport";
|
|
1041
|
-
var FormViewport = ({ children,
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
}
|
|
1404
|
+
var FormViewport = composable(({ children, scroll, gutter = "sm", ...props }, forwardedRef) => {
|
|
1405
|
+
const span = "[.dx-column-root_&]:col-span-full";
|
|
1406
|
+
if (scroll) {
|
|
1407
|
+
return /* @__PURE__ */ React5.createElement(Column.Root, {
|
|
1408
|
+
gutter,
|
|
1409
|
+
classNames: [
|
|
1410
|
+
"dx-expander",
|
|
1411
|
+
span
|
|
1412
|
+
]
|
|
1413
|
+
}, /* @__PURE__ */ React5.createElement(ScrollArea.Root, {
|
|
1414
|
+
...composableProps(props),
|
|
1415
|
+
orientation: "vertical",
|
|
1416
|
+
centered: true,
|
|
1417
|
+
padding: true,
|
|
1418
|
+
thin: true,
|
|
1419
|
+
ref: forwardedRef
|
|
1420
|
+
}, /* @__PURE__ */ React5.createElement(ScrollArea.Viewport, null, children)));
|
|
1421
|
+
}
|
|
1422
|
+
return /* @__PURE__ */ React5.createElement(Column.Root, {
|
|
1423
|
+
...composableProps(props),
|
|
1424
|
+
gutter,
|
|
1425
|
+
classNames: [
|
|
1426
|
+
"w-full min-w-0",
|
|
1427
|
+
span
|
|
1428
|
+
],
|
|
1429
|
+
ref: forwardedRef
|
|
1430
|
+
}, children);
|
|
1431
|
+
});
|
|
1051
1432
|
FormViewport.displayName = FORM_VIEWPORT_NAME;
|
|
1052
1433
|
var FORM_CONTENT_NAME = "Form.Content";
|
|
1053
|
-
var FormContent = ({
|
|
1434
|
+
var FormContent = composable(({ children, ...props }, forwardedRef) => {
|
|
1054
1435
|
const { form, testId } = useFormContext(FORM_CONTENT_NAME);
|
|
1055
|
-
const
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1436
|
+
const localRef = useRef(null);
|
|
1437
|
+
const mergedRef = useMergeRefs([
|
|
1438
|
+
forwardedRef,
|
|
1439
|
+
localRef
|
|
1440
|
+
]);
|
|
1441
|
+
useKeyHandler(localRef, form);
|
|
1442
|
+
return /* @__PURE__ */ React5.createElement("div", {
|
|
1443
|
+
...composableProps(props, {
|
|
1444
|
+
role: "form",
|
|
1445
|
+
classNames: mx3(withColumn.center(), "flex flex-col w-full")
|
|
1446
|
+
}),
|
|
1447
|
+
"data-testid": testId,
|
|
1448
|
+
ref: mergedRef
|
|
1062
1449
|
}, children);
|
|
1063
|
-
};
|
|
1450
|
+
});
|
|
1064
1451
|
FormContent.displayName = FORM_CONTENT_NAME;
|
|
1065
1452
|
var FORM_FIELDSET_NAME2 = "Form.FieldSet";
|
|
1066
1453
|
var FormFieldSet2 = (props) => {
|
|
1067
1454
|
const { form, ...contextProps } = useFormContext(FORM_FIELDSET_NAME2);
|
|
1068
|
-
return /* @__PURE__ */
|
|
1455
|
+
return /* @__PURE__ */ React5.createElement(FormFieldSet, {
|
|
1069
1456
|
schema: form.schema,
|
|
1070
1457
|
...contextProps,
|
|
1071
1458
|
...props
|
|
1072
1459
|
});
|
|
1073
1460
|
};
|
|
1074
1461
|
FormFieldSet2.displayName = FORM_FIELDSET_NAME2;
|
|
1462
|
+
var FORM_LAYOUT_NAME2 = "Form.Layout";
|
|
1463
|
+
var FormLayout2 = ({ schema, ...props }) => {
|
|
1464
|
+
const { form, ...contextProps } = useFormContext(FORM_LAYOUT_NAME2);
|
|
1465
|
+
const resolvedSchema = schema ?? form.schema;
|
|
1466
|
+
if (!resolvedSchema) {
|
|
1467
|
+
return null;
|
|
1468
|
+
}
|
|
1469
|
+
return /* @__PURE__ */ React5.createElement(FormLayout, {
|
|
1470
|
+
schema: resolvedSchema,
|
|
1471
|
+
...contextProps,
|
|
1472
|
+
...props
|
|
1473
|
+
});
|
|
1474
|
+
};
|
|
1475
|
+
FormLayout2.displayName = FORM_LAYOUT_NAME2;
|
|
1075
1476
|
var FORM_ACTIONS_NAME = "Form.Actions";
|
|
1076
1477
|
var FormActions = ({ classNames }) => {
|
|
1077
|
-
const { t } = useTranslation2(
|
|
1478
|
+
const { t } = useTranslation2(translationKey2);
|
|
1078
1479
|
const { form: { canSave, onSave, onCancel }, readonly, layout } = useFormContext(FORM_ACTIONS_NAME);
|
|
1079
1480
|
if (readonly || layout === "static") {
|
|
1080
1481
|
return null;
|
|
1081
1482
|
}
|
|
1082
|
-
return /* @__PURE__ */
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
}, onCancel && /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1483
|
+
return /* @__PURE__ */ React5.createElement("div", {
|
|
1484
|
+
className: mx3(withColumn.center(), "grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding", classNames)
|
|
1485
|
+
}, onCancel && /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1086
1486
|
icon: "ph--x--regular",
|
|
1087
1487
|
iconEnd: true,
|
|
1088
|
-
label: t("cancel
|
|
1488
|
+
label: t("cancel-button.label"),
|
|
1089
1489
|
onClick: onCancel,
|
|
1090
1490
|
"data-testid": "cancel-button"
|
|
1091
|
-
}), onSave && /* @__PURE__ */
|
|
1491
|
+
}), onSave && /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1092
1492
|
type: "submit",
|
|
1093
1493
|
variant: "primary",
|
|
1094
1494
|
disabled: !canSave,
|
|
1095
1495
|
icon: "ph--check--regular",
|
|
1096
1496
|
iconEnd: true,
|
|
1097
|
-
label: t("save
|
|
1497
|
+
label: t("save-button.label"),
|
|
1098
1498
|
onClick: onSave,
|
|
1099
1499
|
"data-testid": "save-button"
|
|
1100
1500
|
}));
|
|
1101
1501
|
};
|
|
1102
1502
|
FormActions.displayName = FORM_ACTIONS_NAME;
|
|
1503
|
+
var FORM_SECTION_NAME = "Form.Section";
|
|
1504
|
+
var FormSection = composable(({ children, label, description, ...props }, forwardedRef) => {
|
|
1505
|
+
return /* @__PURE__ */ React5.createElement("div", {
|
|
1506
|
+
...composableProps(props, {
|
|
1507
|
+
classNames: "flex flex-col pt-form-section-gap first:pt-0"
|
|
1508
|
+
}),
|
|
1509
|
+
ref: forwardedRef
|
|
1510
|
+
}, label && /* @__PURE__ */ React5.createElement("h2", {
|
|
1511
|
+
className: "text-lg"
|
|
1512
|
+
}, label), description && /* @__PURE__ */ React5.createElement("p", {
|
|
1513
|
+
className: "text-description"
|
|
1514
|
+
}, description), children);
|
|
1515
|
+
});
|
|
1516
|
+
FormSection.displayName = FORM_SECTION_NAME;
|
|
1103
1517
|
var FORM_SUBMIT_NAME = "Form.Submit";
|
|
1104
1518
|
var FormSubmit = ({ classNames, label, icon, disabled }) => {
|
|
1105
|
-
const { t } = useTranslation2(
|
|
1519
|
+
const { t } = useTranslation2(translationKey2);
|
|
1106
1520
|
const { form: { canSave, onSave }, readonly, layout } = useFormContext(FORM_SUBMIT_NAME);
|
|
1107
1521
|
if (readonly || layout === "static") {
|
|
1108
1522
|
return null;
|
|
1109
1523
|
}
|
|
1110
|
-
return /* @__PURE__ */
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
}, /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1524
|
+
return /* @__PURE__ */ React5.createElement("div", {
|
|
1525
|
+
className: mx3("flex w-full pt-form-padding", classNames)
|
|
1526
|
+
}, /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1114
1527
|
classNames: "w-full",
|
|
1115
1528
|
type: "submit",
|
|
1116
1529
|
variant: "primary",
|
|
1117
1530
|
disabled: disabled ?? !canSave,
|
|
1118
1531
|
icon: icon ?? "ph--check--regular",
|
|
1119
|
-
label: label ?? t("save
|
|
1532
|
+
label: label ?? t("save-button.label"),
|
|
1120
1533
|
onClick: onSave,
|
|
1121
1534
|
"data-testid": "save-button"
|
|
1122
1535
|
}));
|
|
1123
1536
|
};
|
|
1124
1537
|
FormSubmit.displayName = FORM_SUBMIT_NAME;
|
|
1538
|
+
var FORM_ERROR_NAME = "Form.Error";
|
|
1539
|
+
var FormError = ({ children, classNames }) => {
|
|
1540
|
+
if (!children) {
|
|
1541
|
+
return null;
|
|
1542
|
+
}
|
|
1543
|
+
return /* @__PURE__ */ React5.createElement(Input3.Root, {
|
|
1544
|
+
validationValence: "error"
|
|
1545
|
+
}, /* @__PURE__ */ React5.createElement(Input3.Validation, {
|
|
1546
|
+
classNames
|
|
1547
|
+
}, children));
|
|
1548
|
+
};
|
|
1549
|
+
FormError.displayName = FORM_ERROR_NAME;
|
|
1125
1550
|
var Form = {
|
|
1126
1551
|
Root: FormRoot,
|
|
1127
1552
|
Viewport: FormViewport,
|
|
1128
1553
|
Content: FormContent,
|
|
1554
|
+
Section: FormSection,
|
|
1129
1555
|
FieldSet: FormFieldSet2,
|
|
1556
|
+
Layout: FormLayout2,
|
|
1130
1557
|
Label: FormFieldLabel,
|
|
1131
1558
|
Actions: FormActions,
|
|
1132
|
-
Submit: FormSubmit
|
|
1559
|
+
Submit: FormSubmit,
|
|
1560
|
+
Error: FormError
|
|
1133
1561
|
};
|
|
1134
1562
|
|
|
1135
1563
|
// src/components/Form/fields/ArrayField.tsx
|
|
1136
1564
|
var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps, ...props }) => {
|
|
1137
|
-
const { t } = useTranslation3(
|
|
1565
|
+
const { t } = useTranslation3(translationKey3);
|
|
1138
1566
|
const elementType = getArrayElementType2(type);
|
|
1139
1567
|
const { onValueChange } = inputProps;
|
|
1140
1568
|
const values = useFormValues(ArrayField.displayName, path, () => []);
|
|
1141
1569
|
const getDefaultObjectValue = (typeNode) => {
|
|
1142
|
-
const baseNode =
|
|
1143
|
-
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) :
|
|
1570
|
+
const baseNode = findNode3(typeNode, isDiscriminatedUnion2);
|
|
1571
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode3(typeNode, SchemaAST6.isTypeLiteral);
|
|
1144
1572
|
if (!typeLiteral) {
|
|
1145
1573
|
return {};
|
|
1146
1574
|
}
|
|
1147
1575
|
return Object.fromEntries(getFormProperties(typeLiteral).map((prop) => {
|
|
1148
|
-
const defaultValue =
|
|
1576
|
+
const defaultValue = SchemaAST6.getDefaultAnnotation(prop.type).pipe((annotation) => Option6.getOrUndefined(annotation));
|
|
1149
1577
|
return [
|
|
1150
1578
|
prop.name,
|
|
1151
1579
|
defaultValue
|
|
@@ -1153,9 +1581,9 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1153
1581
|
}));
|
|
1154
1582
|
};
|
|
1155
1583
|
const handleAdd = useCallback3(() => {
|
|
1156
|
-
const defaultValue =
|
|
1157
|
-
|
|
1158
|
-
...values,
|
|
1584
|
+
const defaultValue = isNestedType3(type) && elementType ? getDefaultObjectValue(elementType) : getDefaultValue(elementType);
|
|
1585
|
+
onValueChange(type, [
|
|
1586
|
+
...values ?? [],
|
|
1159
1587
|
defaultValue
|
|
1160
1588
|
]);
|
|
1161
1589
|
}, [
|
|
@@ -1174,47 +1602,49 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1174
1602
|
if (!elementType || (readonly || layout === "static") && values && values.length < 1) {
|
|
1175
1603
|
return null;
|
|
1176
1604
|
}
|
|
1177
|
-
|
|
1605
|
+
const renderItemAsObject = elementType && isNestedType3(elementType) && !Ref2.isRefType(elementType);
|
|
1606
|
+
return /* @__PURE__ */ React6.createElement(React6.Fragment, null, (layout !== "static" || values && values.length > 0) && /* @__PURE__ */ React6.createElement("div", {
|
|
1607
|
+
className: "flex items-center gap-2"
|
|
1608
|
+
}, /* @__PURE__ */ React6.createElement("div", {
|
|
1609
|
+
className: "flex-1 min-w-0"
|
|
1610
|
+
}, /* @__PURE__ */ React6.createElement(FormFieldLabel, {
|
|
1178
1611
|
readonly,
|
|
1179
1612
|
label,
|
|
1613
|
+
path: createJsonPath6(path ?? []),
|
|
1180
1614
|
asChild: true
|
|
1181
|
-
}), /* @__PURE__ */
|
|
1182
|
-
|
|
1183
|
-
|
|
1615
|
+
})), !readonly && layout !== "static" && /* @__PURE__ */ React6.createElement(IconBlock, {
|
|
1616
|
+
inline: true,
|
|
1617
|
+
icon: "ph--plus--regular",
|
|
1618
|
+
label: t("add-item.button"),
|
|
1619
|
+
onClick: handleAdd
|
|
1620
|
+
})), /* @__PURE__ */ React6.createElement("div", {
|
|
1621
|
+
className: "flex flex-col"
|
|
1184
1622
|
}, values?.map((_, index) => {
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
}, /* @__PURE__ */ React5.createElement(FormField, {
|
|
1190
|
-
autoFocus: index === values.length - 1,
|
|
1623
|
+
const isLast = index === values.length - 1;
|
|
1624
|
+
const fieldField = /* @__PURE__ */ React6.createElement(FormField, {
|
|
1625
|
+
...props,
|
|
1626
|
+
autoFocus: isLast,
|
|
1191
1627
|
type: elementType,
|
|
1628
|
+
...renderItemAsObject && {
|
|
1629
|
+
name: null
|
|
1630
|
+
},
|
|
1192
1631
|
path: [
|
|
1193
1632
|
...path ?? [],
|
|
1194
1633
|
index
|
|
1195
1634
|
],
|
|
1196
1635
|
readonly: readonly || layout === "static",
|
|
1197
|
-
layout: "inline"
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
className: "
|
|
1202
|
-
}, /* @__PURE__ */
|
|
1203
|
-
|
|
1204
|
-
className: "flex items-center h-[2rem]"
|
|
1205
|
-
}, /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1636
|
+
layout: renderItemAsObject ? layout === "static" ? "static" : void 0 : "inline"
|
|
1637
|
+
});
|
|
1638
|
+
return /* @__PURE__ */ React6.createElement("div", {
|
|
1639
|
+
key: index,
|
|
1640
|
+
className: "grid grid-cols-[1fr_min-content] items-center mb-1 last:mb-form-gap"
|
|
1641
|
+
}, fieldField, !readonly && layout !== "static" && /* @__PURE__ */ React6.createElement(IconBlock, {
|
|
1642
|
+
inline: !renderItemAsObject,
|
|
1206
1643
|
icon: "ph--x--regular",
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
}))));
|
|
1212
|
-
})), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1213
|
-
classNames: "flex w-full",
|
|
1214
|
-
icon: "ph--plus--regular",
|
|
1215
|
-
label: t("add field"),
|
|
1216
|
-
onClick: handleAdd
|
|
1217
|
-
}));
|
|
1644
|
+
label: t("remove-item.button"),
|
|
1645
|
+
onClick: () => handleDelete(index)
|
|
1646
|
+
}));
|
|
1647
|
+
})));
|
|
1218
1648
|
};
|
|
1219
1649
|
ArrayField.displayName = "Form.ArrayField";
|
|
1220
1650
|
var getDefaultValue = (ast) => {
|
|
@@ -1232,7 +1662,7 @@ var getDefaultValue = (ast) => {
|
|
|
1232
1662
|
return getDefaultValue(ast.f());
|
|
1233
1663
|
}
|
|
1234
1664
|
default: {
|
|
1235
|
-
if (ast &&
|
|
1665
|
+
if (ast && isNestedType3(ast)) {
|
|
1236
1666
|
return {};
|
|
1237
1667
|
} else {
|
|
1238
1668
|
throw new Error(`Unsupported type: ${ast?._tag}`);
|
|
@@ -1242,50 +1672,124 @@ var getDefaultValue = (ast) => {
|
|
|
1242
1672
|
};
|
|
1243
1673
|
|
|
1244
1674
|
// src/components/Form/fields/BooleanField.tsx
|
|
1245
|
-
import
|
|
1246
|
-
import { Input as
|
|
1675
|
+
import React7, { useCallback as useCallback4 } from "react";
|
|
1676
|
+
import { Input as Input4 } from "@dxos/react-ui";
|
|
1247
1677
|
var BooleanField = ({ type, readonly, onValueChange, ...props }) => {
|
|
1248
1678
|
const handleChange = useCallback4((value3) => onValueChange?.(type, value3), [
|
|
1249
1679
|
type,
|
|
1250
1680
|
onValueChange
|
|
1251
1681
|
]);
|
|
1252
|
-
return /* @__PURE__ */
|
|
1682
|
+
return /* @__PURE__ */ React7.createElement(FormFieldWrapper, {
|
|
1253
1683
|
readonly,
|
|
1254
1684
|
...props
|
|
1255
|
-
}, ({ value: value3 }) => /* @__PURE__ */
|
|
1685
|
+
}, ({ value: value3 }) => /* @__PURE__ */ React7.createElement(Input4.Switch, {
|
|
1256
1686
|
disabled: !!readonly,
|
|
1257
1687
|
checked: value3,
|
|
1258
1688
|
onCheckedChange: handleChange
|
|
1259
1689
|
}));
|
|
1260
1690
|
};
|
|
1261
1691
|
|
|
1692
|
+
// src/components/Form/fields/DateField.tsx
|
|
1693
|
+
import { format as formatDate3 } from "date-fns";
|
|
1694
|
+
import React8, { useCallback as useCallback5 } from "react";
|
|
1695
|
+
import { Format as Format5 } from "@dxos/echo";
|
|
1696
|
+
import { Input as Input5 } from "@dxos/react-ui";
|
|
1697
|
+
var isoToLocalDateTime = (value3) => {
|
|
1698
|
+
if (!value3) {
|
|
1699
|
+
return "";
|
|
1700
|
+
}
|
|
1701
|
+
const date = new Date(value3);
|
|
1702
|
+
if (Number.isNaN(date.getTime())) {
|
|
1703
|
+
return "";
|
|
1704
|
+
}
|
|
1705
|
+
return formatDate3(date, "yyyy-MM-dd'T'HH:mm");
|
|
1706
|
+
};
|
|
1707
|
+
var localDateTimeToIso = (value3) => {
|
|
1708
|
+
if (!value3) {
|
|
1709
|
+
return void 0;
|
|
1710
|
+
}
|
|
1711
|
+
const date = new Date(value3);
|
|
1712
|
+
return Number.isNaN(date.getTime()) ? void 0 : date.toISOString();
|
|
1713
|
+
};
|
|
1714
|
+
var DateField = ({ type, format, readonly, placeholder: _placeholder, onValueChange, onBlur: _onBlur, ...props }) => {
|
|
1715
|
+
const handleSimpleChange = useCallback5((next) => onValueChange(type, next), [
|
|
1716
|
+
type,
|
|
1717
|
+
onValueChange
|
|
1718
|
+
]);
|
|
1719
|
+
const handleDateTimeChange = useCallback5((next) => {
|
|
1720
|
+
const iso = localDateTimeToIso(next);
|
|
1721
|
+
onValueChange(type, iso);
|
|
1722
|
+
}, [
|
|
1723
|
+
type,
|
|
1724
|
+
onValueChange
|
|
1725
|
+
]);
|
|
1726
|
+
return /* @__PURE__ */ React8.createElement(FormFieldWrapper, {
|
|
1727
|
+
readonly,
|
|
1728
|
+
format,
|
|
1729
|
+
...props
|
|
1730
|
+
}, ({ value: value3 }) => {
|
|
1731
|
+
switch (format) {
|
|
1732
|
+
case Format5.TypeFormat.Date:
|
|
1733
|
+
return /* @__PURE__ */ React8.createElement("div", {
|
|
1734
|
+
className: "grid grid-cols-[minmax(0,1fr)_min-content] items-stretch gap-1"
|
|
1735
|
+
}, /* @__PURE__ */ React8.createElement(Input5.Date, {
|
|
1736
|
+
classNames: "min-w-0 overflow-hidden",
|
|
1737
|
+
disabled: !!readonly,
|
|
1738
|
+
value: value3 ?? "",
|
|
1739
|
+
onValueChange: handleSimpleChange
|
|
1740
|
+
}), /* @__PURE__ */ React8.createElement(Input5.TriggerIcon, {
|
|
1741
|
+
classNames: "h-full"
|
|
1742
|
+
}));
|
|
1743
|
+
case Format5.TypeFormat.Time:
|
|
1744
|
+
return /* @__PURE__ */ React8.createElement(Input5.Time, {
|
|
1745
|
+
disabled: !!readonly,
|
|
1746
|
+
value: value3 ?? "",
|
|
1747
|
+
onValueChange: handleSimpleChange
|
|
1748
|
+
});
|
|
1749
|
+
case Format5.TypeFormat.DateTime:
|
|
1750
|
+
default:
|
|
1751
|
+
return /* @__PURE__ */ React8.createElement("div", {
|
|
1752
|
+
className: "grid grid-cols-[minmax(0,1fr)_min-content] items-stretch gap-1"
|
|
1753
|
+
}, /* @__PURE__ */ React8.createElement(Input5.DateTime, {
|
|
1754
|
+
classNames: "min-w-0 overflow-hidden",
|
|
1755
|
+
disabled: !!readonly,
|
|
1756
|
+
value: isoToLocalDateTime(value3),
|
|
1757
|
+
onValueChange: handleDateTimeChange
|
|
1758
|
+
}), /* @__PURE__ */ React8.createElement(Input5.TriggerIcon, {
|
|
1759
|
+
classNames: "h-full"
|
|
1760
|
+
}));
|
|
1761
|
+
}
|
|
1762
|
+
});
|
|
1763
|
+
};
|
|
1764
|
+
|
|
1262
1765
|
// src/components/Form/fields/GeoPointField.tsx
|
|
1263
|
-
import
|
|
1766
|
+
import React9, { useCallback as useCallback6, useEffect as useEffect3, useMemo as useMemo6, useState as useState2 } from "react";
|
|
1264
1767
|
import { GeoLocation as GeoLocation3 } from "@dxos/echo/internal";
|
|
1265
|
-
import { Input as
|
|
1768
|
+
import { Input as Input6, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
1266
1769
|
import { safeParseFloat } from "@dxos/util";
|
|
1267
|
-
|
|
1268
|
-
|
|
1770
|
+
import { translationKey as translationKey4 } from "#translations";
|
|
1771
|
+
var GeoPointField = ({ type, label, jsonPath, readonly, layout, getStatus, getValue, onValueChange, onBlur }) => {
|
|
1772
|
+
const { t } = useTranslation4(translationKey4);
|
|
1269
1773
|
const { status, error } = getStatus();
|
|
1270
|
-
const geoPoint =
|
|
1774
|
+
const geoPoint = useMemo6(() => getValue() ?? [
|
|
1271
1775
|
0,
|
|
1272
1776
|
0
|
|
1273
1777
|
], [
|
|
1274
1778
|
getValue
|
|
1275
1779
|
]);
|
|
1276
|
-
const value3 =
|
|
1780
|
+
const value3 = useMemo6(() => GeoLocation3.fromGeoPoint(geoPoint), [
|
|
1277
1781
|
geoPoint
|
|
1278
1782
|
]);
|
|
1279
1783
|
const [longitudeText, setLongitudeText] = useState2(value3.longitude?.toString());
|
|
1280
1784
|
const [latitudeText, setLatitudeText] = useState2(value3.latitude?.toString());
|
|
1281
|
-
|
|
1785
|
+
useEffect3(() => {
|
|
1282
1786
|
const location = GeoLocation3.fromGeoPoint(geoPoint);
|
|
1283
1787
|
setLongitudeText(location.longitude?.toString());
|
|
1284
1788
|
setLatitudeText(location.latitude?.toString());
|
|
1285
1789
|
}, [
|
|
1286
1790
|
geoPoint
|
|
1287
1791
|
]);
|
|
1288
|
-
const handleChange =
|
|
1792
|
+
const handleChange = useCallback6((coordinateType, setText) => (event) => {
|
|
1289
1793
|
const inputText = event.target.value;
|
|
1290
1794
|
setText(inputText);
|
|
1291
1795
|
if (inputText !== "" && inputText !== "-") {
|
|
@@ -1311,33 +1815,33 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
|
|
|
1311
1815
|
if ((readonly || layout === "static") && !value3?.latitude && !value3?.longitude) {
|
|
1312
1816
|
return null;
|
|
1313
1817
|
}
|
|
1314
|
-
return /* @__PURE__ */
|
|
1818
|
+
return /* @__PURE__ */ React9.createElement(Input6.Root, {
|
|
1315
1819
|
validationValence: status
|
|
1316
|
-
}, layout !== "inline" && /* @__PURE__ */
|
|
1820
|
+
}, layout !== "inline" && /* @__PURE__ */ React9.createElement(FormFieldLabel, {
|
|
1317
1821
|
error,
|
|
1318
1822
|
readonly,
|
|
1319
1823
|
label,
|
|
1824
|
+
path: jsonPath,
|
|
1320
1825
|
asChild: true
|
|
1321
|
-
}), layout === "static" ? /* @__PURE__ */
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
}, /* @__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, {
|
|
1826
|
+
}), layout === "static" ? /* @__PURE__ */ React9.createElement(LatLng, value3) : /* @__PURE__ */ React9.createElement("div", {
|
|
1827
|
+
className: "grid grid-cols-2 gap-form-gap"
|
|
1828
|
+
}, /* @__PURE__ */ React9.createElement("div", null, /* @__PURE__ */ React9.createElement(Input6.Root, null, layout !== "inline" && /* @__PURE__ */ React9.createElement(Input6.Label, null, t("latitude.label")), /* @__PURE__ */ React9.createElement(Input6.TextInput, {
|
|
1325
1829
|
type: "number",
|
|
1326
1830
|
step: "0.00001",
|
|
1327
1831
|
min: "-90",
|
|
1328
1832
|
max: "90",
|
|
1329
1833
|
disabled: !!readonly,
|
|
1330
|
-
placeholder: t("latitude
|
|
1834
|
+
placeholder: t("latitude.placeholder"),
|
|
1331
1835
|
value: latitudeText ?? "",
|
|
1332
1836
|
onChange: handleChange("latitude", setLatitudeText),
|
|
1333
1837
|
onBlur
|
|
1334
|
-
}))), /* @__PURE__ */
|
|
1838
|
+
}))), /* @__PURE__ */ React9.createElement("div", null, /* @__PURE__ */ React9.createElement(Input6.Root, null, layout !== "inline" && /* @__PURE__ */ React9.createElement(Input6.Label, null, t("longitude.label")), /* @__PURE__ */ React9.createElement(Input6.TextInput, {
|
|
1335
1839
|
type: "number",
|
|
1336
1840
|
step: "0.00001",
|
|
1337
1841
|
min: "-180",
|
|
1338
1842
|
max: "180",
|
|
1339
1843
|
disabled: !!readonly,
|
|
1340
|
-
placeholder: t("longitude
|
|
1844
|
+
placeholder: t("longitude.placeholder"),
|
|
1341
1845
|
value: longitudeText ?? "",
|
|
1342
1846
|
onChange: handleChange("longitude", setLongitudeText),
|
|
1343
1847
|
onBlur
|
|
@@ -1346,81 +1850,265 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
|
|
|
1346
1850
|
var LatLng = ({ latitude = 0, longitude = 0 }) => {
|
|
1347
1851
|
const latHem = latitude >= 0 ? "N" : "S";
|
|
1348
1852
|
const lngHem = longitude >= 0 ? "E" : "W";
|
|
1349
|
-
return /* @__PURE__ */
|
|
1350
|
-
className: "inline-flex items-center gap-
|
|
1351
|
-
}, /* @__PURE__ */
|
|
1853
|
+
return /* @__PURE__ */ React9.createElement("span", {
|
|
1854
|
+
className: "inline-flex items-center gap-form-gap"
|
|
1855
|
+
}, /* @__PURE__ */ React9.createElement("span", null, /* @__PURE__ */ React9.createElement("span", null, Math.abs(latitude).toFixed(5)), /* @__PURE__ */ React9.createElement("span", {
|
|
1352
1856
|
className: "text-subdued"
|
|
1353
|
-
}, "\xB0", latHem)), /* @__PURE__ */
|
|
1857
|
+
}, "\xB0", latHem)), /* @__PURE__ */ React9.createElement("span", null, /* @__PURE__ */ React9.createElement("span", null, Math.abs(longitude).toFixed(5)), /* @__PURE__ */ React9.createElement("span", {
|
|
1354
1858
|
className: "text-subdued"
|
|
1355
1859
|
}, "\xB0", lngHem)));
|
|
1356
1860
|
};
|
|
1357
1861
|
|
|
1358
|
-
// src/components/Form/fields/
|
|
1359
|
-
import
|
|
1360
|
-
import {
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
}
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
adjustHeight
|
|
1862
|
+
// src/components/Form/fields/InlineRefField.tsx
|
|
1863
|
+
import { useAtomValue } from "@effect-atom/atom-react";
|
|
1864
|
+
import React10, { useCallback as useCallback7, useMemo as useMemo7 } from "react";
|
|
1865
|
+
import { Obj, Ref as Ref3, Type as Type2 } from "@dxos/echo";
|
|
1866
|
+
import { AtomRef } from "@dxos/echo-atom";
|
|
1867
|
+
import { useType as defaultUseType } from "@dxos/echo-react";
|
|
1868
|
+
import { ReferenceAnnotationId as ReferenceAnnotationId2, splitJsonPath } from "@dxos/echo/internal";
|
|
1869
|
+
import { findAnnotation as findAnnotation2 } from "@dxos/effect";
|
|
1870
|
+
import { Button, Icon as Icon2, Input as Input7, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
1871
|
+
import { translationKey as translationKey5 } from "#translations";
|
|
1872
|
+
var InlineRefField = (props) => {
|
|
1873
|
+
const { type, readonly, label, jsonPath, layout, db, getValue, onValueChange, onCreate, useType: useType2 = defaultUseType } = props;
|
|
1874
|
+
const { t } = useTranslation5(translationKey5);
|
|
1875
|
+
const reference = getValue();
|
|
1876
|
+
const typename = useMemo7(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
|
|
1877
|
+
type
|
|
1375
1878
|
]);
|
|
1376
|
-
|
|
1377
|
-
|
|
1879
|
+
const createType = useType2(db, typename);
|
|
1880
|
+
const handleCreate = useCallback7(async () => {
|
|
1881
|
+
if (!createType || !onCreate) {
|
|
1882
|
+
return;
|
|
1883
|
+
}
|
|
1884
|
+
const newObject = await onCreate(createType, {});
|
|
1885
|
+
if (newObject) {
|
|
1886
|
+
onValueChange(type, Ref3.make(newObject));
|
|
1887
|
+
}
|
|
1378
1888
|
}, [
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
]);
|
|
1382
|
-
const handleChange = useCallback6((event) => onValueChange(type, event.target.value), [
|
|
1889
|
+
createType,
|
|
1890
|
+
onCreate,
|
|
1383
1891
|
type,
|
|
1384
1892
|
onValueChange
|
|
1385
1893
|
]);
|
|
1894
|
+
if (readonly && !reference) {
|
|
1895
|
+
return null;
|
|
1896
|
+
}
|
|
1897
|
+
return /* @__PURE__ */ React10.createElement(Input7.Root, null, layout !== "inline" && /* @__PURE__ */ React10.createElement(FormFieldLabel, {
|
|
1898
|
+
readonly,
|
|
1899
|
+
label,
|
|
1900
|
+
path: jsonPath
|
|
1901
|
+
}), reference ? /* @__PURE__ */ React10.createElement(InlineForm, {
|
|
1902
|
+
reference,
|
|
1903
|
+
db,
|
|
1904
|
+
readonly,
|
|
1905
|
+
useType: useType2
|
|
1906
|
+
}) : !readonly && onCreate && /* @__PURE__ */ React10.createElement(Button, {
|
|
1907
|
+
classNames: "w-full gap-form-gap",
|
|
1908
|
+
disabled: !createType || !db,
|
|
1909
|
+
onClick: () => void handleCreate()
|
|
1910
|
+
}, /* @__PURE__ */ React10.createElement(Icon2, {
|
|
1911
|
+
icon: "ph--plus--regular",
|
|
1912
|
+
size: 4
|
|
1913
|
+
}), /* @__PURE__ */ React10.createElement("span", null, label || t("ref-field.placeholder"))));
|
|
1914
|
+
};
|
|
1915
|
+
var InlineForm = ({ reference, db, readonly, useType: useType2 = defaultUseType }) => {
|
|
1916
|
+
const target = useAtomValue(useMemo7(() => AtomRef.make(reference), [
|
|
1917
|
+
reference
|
|
1918
|
+
]));
|
|
1919
|
+
const typename = target ? Obj.getTypename(target) ?? void 0 : void 0;
|
|
1920
|
+
const typeFromRegistry = useType2(db, typename);
|
|
1921
|
+
const targetType = target && Obj.getType(target) || typeFromRegistry;
|
|
1922
|
+
const formSchema = useMemo7(() => targetType ? omitId(Type2.getSchema(targetType)) : void 0, [
|
|
1923
|
+
targetType
|
|
1924
|
+
]);
|
|
1925
|
+
const defaultValues = useMemo7(() => target ? {
|
|
1926
|
+
...target
|
|
1927
|
+
} : {}, [
|
|
1928
|
+
target
|
|
1929
|
+
]);
|
|
1930
|
+
const handleChange = useCallback7((values, { isValid, changed }) => {
|
|
1931
|
+
if (!isValid || !target) {
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1934
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
1935
|
+
if (changedPaths.length === 0) {
|
|
1936
|
+
return;
|
|
1937
|
+
}
|
|
1938
|
+
Obj.update(target, () => {
|
|
1939
|
+
for (const path of changedPaths) {
|
|
1940
|
+
const parts = splitJsonPath(path);
|
|
1941
|
+
Obj.setValue(target, parts, Obj.getValue(values, parts));
|
|
1942
|
+
}
|
|
1943
|
+
});
|
|
1944
|
+
}, [
|
|
1945
|
+
target
|
|
1946
|
+
]);
|
|
1947
|
+
if (!target || !formSchema) {
|
|
1948
|
+
return null;
|
|
1949
|
+
}
|
|
1950
|
+
return /* @__PURE__ */ React10.createElement(Nesting, null, /* @__PURE__ */ React10.createElement(Form.Root, {
|
|
1951
|
+
schema: formSchema,
|
|
1952
|
+
defaultValues,
|
|
1953
|
+
db,
|
|
1954
|
+
onValuesChanged: handleChange
|
|
1955
|
+
}, /* @__PURE__ */ React10.createElement(Form.Content, null, /* @__PURE__ */ React10.createElement(Form.FieldSet, {
|
|
1956
|
+
readonly
|
|
1957
|
+
}))));
|
|
1958
|
+
};
|
|
1959
|
+
|
|
1960
|
+
// src/components/Form/fields/MarkdownField.tsx
|
|
1961
|
+
import { useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
|
|
1962
|
+
import React11, { useCallback as useCallback8, useMemo as useMemo8 } from "react";
|
|
1963
|
+
import { Obj as Obj2, Ref as Ref4 } from "@dxos/echo";
|
|
1964
|
+
import { AtomRef as AtomRef2 } from "@dxos/echo-atom";
|
|
1965
|
+
import { createDocAccessor } from "@dxos/echo-db";
|
|
1966
|
+
import { Button as Button2, Icon as Icon3, Input as Input8, useTranslation as useTranslation6 } from "@dxos/react-ui";
|
|
1967
|
+
import { Editor, useBasicMarkdownExtensions } from "@dxos/react-ui-editor";
|
|
1968
|
+
import { Text } from "@dxos/schema";
|
|
1969
|
+
import { createDataExtensions } from "@dxos/ui-editor";
|
|
1970
|
+
import { translationKey as translationKey6 } from "#translations";
|
|
1971
|
+
var editorClassNames = "transition-colors bg-input-surface focus-within:bg-focus-surface border border-separator rounded-xs p-1 px-2";
|
|
1972
|
+
var MarkdownField = ({ type, readonly, label, jsonPath, placeholder, layout, db, getStatus, getValue, onValueChange }) => {
|
|
1973
|
+
const { status, error } = getStatus();
|
|
1974
|
+
const isRef = Ref4.isRefType(type);
|
|
1386
1975
|
const value3 = getValue();
|
|
1387
|
-
if ((readonly || layout === "static") &&
|
|
1976
|
+
if ((readonly || layout === "static") && value3 == null) {
|
|
1388
1977
|
return null;
|
|
1389
1978
|
}
|
|
1390
|
-
|
|
1979
|
+
const renderEditor = () => {
|
|
1980
|
+
if (isRef) {
|
|
1981
|
+
const reference = value3;
|
|
1982
|
+
if (reference) {
|
|
1983
|
+
return /* @__PURE__ */ React11.createElement(RefMarkdownEditor, {
|
|
1984
|
+
reference,
|
|
1985
|
+
placeholder
|
|
1986
|
+
});
|
|
1987
|
+
}
|
|
1988
|
+
if (readonly) {
|
|
1989
|
+
return null;
|
|
1990
|
+
}
|
|
1991
|
+
return /* @__PURE__ */ React11.createElement(CreateTextButton, {
|
|
1992
|
+
db,
|
|
1993
|
+
disabled: !db,
|
|
1994
|
+
onCreate: (ref) => onValueChange(type, ref)
|
|
1995
|
+
});
|
|
1996
|
+
}
|
|
1997
|
+
return /* @__PURE__ */ React11.createElement(StringMarkdownEditor, {
|
|
1998
|
+
value: value3 ?? "",
|
|
1999
|
+
placeholder,
|
|
2000
|
+
readonly: !!readonly,
|
|
2001
|
+
onChange: (next) => onValueChange(type, next)
|
|
2002
|
+
});
|
|
2003
|
+
};
|
|
2004
|
+
const renderStatic = () => {
|
|
2005
|
+
if (isRef) {
|
|
2006
|
+
const reference = value3;
|
|
2007
|
+
return reference ? /* @__PURE__ */ React11.createElement(RefStaticText, {
|
|
2008
|
+
reference
|
|
2009
|
+
}) : null;
|
|
2010
|
+
}
|
|
2011
|
+
return /* @__PURE__ */ React11.createElement("p", {
|
|
2012
|
+
className: "whitespace-pre-wrap"
|
|
2013
|
+
}, value3 ?? "");
|
|
2014
|
+
};
|
|
2015
|
+
return /* @__PURE__ */ React11.createElement(Input8.Root, {
|
|
1391
2016
|
validationValence: status
|
|
1392
|
-
}, layout !== "inline" && /* @__PURE__ */
|
|
2017
|
+
}, layout !== "inline" && /* @__PURE__ */ React11.createElement(FormFieldLabel, {
|
|
1393
2018
|
error,
|
|
1394
2019
|
readonly,
|
|
1395
|
-
label
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
2020
|
+
label,
|
|
2021
|
+
path: jsonPath
|
|
2022
|
+
}), layout === "static" ? renderStatic() : renderEditor(), layout === "full" && /* @__PURE__ */ React11.createElement(Input8.Validation, null, error));
|
|
2023
|
+
};
|
|
2024
|
+
var RefStaticText = ({ reference }) => {
|
|
2025
|
+
const text = useAtomValue2(useMemo8(() => AtomRef2.make(reference), [
|
|
2026
|
+
reference
|
|
2027
|
+
]));
|
|
2028
|
+
if (!text?.content) {
|
|
2029
|
+
return null;
|
|
2030
|
+
}
|
|
2031
|
+
return /* @__PURE__ */ React11.createElement("p", {
|
|
2032
|
+
className: "whitespace-pre-wrap"
|
|
2033
|
+
}, text.content);
|
|
2034
|
+
};
|
|
2035
|
+
var RefMarkdownEditor = ({ reference, placeholder }) => {
|
|
2036
|
+
const text = useAtomValue2(useMemo8(() => AtomRef2.make(reference), [
|
|
2037
|
+
reference
|
|
2038
|
+
]));
|
|
2039
|
+
const dataExtensions = useMemo8(() => text ? [
|
|
2040
|
+
createDataExtensions({
|
|
2041
|
+
id: reference.uri,
|
|
2042
|
+
text: createDocAccessor(text, [
|
|
2043
|
+
"content"
|
|
2044
|
+
])
|
|
2045
|
+
})
|
|
2046
|
+
] : [], [
|
|
2047
|
+
text,
|
|
2048
|
+
reference
|
|
2049
|
+
]);
|
|
2050
|
+
const extensions = useBasicMarkdownExtensions({
|
|
1399
2051
|
placeholder,
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
})
|
|
2052
|
+
extensions: dataExtensions
|
|
2053
|
+
});
|
|
2054
|
+
if (!text) {
|
|
2055
|
+
return null;
|
|
2056
|
+
}
|
|
2057
|
+
return /* @__PURE__ */ React11.createElement(Editor.Root, null, /* @__PURE__ */ React11.createElement(Editor.View, {
|
|
2058
|
+
classNames: editorClassNames,
|
|
2059
|
+
extensions
|
|
2060
|
+
}));
|
|
2061
|
+
};
|
|
2062
|
+
var StringMarkdownEditor = ({ value: value3, placeholder, readonly, onChange }) => {
|
|
2063
|
+
const extensions = useBasicMarkdownExtensions({
|
|
2064
|
+
placeholder
|
|
2065
|
+
});
|
|
2066
|
+
const handleChange = useCallback8((next) => onChange(next), [
|
|
2067
|
+
onChange
|
|
2068
|
+
]);
|
|
2069
|
+
return /* @__PURE__ */ React11.createElement(Editor.Root, null, /* @__PURE__ */ React11.createElement(Editor.View, {
|
|
2070
|
+
classNames: editorClassNames,
|
|
2071
|
+
extensions,
|
|
2072
|
+
value: value3,
|
|
2073
|
+
onChange: readonly ? void 0 : handleChange
|
|
2074
|
+
}));
|
|
2075
|
+
};
|
|
2076
|
+
var CreateTextButton = ({ db, disabled, onCreate }) => {
|
|
2077
|
+
const { t } = useTranslation6(translationKey6);
|
|
2078
|
+
const handleClick = useCallback8(() => {
|
|
2079
|
+
if (!db) {
|
|
2080
|
+
return;
|
|
2081
|
+
}
|
|
2082
|
+
const text = db.add(Obj2.make(Text.Text, {
|
|
2083
|
+
content: ""
|
|
2084
|
+
}));
|
|
2085
|
+
onCreate(Ref4.make(text));
|
|
2086
|
+
}, [
|
|
2087
|
+
db,
|
|
2088
|
+
onCreate
|
|
2089
|
+
]);
|
|
2090
|
+
return /* @__PURE__ */ React11.createElement(Button2, {
|
|
2091
|
+
onClick: handleClick,
|
|
2092
|
+
disabled
|
|
2093
|
+
}, /* @__PURE__ */ React11.createElement(Icon3, {
|
|
2094
|
+
icon: "ph--plus--regular",
|
|
2095
|
+
size: 4
|
|
2096
|
+
}), /* @__PURE__ */ React11.createElement("span", null, t("create-text.label")));
|
|
1409
2097
|
};
|
|
1410
2098
|
|
|
1411
2099
|
// src/components/Form/fields/NumberField.tsx
|
|
1412
|
-
import
|
|
1413
|
-
import { Input as
|
|
2100
|
+
import React12, { useCallback as useCallback9 } from "react";
|
|
2101
|
+
import { Input as Input9 } from "@dxos/react-ui";
|
|
1414
2102
|
import { safeParseFloat as safeParseFloat2 } from "@dxos/util";
|
|
1415
2103
|
var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props }) => {
|
|
1416
|
-
const handleChange =
|
|
2104
|
+
const handleChange = useCallback9((event) => onValueChange(type, safeParseFloat2(event.target.value) || 0), [
|
|
1417
2105
|
type,
|
|
1418
2106
|
onValueChange
|
|
1419
2107
|
]);
|
|
1420
|
-
return /* @__PURE__ */
|
|
2108
|
+
return /* @__PURE__ */ React12.createElement(FormFieldWrapper, {
|
|
1421
2109
|
readonly,
|
|
1422
2110
|
...props
|
|
1423
|
-
}, ({ value: value3 = "" }) => /* @__PURE__ */
|
|
2111
|
+
}, ({ value: value3 = "" }) => /* @__PURE__ */ React12.createElement(Input9.TextInput, {
|
|
1424
2112
|
type: "number",
|
|
1425
2113
|
disabled: !!readonly,
|
|
1426
2114
|
placeholder,
|
|
@@ -1431,58 +2119,43 @@ var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...prop
|
|
|
1431
2119
|
};
|
|
1432
2120
|
|
|
1433
2121
|
// src/components/Form/fields/RefField.tsx
|
|
2122
|
+
import React14, { useCallback as useCallback11, useMemo as useMemo9, useState as useState4 } from "react";
|
|
1434
2123
|
import "@dxos/lit-ui/dx-tag-picker.pcss";
|
|
1435
|
-
import
|
|
1436
|
-
import {
|
|
1437
|
-
import { ReferenceAnnotationId } from "@dxos/echo/internal";
|
|
1438
|
-
import {
|
|
1439
|
-
import {
|
|
1440
|
-
import { DXN } from "@dxos/keys";
|
|
2124
|
+
import { Entity, Filter, Obj as Obj3, Ref as Ref5, Type as Type3 } from "@dxos/echo";
|
|
2125
|
+
import { useQuery, useType as defaultUseType2 } from "@dxos/echo-react";
|
|
2126
|
+
import { ANY_OBJECT_TYPENAME, ReferenceAnnotationId as ReferenceAnnotationId3 } from "@dxos/echo/internal";
|
|
2127
|
+
import { findAnnotation as findAnnotation3 } from "@dxos/effect";
|
|
2128
|
+
import { URI } from "@dxos/keys";
|
|
1441
2129
|
import { DxAnchor } from "@dxos/lit-ui/react";
|
|
1442
|
-
import { Button, Icon as
|
|
2130
|
+
import { Button as Button3, Icon as Icon4, Input as Input10, useTranslation as useTranslation8 } from "@dxos/react-ui";
|
|
1443
2131
|
import { ParentLabelAnnotationId } from "@dxos/schema";
|
|
1444
|
-
import {
|
|
2132
|
+
import { translationKey as translationKey8 } from "#translations";
|
|
1445
2133
|
|
|
1446
2134
|
// src/components/ObjectPicker/ObjectPicker.tsx
|
|
1447
|
-
import
|
|
1448
|
-
import { Popover, useTranslation as
|
|
1449
|
-
import { Combobox
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
value: "__create__",
|
|
1455
|
-
label: t(createOptionLabel[0], {
|
|
1456
|
-
ns: createOptionLabel[1].ns,
|
|
1457
|
-
text: query
|
|
1458
|
-
}),
|
|
1459
|
-
icon: createOptionIcon,
|
|
1460
|
-
classNames: "flex items-center gap-2",
|
|
1461
|
-
closeOnSelect: false,
|
|
1462
|
-
onSelect: () => {
|
|
1463
|
-
onCreateItemSelect(query);
|
|
1464
|
-
}
|
|
1465
|
-
});
|
|
1466
|
-
};
|
|
1467
|
-
var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
|
|
1468
|
-
const { t } = useTranslation5(translationKey);
|
|
2135
|
+
import React13, { forwardRef, useCallback as useCallback10, useState as useState3 } from "react";
|
|
2136
|
+
import { Popover, useTranslation as useTranslation7 } from "@dxos/react-ui";
|
|
2137
|
+
import { Combobox } from "@dxos/react-ui-list";
|
|
2138
|
+
import { useSearchListResults } from "@dxos/react-ui-search";
|
|
2139
|
+
import { translationKey as translationKey7 } from "#translations";
|
|
2140
|
+
var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, onSelect, onCreate, ...props }, forwardedRef) => {
|
|
2141
|
+
const { t } = useTranslation7(translationKey7);
|
|
1469
2142
|
const [showForm, setShowForm] = useState3(false);
|
|
1470
2143
|
const [formInitialValue, setFormInitialValue] = useState3("");
|
|
1471
|
-
const { results, handleSearch } = useSearchListResults({
|
|
2144
|
+
const { results, query, handleSearch } = useSearchListResults({
|
|
1472
2145
|
items: options
|
|
1473
2146
|
});
|
|
1474
|
-
const handleFormSave =
|
|
1475
|
-
onCreate?.(values);
|
|
2147
|
+
const handleFormSave = useCallback10(async (values) => {
|
|
2148
|
+
await onCreate?.(values);
|
|
1476
2149
|
setShowForm(false);
|
|
1477
2150
|
setFormInitialValue("");
|
|
1478
2151
|
}, [
|
|
1479
2152
|
onCreate
|
|
1480
2153
|
]);
|
|
1481
|
-
const handleFormCancel =
|
|
2154
|
+
const handleFormCancel = useCallback10(() => {
|
|
1482
2155
|
setShowForm(false);
|
|
1483
2156
|
setFormInitialValue("");
|
|
1484
2157
|
}, []);
|
|
1485
|
-
const handleKeyDown =
|
|
2158
|
+
const handleKeyDown = useCallback10((event) => {
|
|
1486
2159
|
if (event.key === "Enter" && createSchema && event.currentTarget.querySelector('[role="option"][aria-selected="true"][data-value="__create__"]')) {
|
|
1487
2160
|
event.stopPropagation();
|
|
1488
2161
|
event.preventDefault();
|
|
@@ -1494,39 +2167,66 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
|
|
|
1494
2167
|
}, [
|
|
1495
2168
|
createSchema
|
|
1496
2169
|
]);
|
|
1497
|
-
|
|
2170
|
+
if (showForm && createSchema) {
|
|
2171
|
+
return /* @__PURE__ */ React13.createElement(Combobox.Content, {
|
|
2172
|
+
...props,
|
|
2173
|
+
onKeyDownCapture: handleKeyDown,
|
|
2174
|
+
ref: forwardedRef
|
|
2175
|
+
}, /* @__PURE__ */ React13.createElement(Popover.Viewport, null, /* @__PURE__ */ React13.createElement(Form.Root, {
|
|
2176
|
+
testId: "create-referenced-object-form",
|
|
2177
|
+
schema: createSchema,
|
|
2178
|
+
defaultValues: createInitialValuePath ? {
|
|
2179
|
+
[createInitialValuePath]: formInitialValue
|
|
2180
|
+
} : {},
|
|
2181
|
+
fieldMap: createFieldMap3,
|
|
2182
|
+
onSave: handleFormSave,
|
|
2183
|
+
onCancel: handleFormCancel
|
|
2184
|
+
}, /* @__PURE__ */ React13.createElement(Form.Viewport, null, /* @__PURE__ */ React13.createElement(Form.Content, null, /* @__PURE__ */ React13.createElement(Form.FieldSet, null), /* @__PURE__ */ React13.createElement(Form.Actions, null))))), /* @__PURE__ */ React13.createElement(Combobox.Arrow, null));
|
|
2185
|
+
}
|
|
2186
|
+
return /* @__PURE__ */ React13.createElement(Combobox.Content, {
|
|
1498
2187
|
...props,
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
} : {},
|
|
1508
|
-
onSave: handleFormSave,
|
|
1509
|
-
onCancel: handleFormCancel
|
|
1510
|
-
}, /* @__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(React10.Fragment, null, /* @__PURE__ */ React10.createElement(Combobox.Input, {
|
|
1511
|
-
placeholder: t("ref field combobox input placeholder"),
|
|
1512
|
-
autoFocus: true
|
|
1513
|
-
}), /* @__PURE__ */ React10.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
|
|
2188
|
+
onKeyDownCapture: handleKeyDown,
|
|
2189
|
+
ref: forwardedRef
|
|
2190
|
+
}, /* @__PURE__ */ React13.createElement(Combobox.Input, {
|
|
2191
|
+
placeholder: t("ref-field-combobox-input.placeholder"),
|
|
2192
|
+
autoFocus: true,
|
|
2193
|
+
value: query,
|
|
2194
|
+
onValueChange: handleSearch
|
|
2195
|
+
}), /* @__PURE__ */ React13.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React13.createElement(Combobox.Item, {
|
|
1514
2196
|
key: option.id,
|
|
1515
2197
|
value: option.id,
|
|
1516
2198
|
label: option.label,
|
|
1517
2199
|
checked: selectedIds?.includes(option.id),
|
|
1518
2200
|
onSelect: () => onSelect(option.id),
|
|
1519
2201
|
classNames: "flex items-center gap-2"
|
|
1520
|
-
})),
|
|
2202
|
+
})), createSchema && onCreate && /* @__PURE__ */ React13.createElement(CreateItem, {
|
|
2203
|
+
query,
|
|
1521
2204
|
createOptionLabel,
|
|
1522
|
-
createOptionIcon,
|
|
1523
|
-
onCreateItemSelect: (
|
|
1524
|
-
setFormInitialValue(
|
|
2205
|
+
createOptionIcon: createOptionIcon ?? "ph--plus--regular",
|
|
2206
|
+
onCreateItemSelect: (currentQuery) => {
|
|
2207
|
+
setFormInitialValue(currentQuery);
|
|
1525
2208
|
setShowForm(true);
|
|
1526
2209
|
}
|
|
1527
|
-
}))
|
|
2210
|
+
})), /* @__PURE__ */ React13.createElement(Combobox.Arrow, null));
|
|
1528
2211
|
});
|
|
1529
|
-
|
|
2212
|
+
var CreateItem = ({ query, createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
|
|
2213
|
+
const { t } = useTranslation7(translationKey7);
|
|
2214
|
+
const label = createOptionLabel ? t(createOptionLabel[0], {
|
|
2215
|
+
ns: createOptionLabel[1].ns,
|
|
2216
|
+
text: query
|
|
2217
|
+
}) : t("create-option.label");
|
|
2218
|
+
return /* @__PURE__ */ React13.createElement(Combobox.Item, {
|
|
2219
|
+
value: "__create__",
|
|
2220
|
+
label,
|
|
2221
|
+
icon: createOptionIcon,
|
|
2222
|
+
classNames: "flex items-center gap-2",
|
|
2223
|
+
closeOnSelect: false,
|
|
2224
|
+
onSelect: () => {
|
|
2225
|
+
onCreateItemSelect(query);
|
|
2226
|
+
}
|
|
2227
|
+
});
|
|
2228
|
+
};
|
|
2229
|
+
ObjectPickerContent.displayName = "ObjectPicker.Content";
|
|
1530
2230
|
var ObjectPicker = {
|
|
1531
2231
|
Root: Combobox.Root,
|
|
1532
2232
|
Portal: Combobox.Portal,
|
|
@@ -1540,40 +2240,42 @@ var isRefSnapshot = (val) => {
|
|
|
1540
2240
|
return typeof val === "object" && typeof val?.["/"] === "string";
|
|
1541
2241
|
};
|
|
1542
2242
|
var defaultGetOptions = (results, { parentLabel } = {}) => results.map((result) => {
|
|
1543
|
-
const id = Entity.
|
|
1544
|
-
const parent = parentLabel ?
|
|
2243
|
+
const id = Entity.getURI(result);
|
|
2244
|
+
const parent = parentLabel ? Obj3.getParent(result) : void 0;
|
|
1545
2245
|
const label = parent ? Entity.getLabel(parent) : Entity.getLabel(result);
|
|
1546
2246
|
return {
|
|
1547
2247
|
id,
|
|
1548
2248
|
label: label ?? id
|
|
1549
2249
|
};
|
|
1550
2250
|
});
|
|
1551
|
-
var
|
|
2251
|
+
var defaultUseResults = (db, typename) => useQuery(db, typename ? typename === ANY_OBJECT_TYPENAME ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
|
|
1552
2252
|
var RefField = (props) => {
|
|
1553
|
-
const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, db,
|
|
1554
|
-
const { t } =
|
|
2253
|
+
const { type, readonly, label, jsonPath, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, db, useType: useType2 = defaultUseType2, useResults = defaultUseResults, getOptions = defaultGetOptions, onCreate, onValueChange } = props;
|
|
2254
|
+
const { t } = useTranslation8(translationKey8);
|
|
1555
2255
|
const { status, error } = getStatus();
|
|
1556
|
-
const typename =
|
|
2256
|
+
const typename = useMemo9(() => type ? findAnnotation3(type, ReferenceAnnotationId3)?.typename : void 0, [
|
|
1557
2257
|
type
|
|
1558
2258
|
]);
|
|
1559
2259
|
const results = useResults(db, typename);
|
|
1560
|
-
const options =
|
|
1561
|
-
const parentLabel = type ?
|
|
1562
|
-
return
|
|
2260
|
+
const options = useMemo9(() => {
|
|
2261
|
+
const parentLabel = type ? findAnnotation3(type, ParentLabelAnnotationId) === true : false;
|
|
2262
|
+
return getOptions(results, {
|
|
1563
2263
|
parentLabel
|
|
1564
2264
|
});
|
|
1565
2265
|
}, [
|
|
1566
2266
|
results,
|
|
1567
|
-
|
|
2267
|
+
getOptions,
|
|
1568
2268
|
type
|
|
1569
2269
|
]);
|
|
1570
|
-
const handleGetValue =
|
|
2270
|
+
const handleGetValue = useCallback11(() => {
|
|
1571
2271
|
const formValue = getValue();
|
|
2272
|
+
const dxnToEntityId = (dxn) => dxn.split(/[:/]/).filter(Boolean).pop() ?? dxn;
|
|
1572
2273
|
const unknownToRefOption = (value3) => {
|
|
1573
|
-
const isRef =
|
|
2274
|
+
const isRef = Ref5.isRef(value3);
|
|
1574
2275
|
if (isRef || isRefSnapshot(value3)) {
|
|
1575
|
-
const dxnString = isRef ? value3.
|
|
1576
|
-
const
|
|
2276
|
+
const dxnString = isRef ? value3.uri : value3["/"];
|
|
2277
|
+
const objectId = dxnToEntityId(dxnString);
|
|
2278
|
+
const matchingOption = options.find((option) => dxnToEntityId(option.id) === objectId);
|
|
1577
2279
|
if (matchingOption) {
|
|
1578
2280
|
return matchingOption;
|
|
1579
2281
|
}
|
|
@@ -1585,31 +2287,39 @@ var RefField = (props) => {
|
|
|
1585
2287
|
options,
|
|
1586
2288
|
getValue
|
|
1587
2289
|
]);
|
|
1588
|
-
const handleUpdate = useCallback9((id) => {
|
|
1589
|
-
const item2 = options.find((option) => option.id === id);
|
|
1590
|
-
const ref = item2 ? Ref2.fromDXN(DXN.parse(item2.id)) : void 0;
|
|
1591
|
-
onValueChange(type, ref);
|
|
1592
|
-
}, [
|
|
1593
|
-
options,
|
|
1594
|
-
type,
|
|
1595
|
-
onValueChange
|
|
1596
|
-
]);
|
|
1597
2290
|
const item = handleGetValue();
|
|
1598
|
-
const selectedIds =
|
|
2291
|
+
const selectedIds = useMemo9(() => item ? [
|
|
1599
2292
|
item.id
|
|
1600
2293
|
] : [], [
|
|
1601
2294
|
item
|
|
1602
2295
|
]);
|
|
1603
|
-
const createSchema =
|
|
1604
|
-
const
|
|
1605
|
-
|
|
1606
|
-
|
|
2296
|
+
const createSchema = useType2(db, typename);
|
|
2297
|
+
const [open, setOpen] = useState4(false);
|
|
2298
|
+
const handleCreate = useCallback11(async (values) => {
|
|
2299
|
+
if (!createSchema || !onCreate) {
|
|
2300
|
+
return;
|
|
2301
|
+
}
|
|
2302
|
+
const newObject = await onCreate(createSchema, values);
|
|
2303
|
+
if (newObject) {
|
|
2304
|
+
onValueChange(type, Ref5.make(newObject));
|
|
1607
2305
|
}
|
|
2306
|
+
setOpen(false);
|
|
1608
2307
|
}, [
|
|
1609
2308
|
createSchema,
|
|
1610
|
-
onCreate
|
|
2309
|
+
onCreate,
|
|
2310
|
+
type,
|
|
2311
|
+
onValueChange
|
|
2312
|
+
]);
|
|
2313
|
+
const handleUpdate = useCallback11((id) => {
|
|
2314
|
+
const item2 = options.find((option) => option.id === id);
|
|
2315
|
+
const ref = item2 ? Ref5.fromURI(URI.make(item2.id)) : void 0;
|
|
2316
|
+
onValueChange(type, ref);
|
|
2317
|
+
}, [
|
|
2318
|
+
options,
|
|
2319
|
+
type,
|
|
2320
|
+
onValueChange
|
|
1611
2321
|
]);
|
|
1612
|
-
const handleSelect =
|
|
2322
|
+
const handleSelect = useCallback11((id) => {
|
|
1613
2323
|
if (item?.id === id) {
|
|
1614
2324
|
handleUpdate(void 0);
|
|
1615
2325
|
} else {
|
|
@@ -1622,102 +2332,123 @@ var RefField = (props) => {
|
|
|
1622
2332
|
if (!typename || (readonly || layout === "static") && !item) {
|
|
1623
2333
|
return null;
|
|
1624
2334
|
}
|
|
1625
|
-
return /* @__PURE__ */
|
|
2335
|
+
return /* @__PURE__ */ React14.createElement(Input10.Root, {
|
|
1626
2336
|
validationValence: status
|
|
1627
|
-
}, layout !== "inline" && /* @__PURE__ */
|
|
2337
|
+
}, layout !== "inline" && /* @__PURE__ */ React14.createElement(FormFieldLabel, {
|
|
1628
2338
|
error,
|
|
1629
2339
|
readonly,
|
|
1630
|
-
label
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
2340
|
+
label,
|
|
2341
|
+
path: jsonPath
|
|
2342
|
+
}), /* @__PURE__ */ React14.createElement("div", null, readonly ? !item ? /* @__PURE__ */ React14.createElement("p", {
|
|
2343
|
+
className: "text-description mb-2"
|
|
2344
|
+
}, t("empty-readonly-ref-field.label")) : /* @__PURE__ */ React14.createElement(DxAnchor, {
|
|
1634
2345
|
key: item.id,
|
|
1635
2346
|
dxn: item.id,
|
|
1636
2347
|
rootclassname: "me-1"
|
|
1637
|
-
}, item.label) : /* @__PURE__ */
|
|
2348
|
+
}, item.label) : /* @__PURE__ */ React14.createElement(ObjectPicker.Root, {
|
|
2349
|
+
open,
|
|
2350
|
+
onOpenChange: setOpen
|
|
2351
|
+
}, /* @__PURE__ */ React14.createElement(ObjectPicker.Trigger, {
|
|
1638
2352
|
asChild: true,
|
|
1639
2353
|
classNames: "p-0"
|
|
1640
|
-
}, item ? /* @__PURE__ */
|
|
1641
|
-
className: "flex gap-
|
|
1642
|
-
}, /* @__PURE__ */
|
|
2354
|
+
}, item ? /* @__PURE__ */ React14.createElement("div", {
|
|
2355
|
+
className: "flex gap-form-gap w-full"
|
|
2356
|
+
}, /* @__PURE__ */ React14.createElement(Input10.Root, {
|
|
1643
2357
|
key: item.id
|
|
1644
|
-
}, /* @__PURE__ */
|
|
2358
|
+
}, /* @__PURE__ */ React14.createElement(Input10.TextInput, {
|
|
1645
2359
|
value: item.label,
|
|
1646
2360
|
readOnly: true,
|
|
1647
2361
|
classNames: "w-full"
|
|
1648
|
-
}))) : /* @__PURE__ */
|
|
1649
|
-
classNames: "w-full text-start gap-
|
|
1650
|
-
}, /* @__PURE__ */
|
|
1651
|
-
role: "none",
|
|
2362
|
+
}))) : /* @__PURE__ */ React14.createElement(Button3, {
|
|
2363
|
+
classNames: "w-full text-start gap-form-gap"
|
|
2364
|
+
}, /* @__PURE__ */ React14.createElement("div", {
|
|
1652
2365
|
className: "grow overflow-hidden"
|
|
1653
|
-
}, /* @__PURE__ */
|
|
1654
|
-
className: "
|
|
1655
|
-
}, placeholder
|
|
2366
|
+
}, /* @__PURE__ */ React14.createElement("span", {
|
|
2367
|
+
className: "truncate text-description"
|
|
2368
|
+
}, placeholder || label || t("ref-field.placeholder"))), /* @__PURE__ */ React14.createElement(Icon4, {
|
|
1656
2369
|
size: 3,
|
|
1657
2370
|
icon: "ph--caret-down--bold"
|
|
1658
|
-
}))), /* @__PURE__ */
|
|
2371
|
+
}))), /* @__PURE__ */ React14.createElement(ObjectPicker.Portal, null, /* @__PURE__ */ React14.createElement(ObjectPicker.Content, {
|
|
1659
2372
|
classNames: "dx-card-popover-width",
|
|
1660
2373
|
options,
|
|
1661
2374
|
selectedIds,
|
|
1662
|
-
|
|
2375
|
+
// Strip hidden (`FormInputAnnotation.set(false)`) fields so the
|
|
2376
|
+
// form's validator doesn't reject required-but-hidden fields
|
|
2377
|
+
// such as backing-object refs supplied by a `FactoryAnnotation`.
|
|
2378
|
+
createSchema: createSchema && omitHiddenFormFields(omitId(Type3.getSchema(createSchema))),
|
|
1663
2379
|
createOptionLabel,
|
|
1664
2380
|
createOptionIcon,
|
|
1665
2381
|
createInitialValuePath,
|
|
2382
|
+
createFieldMap: createFieldMap3,
|
|
1666
2383
|
onCreate: handleCreate,
|
|
1667
2384
|
onSelect: handleSelect
|
|
1668
|
-
})))), layout === "full" && /* @__PURE__ */
|
|
2385
|
+
})))), layout === "full" && /* @__PURE__ */ React14.createElement(Input10.DescriptionAndValidation, null, error));
|
|
1669
2386
|
};
|
|
1670
2387
|
|
|
1671
2388
|
// src/components/Form/fields/SelectField.tsx
|
|
1672
|
-
import
|
|
1673
|
-
import { Input as
|
|
1674
|
-
|
|
2389
|
+
import React15, { useCallback as useCallback12 } from "react";
|
|
2390
|
+
import { Icon as Icon5, Input as Input11, Select } from "@dxos/react-ui";
|
|
2391
|
+
import { getStyles } from "@dxos/ui-theme";
|
|
2392
|
+
var SelectField = ({ type, readonly, label, jsonPath, layout, placeholder, options, getStatus, getValue, onValueChange }) => {
|
|
1675
2393
|
const { status, error } = getStatus();
|
|
1676
2394
|
const value3 = getValue();
|
|
1677
|
-
const handleValueChange =
|
|
2395
|
+
const handleValueChange = useCallback12((value4) => onValueChange(type, value4), [
|
|
1678
2396
|
type,
|
|
1679
2397
|
onValueChange
|
|
1680
2398
|
]);
|
|
1681
2399
|
if ((readonly || layout === "static") && value3 == null) {
|
|
1682
2400
|
return null;
|
|
1683
2401
|
}
|
|
1684
|
-
return /* @__PURE__ */
|
|
2402
|
+
return /* @__PURE__ */ React15.createElement(Input11.Root, {
|
|
1685
2403
|
validationValence: status
|
|
1686
|
-
}, layout !== "inline" && /* @__PURE__ */
|
|
2404
|
+
}, layout !== "inline" && /* @__PURE__ */ React15.createElement(FormFieldLabel, {
|
|
1687
2405
|
error,
|
|
1688
2406
|
readonly,
|
|
1689
|
-
label
|
|
1690
|
-
|
|
2407
|
+
label,
|
|
2408
|
+
path: jsonPath
|
|
2409
|
+
}), layout === "static" ? /* @__PURE__ */ React15.createElement("p", null, options?.find(({ value: optionValue }) => optionValue === value3)?.label ?? String(value3)) : /* @__PURE__ */ React15.createElement(Select.Root, {
|
|
1691
2410
|
value: value3,
|
|
1692
2411
|
onValueChange: handleValueChange
|
|
1693
|
-
}, /* @__PURE__ */
|
|
2412
|
+
}, /* @__PURE__ */ React15.createElement(Select.TriggerButton, {
|
|
1694
2413
|
classNames: "w-full",
|
|
1695
2414
|
disabled: !!readonly,
|
|
1696
2415
|
placeholder
|
|
1697
|
-
}), /* @__PURE__ */
|
|
2416
|
+
}), /* @__PURE__ */ React15.createElement(Select.Portal, null, /* @__PURE__ */ React15.createElement(Select.Content, null, /* @__PURE__ */ React15.createElement(Select.Viewport, null, options?.map(({ value: value4, label: label2, secondaryLabel, icon, iconHue }) => (
|
|
1698
2417
|
// NOTE: Numeric values are converted to and from strings.
|
|
1699
|
-
/* @__PURE__ */
|
|
2418
|
+
/* @__PURE__ */ React15.createElement(Select.Option, {
|
|
1700
2419
|
key: String(value4),
|
|
1701
2420
|
value: String(value4)
|
|
1702
|
-
},
|
|
1703
|
-
|
|
2421
|
+
}, /* @__PURE__ */ React15.createElement("span", {
|
|
2422
|
+
className: "flex items-center flex-row gap-2"
|
|
2423
|
+
}, icon && /* @__PURE__ */ React15.createElement(Icon5, {
|
|
2424
|
+
icon,
|
|
2425
|
+
classNames: getIconHueStyles(iconHue)
|
|
2426
|
+
}), label2 ?? String(value4), secondaryLabel && /* @__PURE__ */ React15.createElement("span", {
|
|
2427
|
+
className: "text-subdued text-xs"
|
|
2428
|
+
}, secondaryLabel)))
|
|
2429
|
+
))), /* @__PURE__ */ React15.createElement(Select.Arrow, null)))), layout === "full" && /* @__PURE__ */ React15.createElement(Input11.DescriptionAndValidation, null, error));
|
|
2430
|
+
};
|
|
2431
|
+
var getIconHueStyles = (iconHue) => {
|
|
2432
|
+
const styles = iconHue ? getStyles(iconHue) : void 0;
|
|
2433
|
+
return styles?.fg;
|
|
1704
2434
|
};
|
|
1705
2435
|
|
|
1706
2436
|
// src/components/Form/fields/SelectOptionField.tsx
|
|
1707
|
-
import
|
|
2437
|
+
import React16, { useCallback as useCallback13, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
|
|
1708
2438
|
import { PublicKey } from "@dxos/keys";
|
|
1709
|
-
import { IconButton as IconButton3, Input as
|
|
2439
|
+
import { IconButton as IconButton3, Input as Input12, Tag, useTranslation as useTranslation9 } from "@dxos/react-ui";
|
|
1710
2440
|
import { List } from "@dxos/react-ui-list";
|
|
1711
2441
|
import { HuePicker } from "@dxos/react-ui-pickers";
|
|
1712
|
-
import { hues, osTranslations
|
|
1713
|
-
|
|
1714
|
-
|
|
2442
|
+
import { hues, osTranslations } from "@dxos/ui-theme";
|
|
2443
|
+
import { translationKey as translationKey9 } from "#translations";
|
|
2444
|
+
var SelectOptionField = ({ type, readonly, label, jsonPath, getStatus, getValue, onValueChange }) => {
|
|
2445
|
+
const { t } = useTranslation9(translationKey9);
|
|
1715
2446
|
const { status, error } = getStatus();
|
|
1716
|
-
const [selected, setSelectedId] =
|
|
1717
|
-
const [isNewOption, setIsNewOption] =
|
|
1718
|
-
const inputRef =
|
|
2447
|
+
const [selected, setSelectedId] = useState5(null);
|
|
2448
|
+
const [isNewOption, setIsNewOption] = useState5(false);
|
|
2449
|
+
const inputRef = useRef2(null);
|
|
1719
2450
|
const options = getValue();
|
|
1720
|
-
|
|
2451
|
+
useEffect4(() => {
|
|
1721
2452
|
if (options === void 0) {
|
|
1722
2453
|
onValueChange(type, []);
|
|
1723
2454
|
}
|
|
@@ -1736,7 +2467,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1736
2467
|
const availableHues = hues.filter((hue) => !lastThree.has(hue));
|
|
1737
2468
|
return availableHues[Math.floor(Math.random() * availableHues.length)] ?? hues[Math.floor(Math.random() * hues.length)];
|
|
1738
2469
|
};
|
|
1739
|
-
const handleAdd =
|
|
2470
|
+
const handleAdd = useCallback13(() => {
|
|
1740
2471
|
const newId = PublicKey.random().truncate();
|
|
1741
2472
|
const newOption = {
|
|
1742
2473
|
id: newId,
|
|
@@ -1754,7 +2485,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1754
2485
|
type,
|
|
1755
2486
|
onValueChange
|
|
1756
2487
|
]);
|
|
1757
|
-
const handleDelete =
|
|
2488
|
+
const handleDelete = useCallback13((id) => {
|
|
1758
2489
|
const newOptions = options?.filter((option) => option.id !== id) ?? [];
|
|
1759
2490
|
onValueChange(type, newOptions);
|
|
1760
2491
|
setSelectedId(null);
|
|
@@ -1763,7 +2494,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1763
2494
|
type,
|
|
1764
2495
|
onValueChange
|
|
1765
2496
|
]);
|
|
1766
|
-
const handleMove =
|
|
2497
|
+
const handleMove = useCallback13((from, to) => {
|
|
1767
2498
|
if (!options) {
|
|
1768
2499
|
return;
|
|
1769
2500
|
}
|
|
@@ -1778,10 +2509,10 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1778
2509
|
type,
|
|
1779
2510
|
onValueChange
|
|
1780
2511
|
]);
|
|
1781
|
-
const handleClick =
|
|
2512
|
+
const handleClick = useCallback13((id) => {
|
|
1782
2513
|
setSelectedId((current) => current === id ? null : id);
|
|
1783
2514
|
}, []);
|
|
1784
|
-
const handleTitleChange =
|
|
2515
|
+
const handleTitleChange = useCallback13((id) => (e) => {
|
|
1785
2516
|
const newOptions = options?.map((o) => o.id === id ? {
|
|
1786
2517
|
...o,
|
|
1787
2518
|
title: e.target.value
|
|
@@ -1792,12 +2523,12 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1792
2523
|
type,
|
|
1793
2524
|
onValueChange
|
|
1794
2525
|
]);
|
|
1795
|
-
const handleKeyDown =
|
|
2526
|
+
const handleKeyDown = useCallback13((ev) => {
|
|
1796
2527
|
if (ev.key === "Enter") {
|
|
1797
2528
|
setSelectedId(null);
|
|
1798
2529
|
}
|
|
1799
2530
|
}, []);
|
|
1800
|
-
const handleColorChange =
|
|
2531
|
+
const handleColorChange = useCallback13((id) => (hue) => {
|
|
1801
2532
|
const newOptions = options?.map((o) => o.id === id ? {
|
|
1802
2533
|
...o,
|
|
1803
2534
|
color: hue
|
|
@@ -1808,7 +2539,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1808
2539
|
type,
|
|
1809
2540
|
onValueChange
|
|
1810
2541
|
]);
|
|
1811
|
-
|
|
2542
|
+
useEffect4(() => {
|
|
1812
2543
|
if (selected && isNewOption && inputRef.current) {
|
|
1813
2544
|
inputRef.current.focus();
|
|
1814
2545
|
setIsNewOption(false);
|
|
@@ -1817,77 +2548,73 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1817
2548
|
selected,
|
|
1818
2549
|
isNewOption
|
|
1819
2550
|
]);
|
|
1820
|
-
return /* @__PURE__ */
|
|
2551
|
+
return /* @__PURE__ */ React16.createElement(Input12.Root, {
|
|
1821
2552
|
validationValence: status
|
|
1822
|
-
}, /* @__PURE__ */
|
|
2553
|
+
}, /* @__PURE__ */ React16.createElement(FormFieldLabel, {
|
|
1823
2554
|
error,
|
|
1824
2555
|
readonly,
|
|
1825
|
-
label
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
}, options && /* @__PURE__ */ React13.createElement(List.Root, {
|
|
2556
|
+
label,
|
|
2557
|
+
path: jsonPath
|
|
2558
|
+
}), /* @__PURE__ */ React16.createElement("div", null, options && /* @__PURE__ */ React16.createElement(List.Root, {
|
|
1829
2559
|
items: options,
|
|
1830
2560
|
isItem: (_item) => true,
|
|
1831
2561
|
onMove: readonly ? void 0 : handleMove,
|
|
1832
2562
|
readonly: !!readonly
|
|
1833
|
-
}, ({ items }) => /* @__PURE__ */
|
|
2563
|
+
}, ({ items }) => /* @__PURE__ */ React16.createElement("div", {
|
|
1834
2564
|
role: "list",
|
|
1835
2565
|
className: "w-full overflow-auto"
|
|
1836
|
-
}, items?.map((item) => /* @__PURE__ */
|
|
2566
|
+
}, items?.map((item) => /* @__PURE__ */ React16.createElement("div", {
|
|
1837
2567
|
key: item.id
|
|
1838
|
-
}, /* @__PURE__ */
|
|
2568
|
+
}, /* @__PURE__ */ React16.createElement(List.Item, {
|
|
1839
2569
|
role: "button",
|
|
1840
2570
|
item,
|
|
1841
|
-
classNames:
|
|
1842
|
-
subtleHover,
|
|
1843
|
-
"flex flex-col cursor-pointer rounded-xs"
|
|
1844
|
-
],
|
|
2571
|
+
classNames: "flex flex-col cursor-pointer rounded-xs dx-hover",
|
|
1845
2572
|
"aria-expanded": selected === item.id
|
|
1846
|
-
}, /* @__PURE__ */
|
|
2573
|
+
}, /* @__PURE__ */ React16.createElement("div", {
|
|
1847
2574
|
className: "flex items-center"
|
|
1848
|
-
}, /* @__PURE__ */
|
|
2575
|
+
}, /* @__PURE__ */ React16.createElement(List.ItemDragHandle, {
|
|
1849
2576
|
disabled: !!readonly
|
|
1850
|
-
}), /* @__PURE__ */
|
|
2577
|
+
}), /* @__PURE__ */ React16.createElement(List.ItemTitle, {
|
|
1851
2578
|
onClick: () => handleClick(item.id),
|
|
1852
2579
|
classNames: "flex-1"
|
|
1853
|
-
}, /* @__PURE__ */
|
|
2580
|
+
}, /* @__PURE__ */ React16.createElement(Tag, {
|
|
1854
2581
|
palette: item.color
|
|
1855
|
-
}, item.title || "\u200B")), /* @__PURE__ */
|
|
2582
|
+
}, item.title || "\u200B")), /* @__PURE__ */ React16.createElement(IconButton3, {
|
|
1856
2583
|
iconOnly: true,
|
|
1857
2584
|
variant: "ghost",
|
|
1858
|
-
label: t(selected === item.id ? "collapse
|
|
2585
|
+
label: t(selected === item.id ? "collapse.label" : "expand.label", {
|
|
1859
2586
|
ns: osTranslations
|
|
1860
2587
|
}),
|
|
1861
2588
|
icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
1862
2589
|
onClick: () => handleClick(item.id)
|
|
1863
|
-
})), selected === item.id && /* @__PURE__ */
|
|
1864
|
-
className: "flex flex-col p-form-padding gap-
|
|
1865
|
-
}, /* @__PURE__ */
|
|
1866
|
-
classNames: "text-
|
|
1867
|
-
}, t("select
|
|
1868
|
-
className: "grid grid-cols-[1fr_min-content_min-content] gap-
|
|
1869
|
-
}, /* @__PURE__ */
|
|
2590
|
+
})), selected === item.id && /* @__PURE__ */ React16.createElement("div", {
|
|
2591
|
+
className: "flex flex-col p-form-padding gap-form-gap dx-density-md"
|
|
2592
|
+
}, /* @__PURE__ */ React16.createElement(Input12.Label, {
|
|
2593
|
+
classNames: "text-sm"
|
|
2594
|
+
}, t("select-option.label")), /* @__PURE__ */ React16.createElement("div", {
|
|
2595
|
+
className: "grid grid-cols-[1fr_min-content_min-content] gap-form-gap"
|
|
2596
|
+
}, /* @__PURE__ */ React16.createElement(Input12.TextInput, {
|
|
1870
2597
|
disabled: !!readonly,
|
|
1871
|
-
placeholder: t("select
|
|
2598
|
+
placeholder: t("select-option-label.placeholder"),
|
|
1872
2599
|
ref: selected === item.id ? inputRef : void 0,
|
|
1873
2600
|
value: item.title,
|
|
1874
2601
|
onChange: handleTitleChange(item.id),
|
|
1875
2602
|
onKeyDown: handleKeyDown,
|
|
1876
2603
|
classNames: "flex-1"
|
|
1877
|
-
}), /* @__PURE__ */
|
|
2604
|
+
}), /* @__PURE__ */ React16.createElement(HuePicker, {
|
|
1878
2605
|
disabled: !!readonly,
|
|
1879
2606
|
value: item.color,
|
|
1880
2607
|
onChange: handleColorChange(item.id)
|
|
1881
|
-
}), /* @__PURE__ */
|
|
2608
|
+
}), /* @__PURE__ */ React16.createElement(IconButton3, {
|
|
1882
2609
|
disabled: !!readonly,
|
|
1883
2610
|
icon: "ph--trash--fill",
|
|
1884
2611
|
iconOnly: true,
|
|
1885
|
-
label: t("select
|
|
2612
|
+
label: t("select-option-delete.button"),
|
|
1886
2613
|
onClick: () => handleDelete(item.id)
|
|
1887
|
-
})))))), /* @__PURE__ */
|
|
2614
|
+
})))))), /* @__PURE__ */ React16.createElement(IconButton3, {
|
|
1888
2615
|
variant: "ghost",
|
|
1889
2616
|
icon: "ph--plus--regular",
|
|
1890
|
-
label: t("select
|
|
2617
|
+
label: t("select-option-add.button"),
|
|
1891
2618
|
onClick: handleAdd,
|
|
1892
2619
|
disabled: !!readonly,
|
|
1893
2620
|
classNames: "w-full"
|
|
@@ -1895,39 +2622,39 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1895
2622
|
};
|
|
1896
2623
|
|
|
1897
2624
|
// src/components/Form/fields/TextField.tsx
|
|
1898
|
-
import
|
|
1899
|
-
import { Input as
|
|
1900
|
-
var TextField = ({ type, readonly, placeholder,
|
|
1901
|
-
const handleChange =
|
|
2625
|
+
import React17, { useCallback as useCallback14 } from "react";
|
|
2626
|
+
import { Input as Input13 } from "@dxos/react-ui";
|
|
2627
|
+
var TextField = ({ type, readonly, placeholder, onBlur, onValueChange, ...props }) => {
|
|
2628
|
+
const handleChange = useCallback14((event) => onValueChange(type, event.target.value), [
|
|
1902
2629
|
type,
|
|
1903
2630
|
onValueChange
|
|
1904
2631
|
]);
|
|
1905
|
-
return /* @__PURE__ */
|
|
2632
|
+
return /* @__PURE__ */ React17.createElement(FormFieldWrapper, {
|
|
1906
2633
|
readonly,
|
|
1907
2634
|
...props
|
|
1908
|
-
}, ({ value: value3 = "" }) => /* @__PURE__ */
|
|
2635
|
+
}, ({ value: value3 = "" }) => /* @__PURE__ */ React17.createElement(Input13.TextInput, {
|
|
1909
2636
|
noAutoFill: true,
|
|
1910
2637
|
disabled: !!readonly,
|
|
1911
2638
|
placeholder,
|
|
1912
2639
|
value: value3,
|
|
1913
|
-
|
|
1914
|
-
|
|
2640
|
+
onBlur,
|
|
2641
|
+
onChange: handleChange
|
|
1915
2642
|
}));
|
|
1916
2643
|
};
|
|
1917
2644
|
|
|
1918
2645
|
// src/components/Form/fields/TextAreaField.tsx
|
|
1919
|
-
import
|
|
1920
|
-
import { Input as
|
|
2646
|
+
import React18, { useCallback as useCallback15 } from "react";
|
|
2647
|
+
import { Input as Input14 } from "@dxos/react-ui";
|
|
1921
2648
|
var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props }) => {
|
|
1922
|
-
const handleChange =
|
|
2649
|
+
const handleChange = useCallback15((event) => onValueChange(type, event.target.value), [
|
|
1923
2650
|
type,
|
|
1924
2651
|
onValueChange
|
|
1925
2652
|
]);
|
|
1926
|
-
return /* @__PURE__ */
|
|
2653
|
+
return /* @__PURE__ */ React18.createElement(FormFieldWrapper, {
|
|
1927
2654
|
readonly,
|
|
1928
2655
|
...props
|
|
1929
|
-
}, ({ value: value3 = "" }) => /* @__PURE__ */
|
|
1930
|
-
rows:
|
|
2656
|
+
}, ({ value: value3 = "" }) => /* @__PURE__ */ React18.createElement(Input14.TextArea, {
|
|
2657
|
+
rows: 5,
|
|
1931
2658
|
disabled: !!readonly,
|
|
1932
2659
|
placeholder,
|
|
1933
2660
|
value: value3,
|
|
@@ -1937,8 +2664,8 @@ var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...pr
|
|
|
1937
2664
|
};
|
|
1938
2665
|
|
|
1939
2666
|
// src/components/Form/fields/TupleField.tsx
|
|
1940
|
-
import
|
|
1941
|
-
import { Input as
|
|
2667
|
+
import React19 from "react";
|
|
2668
|
+
import { Input as Input15 } from "@dxos/react-ui";
|
|
1942
2669
|
import { mx as mx4 } from "@dxos/ui-theme";
|
|
1943
2670
|
import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
|
|
1944
2671
|
var gridCols = [
|
|
@@ -1947,18 +2674,19 @@ var gridCols = [
|
|
|
1947
2674
|
"grid-cols-3",
|
|
1948
2675
|
"grid-cols-4"
|
|
1949
2676
|
];
|
|
1950
|
-
var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValueChange, onBlur }) => {
|
|
2677
|
+
var TupleField = ({ binding, type, readonly, label, jsonPath, getStatus, getValue, onValueChange, onBlur }) => {
|
|
1951
2678
|
const { status, error } = getStatus();
|
|
1952
2679
|
const values = getValue() ?? {};
|
|
1953
|
-
return /* @__PURE__ */
|
|
2680
|
+
return /* @__PURE__ */ React19.createElement(Input15.Root, {
|
|
1954
2681
|
validationValence: status
|
|
1955
|
-
}, /* @__PURE__ */
|
|
2682
|
+
}, /* @__PURE__ */ React19.createElement(FormFieldLabel, {
|
|
1956
2683
|
error,
|
|
1957
2684
|
readonly,
|
|
1958
|
-
label
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
2685
|
+
label,
|
|
2686
|
+
path: jsonPath
|
|
2687
|
+
}), /* @__PURE__ */ React19.createElement("div", {
|
|
2688
|
+
className: mx4("grid gap-form-gap", gridCols[binding.length - 1])
|
|
2689
|
+
}, binding.map((prop) => /* @__PURE__ */ React19.createElement(Input15.TextInput, {
|
|
1962
2690
|
key: prop,
|
|
1963
2691
|
type: "number",
|
|
1964
2692
|
disabled: !!readonly,
|
|
@@ -1973,67 +2701,77 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1973
2701
|
}))));
|
|
1974
2702
|
};
|
|
1975
2703
|
|
|
2704
|
+
// src/components/Form/meta-tags.ts
|
|
2705
|
+
import * as Schema4 from "effect/Schema";
|
|
2706
|
+
import { Ref as Ref6, Tag as Tag2 } from "@dxos/echo";
|
|
2707
|
+
var META_TAGS_KEY = "_tags";
|
|
2708
|
+
var withMetaTags = (schema) => omitId(Schema4.Struct({
|
|
2709
|
+
[META_TAGS_KEY]: Schema4.Array(Ref6.Ref(Tag2.Tag)).pipe(Schema4.annotations({
|
|
2710
|
+
title: "Tags"
|
|
2711
|
+
}), Schema4.optional)
|
|
2712
|
+
}).pipe(Schema4.extend(schema)));
|
|
2713
|
+
|
|
1976
2714
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
1977
2715
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
1978
2716
|
var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }) => {
|
|
1979
|
-
const { t } =
|
|
1980
|
-
const [props, setProps] =
|
|
1981
|
-
|
|
2717
|
+
const { t } = useTranslation10(translationKey10);
|
|
2718
|
+
const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
|
|
2719
|
+
useEffect5(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
1982
2720
|
field,
|
|
1983
2721
|
projection
|
|
1984
2722
|
]);
|
|
1985
|
-
const [schemas, setSchemas] =
|
|
2723
|
+
const [schemas, setSchemas] = useState6([]);
|
|
1986
2724
|
useAsyncEffect(async () => {
|
|
1987
2725
|
if (!registry) {
|
|
1988
2726
|
return;
|
|
1989
2727
|
}
|
|
1990
|
-
const subscription = registry.query().subscribe((query) => setSchemas(query.results), {
|
|
2728
|
+
const subscription = registry.query(Filter2.type(Type4.Type)).subscribe((query) => setSchemas(query.results), {
|
|
1991
2729
|
fire: true
|
|
1992
2730
|
});
|
|
1993
|
-
const schemas2 = await registry.query().run();
|
|
2731
|
+
const schemas2 = await registry.query(Filter2.type(Type4.Type)).run();
|
|
1994
2732
|
setSchemas(schemas2);
|
|
1995
2733
|
return () => subscription?.();
|
|
1996
2734
|
}, [
|
|
1997
2735
|
registry
|
|
1998
2736
|
]);
|
|
1999
|
-
const [referenceSchema, setReferenceSchema] =
|
|
2000
|
-
|
|
2001
|
-
setReferenceSchema(schemas.find((schema) => schema
|
|
2737
|
+
const [referenceSchema, setReferenceSchema] = useState6();
|
|
2738
|
+
useEffect5(() => {
|
|
2739
|
+
setReferenceSchema(schemas.find((schema) => Type4.getTypename(schema) === props?.referenceSchema));
|
|
2002
2740
|
}, [
|
|
2003
2741
|
schemas,
|
|
2004
2742
|
props?.referenceSchema
|
|
2005
2743
|
]);
|
|
2006
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
2744
|
+
const [{ fieldSchema }, setFieldSchema] = useState6({
|
|
2007
2745
|
fieldSchema: getFormatSchema(props?.format)
|
|
2008
2746
|
});
|
|
2009
|
-
const fieldMap =
|
|
2010
|
-
["format"]: (props2) => /* @__PURE__ */
|
|
2747
|
+
const fieldMap = useMemo10(() => ({
|
|
2748
|
+
["format"]: (props2) => /* @__PURE__ */ React20.createElement(SelectField, {
|
|
2011
2749
|
...props2,
|
|
2012
|
-
options: FormatEnums.filter((value3) => value3 !==
|
|
2750
|
+
options: FormatEnums.filter((value3) => value3 !== Format6.TypeFormat.None).map((value3) => ({
|
|
2013
2751
|
value: value3,
|
|
2014
|
-
label: t(`format
|
|
2752
|
+
label: t(`format.${value3}.label`)
|
|
2015
2753
|
}))
|
|
2016
2754
|
}),
|
|
2017
|
-
["referenceSchema"]: (props2) => /* @__PURE__ */
|
|
2755
|
+
["referenceSchema"]: (props2) => /* @__PURE__ */ React20.createElement(SelectField, {
|
|
2018
2756
|
...props2,
|
|
2019
|
-
options: schemas.map((schema) => ({
|
|
2020
|
-
value:
|
|
2757
|
+
options: schemas.map((schema) => Type4.getTypename(schema)).filter((typename) => typename != null).map((typename) => ({
|
|
2758
|
+
value: typename
|
|
2021
2759
|
}))
|
|
2022
2760
|
}),
|
|
2023
|
-
["referencePath"]: (props2) => /* @__PURE__ */
|
|
2761
|
+
["referencePath"]: (props2) => /* @__PURE__ */ React20.createElement(SelectField, {
|
|
2024
2762
|
...props2,
|
|
2025
|
-
options: referenceSchema ? getFormProperties(referenceSchema.ast).sort((a, b) => a.name.toString().localeCompare(b.name.toString())).map((p) => ({
|
|
2763
|
+
options: referenceSchema ? getFormProperties(Type4.getSchema(referenceSchema).ast).sort((a, b) => a.name.toString().localeCompare(b.name.toString())).map((p) => ({
|
|
2026
2764
|
value: p.name.toString()
|
|
2027
2765
|
})) : []
|
|
2028
2766
|
}),
|
|
2029
|
-
["options"]: (props2) => /* @__PURE__ */
|
|
2767
|
+
["options"]: (props2) => /* @__PURE__ */ React20.createElement(SelectOptionField, props2)
|
|
2030
2768
|
}), [
|
|
2031
2769
|
t,
|
|
2032
2770
|
schemas,
|
|
2033
2771
|
referenceSchema
|
|
2034
2772
|
]);
|
|
2035
|
-
const propIsNotType =
|
|
2036
|
-
const handleValuesChanged =
|
|
2773
|
+
const propIsNotType = useCallback16((props2) => props2.filter((prop) => prop.name !== "type"), []);
|
|
2774
|
+
const handleValuesChanged = useCallback16((_props) => {
|
|
2037
2775
|
setFieldSchema((prev) => {
|
|
2038
2776
|
const fieldSchema2 = getFormatSchema(_props.format);
|
|
2039
2777
|
if (prev.fieldSchema === fieldSchema2) {
|
|
@@ -2044,8 +2782,8 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2044
2782
|
};
|
|
2045
2783
|
});
|
|
2046
2784
|
setReferenceSchema((prev) => {
|
|
2047
|
-
if (_props.referenceSchema !== prev
|
|
2048
|
-
const newSchema = schemas.find((schema) => schema
|
|
2785
|
+
if (_props.referenceSchema !== (prev ? Type4.getTypename(prev) : void 0)) {
|
|
2786
|
+
const newSchema = schemas.find((schema) => Type4.getTypename(schema) === _props.referenceSchema);
|
|
2049
2787
|
if (newSchema) {
|
|
2050
2788
|
return newSchema;
|
|
2051
2789
|
}
|
|
@@ -2070,7 +2808,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2070
2808
|
props.format,
|
|
2071
2809
|
props.referenceSchema
|
|
2072
2810
|
]);
|
|
2073
|
-
const handleValidate =
|
|
2811
|
+
const handleValidate = useCallback16(({ property }) => {
|
|
2074
2812
|
if (property && projection.getFields().find((f) => f.path === property && f.path !== field.path)) {
|
|
2075
2813
|
return [
|
|
2076
2814
|
{
|
|
@@ -2083,9 +2821,9 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2083
2821
|
projection.getFields(),
|
|
2084
2822
|
field
|
|
2085
2823
|
]);
|
|
2086
|
-
const handleSave =
|
|
2824
|
+
const handleSave = useCallback16((props2) => {
|
|
2087
2825
|
if (view) {
|
|
2088
|
-
|
|
2826
|
+
Obj4.update(view, () => {
|
|
2089
2827
|
projection.setFieldProjection({
|
|
2090
2828
|
field,
|
|
2091
2829
|
props: props2
|
|
@@ -2104,7 +2842,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2104
2842
|
view,
|
|
2105
2843
|
onSave
|
|
2106
2844
|
]);
|
|
2107
|
-
const handleCancel =
|
|
2845
|
+
const handleCancel = useCallback16(() => {
|
|
2108
2846
|
onSave();
|
|
2109
2847
|
requestAnimationFrame(() => onCancel?.());
|
|
2110
2848
|
}, [
|
|
@@ -2113,15 +2851,10 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2113
2851
|
if (!fieldSchema) {
|
|
2114
2852
|
log2.warn("invalid format", {
|
|
2115
2853
|
props
|
|
2116
|
-
}, {
|
|
2117
|
-
F: __dxlog_file2,
|
|
2118
|
-
L: 172,
|
|
2119
|
-
S: void 0,
|
|
2120
|
-
C: (f, a) => f(...a)
|
|
2121
|
-
});
|
|
2854
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 156, S: void 0 });
|
|
2122
2855
|
return null;
|
|
2123
2856
|
}
|
|
2124
|
-
return /* @__PURE__ */
|
|
2857
|
+
return /* @__PURE__ */ React20.createElement(Form.Root, {
|
|
2125
2858
|
key: field.id,
|
|
2126
2859
|
fieldMap,
|
|
2127
2860
|
autoFocus: true,
|
|
@@ -2137,165 +2870,617 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2137
2870
|
onValidate: handleValidate,
|
|
2138
2871
|
onSave: handleSave,
|
|
2139
2872
|
onCancel: handleCancel
|
|
2140
|
-
}, /* @__PURE__ */
|
|
2873
|
+
}, /* @__PURE__ */ React20.createElement(Form.Content, null, /* @__PURE__ */ React20.createElement(Form.FieldSet, null), /* @__PURE__ */ React20.createElement(Form.Actions, null)));
|
|
2141
2874
|
};
|
|
2142
2875
|
|
|
2143
|
-
// src/components/
|
|
2144
|
-
import
|
|
2145
|
-
import {
|
|
2876
|
+
// src/components/ObjectForm/ObjectForm.tsx
|
|
2877
|
+
import React21, { useCallback as useCallback17, useMemo as useMemo11 } from "react";
|
|
2878
|
+
import { Obj as Obj5, Ref as Ref7, Tag as Tag3, Type as Type5 } from "@dxos/echo";
|
|
2879
|
+
import { splitJsonPath as splitJsonPath2 } from "@dxos/echo/internal";
|
|
2880
|
+
import { invariant } from "@dxos/invariant";
|
|
2881
|
+
import { HuePicker as HuePicker2 } from "@dxos/react-ui-pickers";
|
|
2882
|
+
import { translationKey as translationKey11 } from "#translations";
|
|
2883
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectForm/ObjectForm.tsx";
|
|
2884
|
+
var createFieldMap = {
|
|
2885
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
2886
|
+
const handleChange = useCallback17((nextHue) => onValueChange(type, nextHue), [
|
|
2887
|
+
onValueChange,
|
|
2888
|
+
type
|
|
2889
|
+
]);
|
|
2890
|
+
const handleReset = useCallback17(() => onValueChange(type, void 0), [
|
|
2891
|
+
onValueChange,
|
|
2892
|
+
type
|
|
2893
|
+
]);
|
|
2894
|
+
return /* @__PURE__ */ React21.createElement(React21.Fragment, null, layout !== "inline" && /* @__PURE__ */ React21.createElement(Form.Label, {
|
|
2895
|
+
label
|
|
2896
|
+
}), /* @__PURE__ */ React21.createElement(HuePicker2, {
|
|
2897
|
+
value: getValue(),
|
|
2898
|
+
onChange: handleChange,
|
|
2899
|
+
onReset: handleReset
|
|
2900
|
+
}));
|
|
2901
|
+
}
|
|
2902
|
+
};
|
|
2903
|
+
var ObjectForm = ({ object, type }) => {
|
|
2904
|
+
const db = Obj5.getDatabase(object);
|
|
2905
|
+
const meta = Obj5.getMeta(object);
|
|
2906
|
+
const tags = [
|
|
2907
|
+
...meta.tags
|
|
2908
|
+
];
|
|
2909
|
+
const values = useMemo11(() => ({
|
|
2910
|
+
[META_TAGS_KEY]: tags,
|
|
2911
|
+
...object
|
|
2912
|
+
}), [
|
|
2913
|
+
object,
|
|
2914
|
+
tags
|
|
2915
|
+
]);
|
|
2916
|
+
const formSchema = useMemo11(() => withMetaTags(Type5.getSchema(type)), [
|
|
2917
|
+
type
|
|
2918
|
+
]);
|
|
2919
|
+
const handleCreate = useCallback17((type2, values2) => {
|
|
2920
|
+
invariant(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 48, S: void 0, A: ["db", ""] });
|
|
2921
|
+
invariant(Type5.isObject(type2), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 49, S: void 0, A: ["Type.isObject(type)", ""] });
|
|
2922
|
+
const newObject = db.add(Obj5.make(type2, values2));
|
|
2923
|
+
if (Obj5.instanceOf(Tag3.Tag, newObject)) {
|
|
2924
|
+
Obj5.update(object, (object2) => {
|
|
2925
|
+
Obj5.getMeta(object2).tags = [
|
|
2926
|
+
...Obj5.getMeta(object2).tags,
|
|
2927
|
+
Ref7.make(newObject)
|
|
2928
|
+
];
|
|
2929
|
+
});
|
|
2930
|
+
}
|
|
2931
|
+
}, []);
|
|
2932
|
+
const handleChange = useCallback17(({ [META_TAGS_KEY]: metaTags, ...values2 }, { isValid, changed }) => {
|
|
2933
|
+
if (!isValid) {
|
|
2934
|
+
return;
|
|
2935
|
+
}
|
|
2936
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
2937
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath2(path)[0] === META_TAGS_KEY);
|
|
2938
|
+
if (hasTagsChange) {
|
|
2939
|
+
Obj5.update(object, (object2) => {
|
|
2940
|
+
Obj5.getMeta(object2).tags = Array.isArray(metaTags) ? [
|
|
2941
|
+
...metaTags
|
|
2942
|
+
] : [];
|
|
2943
|
+
});
|
|
2944
|
+
}
|
|
2945
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath2(path)[0] !== META_TAGS_KEY);
|
|
2946
|
+
if (nonTagPaths.length > 0) {
|
|
2947
|
+
Obj5.update(object, () => {
|
|
2948
|
+
for (const path of nonTagPaths) {
|
|
2949
|
+
const parts = splitJsonPath2(path);
|
|
2950
|
+
const value3 = Obj5.getValue(values2, parts);
|
|
2951
|
+
Obj5.setValue(object, parts, value3);
|
|
2952
|
+
}
|
|
2953
|
+
});
|
|
2954
|
+
}
|
|
2955
|
+
}, [
|
|
2956
|
+
object
|
|
2957
|
+
]);
|
|
2958
|
+
return /* @__PURE__ */ React21.createElement(Form.Root, {
|
|
2959
|
+
schema: formSchema,
|
|
2960
|
+
defaultValues: values,
|
|
2961
|
+
createTypename: Type5.getTypename(Tag3.Tag),
|
|
2962
|
+
createOptionIcon: "ph--plus--regular",
|
|
2963
|
+
createOptionLabel: [
|
|
2964
|
+
"add-tag.label",
|
|
2965
|
+
{
|
|
2966
|
+
ns: translationKey11
|
|
2967
|
+
}
|
|
2968
|
+
],
|
|
2969
|
+
createInitialValuePath: "label",
|
|
2970
|
+
createFieldMap,
|
|
2971
|
+
db,
|
|
2972
|
+
onValuesChanged: handleChange,
|
|
2973
|
+
onCreate: handleCreate
|
|
2974
|
+
}, /* @__PURE__ */ React21.createElement(Form.Viewport, null, /* @__PURE__ */ React21.createElement(Form.Content, null, /* @__PURE__ */ React21.createElement(Form.FieldSet, null))));
|
|
2975
|
+
};
|
|
2976
|
+
|
|
2977
|
+
// src/components/ObjectProperties/ObjectProperties.tsx
|
|
2978
|
+
import * as Function from "effect/Function";
|
|
2979
|
+
import * as Option7 from "effect/Option";
|
|
2980
|
+
import React22, { useCallback as useCallback18, useMemo as useMemo12 } from "react";
|
|
2981
|
+
import { Obj as Obj6, Tag as Tag4, Type as Type6 } from "@dxos/echo";
|
|
2982
|
+
import { useType } from "@dxos/echo-react";
|
|
2983
|
+
import { splitJsonPath as splitJsonPath3 } from "@dxos/echo/internal";
|
|
2984
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2985
|
+
import { composable as composable2, composableProps as composableProps2 } from "@dxos/react-ui";
|
|
2986
|
+
import { HuePicker as HuePicker3 } from "@dxos/react-ui-pickers";
|
|
2987
|
+
import { FactoryAnnotation } from "@dxos/schema";
|
|
2988
|
+
import { translationKey as translationKey12 } from "#translations";
|
|
2989
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectProperties/ObjectProperties.tsx";
|
|
2990
|
+
var ObjectProperties = composable2(({ children, object, ...props }, forwardedRef) => {
|
|
2991
|
+
const db = Obj6.getDatabase(object);
|
|
2992
|
+
const meta = Obj6.getMeta(object);
|
|
2993
|
+
const tags = [
|
|
2994
|
+
...meta.tags
|
|
2995
|
+
];
|
|
2996
|
+
const values = useMemo12(() => ({
|
|
2997
|
+
[META_TAGS_KEY]: tags,
|
|
2998
|
+
...object
|
|
2999
|
+
}), [
|
|
3000
|
+
object,
|
|
3001
|
+
tags
|
|
3002
|
+
]);
|
|
3003
|
+
const typename = Obj6.getTypename(object) ?? void 0;
|
|
3004
|
+
const typeFromRegistry = useType(db, typename);
|
|
3005
|
+
const type = Obj6.getType(object) ?? typeFromRegistry;
|
|
3006
|
+
const formSchema = useMemo12(() => {
|
|
3007
|
+
return Function.pipe(type, Option7.fromNullable, Option7.map((type2) => Type6.getSchema(type2)), Option7.map((schema) => withMetaTags(schema)), Option7.getOrUndefined);
|
|
3008
|
+
}, [
|
|
3009
|
+
type
|
|
3010
|
+
]);
|
|
3011
|
+
const handleCreate = useCallback18((type2, values2) => {
|
|
3012
|
+
invariant2(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 52, S: void 0, A: ["db", ""] });
|
|
3013
|
+
invariant2(Type6.isObject(type2), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 53, S: void 0, A: ["Type.isObject(type)", ""] });
|
|
3014
|
+
const factory = Option7.getOrUndefined(FactoryAnnotation.get(Type6.getSchema(type2)));
|
|
3015
|
+
const newObject = factory ? factory(values2) : Obj6.make(type2, values2);
|
|
3016
|
+
return db.add(newObject);
|
|
3017
|
+
}, [
|
|
3018
|
+
db
|
|
3019
|
+
]);
|
|
3020
|
+
const handleChange = useCallback18(({ [META_TAGS_KEY]: metaTags, ...values2 }, { isValid, changed }) => {
|
|
3021
|
+
if (!isValid) {
|
|
3022
|
+
return;
|
|
3023
|
+
}
|
|
3024
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
3025
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath3(path)[0] === META_TAGS_KEY);
|
|
3026
|
+
if (hasTagsChange) {
|
|
3027
|
+
Obj6.update(object, (object2) => {
|
|
3028
|
+
Obj6.getMeta(object2).tags = Array.isArray(metaTags) ? [
|
|
3029
|
+
...metaTags
|
|
3030
|
+
] : [];
|
|
3031
|
+
});
|
|
3032
|
+
}
|
|
3033
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath3(path)[0] !== META_TAGS_KEY);
|
|
3034
|
+
if (nonTagPaths.length > 0) {
|
|
3035
|
+
Obj6.update(object, () => {
|
|
3036
|
+
for (const path of nonTagPaths) {
|
|
3037
|
+
const parts = splitJsonPath3(path);
|
|
3038
|
+
const value3 = Obj6.getValue(values2, parts);
|
|
3039
|
+
Obj6.setValue(object, parts, value3);
|
|
3040
|
+
}
|
|
3041
|
+
});
|
|
3042
|
+
}
|
|
3043
|
+
}, [
|
|
3044
|
+
object
|
|
3045
|
+
]);
|
|
3046
|
+
if (!formSchema) {
|
|
3047
|
+
return null;
|
|
3048
|
+
}
|
|
3049
|
+
return /* @__PURE__ */ React22.createElement(Form.Root, {
|
|
3050
|
+
schema: formSchema,
|
|
3051
|
+
defaultValues: values,
|
|
3052
|
+
createTypename: Type6.getTypename(Tag4.Tag),
|
|
3053
|
+
createOptionIcon: "ph--plus--regular",
|
|
3054
|
+
createOptionLabel: [
|
|
3055
|
+
"add-tag.label",
|
|
3056
|
+
{
|
|
3057
|
+
ns: translationKey12
|
|
3058
|
+
}
|
|
3059
|
+
],
|
|
3060
|
+
createInitialValuePath: "label",
|
|
3061
|
+
createFieldMap: createFieldMap2,
|
|
3062
|
+
db,
|
|
3063
|
+
onValuesChanged: handleChange,
|
|
3064
|
+
onCreate: handleCreate
|
|
3065
|
+
}, /* @__PURE__ */ React22.createElement(Form.Viewport, {
|
|
3066
|
+
...composableProps2(props),
|
|
3067
|
+
ref: forwardedRef
|
|
3068
|
+
}, /* @__PURE__ */ React22.createElement(Form.Content, null, /* @__PURE__ */ React22.createElement(Form.FieldSet, null), children)));
|
|
3069
|
+
});
|
|
3070
|
+
var createFieldMap2 = {
|
|
3071
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
3072
|
+
const handleChange = useCallback18((nextHue) => onValueChange(type, nextHue), [
|
|
3073
|
+
onValueChange,
|
|
3074
|
+
type
|
|
3075
|
+
]);
|
|
3076
|
+
const handleReset = useCallback18(() => onValueChange(type, void 0), [
|
|
3077
|
+
onValueChange,
|
|
3078
|
+
type
|
|
3079
|
+
]);
|
|
3080
|
+
return /* @__PURE__ */ React22.createElement(React22.Fragment, null, layout !== "inline" && /* @__PURE__ */ React22.createElement(Form.Label, {
|
|
3081
|
+
label
|
|
3082
|
+
}), /* @__PURE__ */ React22.createElement(HuePicker3, {
|
|
3083
|
+
value: getValue(),
|
|
3084
|
+
onChange: handleChange,
|
|
3085
|
+
onReset: handleReset
|
|
3086
|
+
}));
|
|
3087
|
+
}
|
|
3088
|
+
};
|
|
3089
|
+
|
|
3090
|
+
// src/components/ObjectTree/ObjectTree.tsx
|
|
3091
|
+
import * as SchemaAST7 from "effect/SchemaAST";
|
|
3092
|
+
import React23 from "react";
|
|
3093
|
+
import { composable as composable3, composableProps as composableProps3 } from "@dxos/react-ui";
|
|
2146
3094
|
import { mx as mx5 } from "@dxos/ui-theme";
|
|
2147
|
-
var
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
3095
|
+
var ObjectTreeImpl = composable3(({ schema, value: value3, ...props }, forwardedRef) => /* @__PURE__ */ React23.createElement("div", {
|
|
3096
|
+
...composableProps3(props, {
|
|
3097
|
+
role: "table",
|
|
3098
|
+
classNames: "font-mono text-sm w-full"
|
|
3099
|
+
}),
|
|
3100
|
+
ref: forwardedRef
|
|
3101
|
+
}, /* @__PURE__ */ React23.createElement(Node, {
|
|
3102
|
+
ast: schema.ast,
|
|
3103
|
+
value: value3,
|
|
3104
|
+
label: null,
|
|
3105
|
+
depth: 0
|
|
3106
|
+
})));
|
|
3107
|
+
ObjectTreeImpl.displayName = "ObjectTree";
|
|
3108
|
+
var ObjectTree = ObjectTreeImpl;
|
|
3109
|
+
var unwrap = (ast) => {
|
|
3110
|
+
if (SchemaAST7.isRefinement(ast)) {
|
|
3111
|
+
return unwrap(ast.from);
|
|
3112
|
+
}
|
|
3113
|
+
if (SchemaAST7.isSuspend(ast)) {
|
|
3114
|
+
return unwrap(ast.f());
|
|
3115
|
+
}
|
|
3116
|
+
if (SchemaAST7.isTransformation(ast)) {
|
|
3117
|
+
return unwrap(ast.from);
|
|
3118
|
+
}
|
|
3119
|
+
return ast;
|
|
2169
3120
|
};
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
className: "w-full pt-trim-md space-y-trim-md"
|
|
2177
|
-
}, children));
|
|
3121
|
+
var stripOptional = (ast) => {
|
|
3122
|
+
if (!SchemaAST7.isUnion(ast)) {
|
|
3123
|
+
return ast;
|
|
3124
|
+
}
|
|
3125
|
+
const nonUndef = ast.types.filter((t) => !SchemaAST7.isUndefinedKeyword(t));
|
|
3126
|
+
return nonUndef.length === 1 ? nonUndef[0] : ast;
|
|
2178
3127
|
};
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
3128
|
+
var Node = ({ ast, value: value3, label, depth }) => {
|
|
3129
|
+
const inner = unwrap(stripOptional(ast));
|
|
3130
|
+
if (SchemaAST7.isTypeLiteral(inner) && isPlainObject(value3)) {
|
|
3131
|
+
const childDepth = label === null ? depth : depth + 1;
|
|
3132
|
+
return /* @__PURE__ */ React23.createElement(React23.Fragment, null, label !== null && /* @__PURE__ */ React23.createElement(Row, {
|
|
3133
|
+
label,
|
|
3134
|
+
value: null,
|
|
3135
|
+
depth,
|
|
3136
|
+
kind: "group"
|
|
3137
|
+
}), inner.propertySignatures.map((prop) => /* @__PURE__ */ React23.createElement(Node, {
|
|
3138
|
+
key: String(prop.name),
|
|
3139
|
+
ast: prop.type,
|
|
3140
|
+
value: value3[String(prop.name)],
|
|
3141
|
+
label: String(prop.name),
|
|
3142
|
+
depth: childDepth
|
|
3143
|
+
})));
|
|
3144
|
+
}
|
|
3145
|
+
if (SchemaAST7.isTupleType(inner) && Array.isArray(value3)) {
|
|
3146
|
+
const elemType = inner.rest[0]?.type;
|
|
3147
|
+
return /* @__PURE__ */ React23.createElement(React23.Fragment, null, label !== null && /* @__PURE__ */ React23.createElement(Row, {
|
|
3148
|
+
label,
|
|
3149
|
+
value: `Array(${value3.length})`,
|
|
3150
|
+
depth,
|
|
3151
|
+
kind: "group"
|
|
3152
|
+
}), value3.map((item, index) => /* @__PURE__ */ React23.createElement(Node, {
|
|
3153
|
+
key: index,
|
|
3154
|
+
ast: elemType ?? SchemaAST7.unknownKeyword,
|
|
3155
|
+
value: item,
|
|
3156
|
+
label: `[${index}]`,
|
|
3157
|
+
depth: depth + 1
|
|
3158
|
+
})));
|
|
3159
|
+
}
|
|
3160
|
+
return /* @__PURE__ */ React23.createElement(Row, {
|
|
3161
|
+
label: label ?? "",
|
|
3162
|
+
value: formatLeaf(value3),
|
|
3163
|
+
depth,
|
|
3164
|
+
kind: "leaf"
|
|
2196
3165
|
});
|
|
2197
3166
|
};
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
role: "
|
|
2206
|
-
className: "
|
|
2207
|
-
},
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
};
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
3167
|
+
var Row = ({ label, value: value3, depth }) => /* @__PURE__ */ React23.createElement("div", {
|
|
3168
|
+
role: "row",
|
|
3169
|
+
className: mx5("flex items-baseline gap-3 py-1"),
|
|
3170
|
+
style: {
|
|
3171
|
+
paddingInlineStart: 8 + depth * 16
|
|
3172
|
+
}
|
|
3173
|
+
}, /* @__PURE__ */ React23.createElement("div", {
|
|
3174
|
+
role: "cell",
|
|
3175
|
+
className: "text-subdued"
|
|
3176
|
+
}, label), /* @__PURE__ */ React23.createElement("div", {
|
|
3177
|
+
role: "cell",
|
|
3178
|
+
className: mx5("break-all text-base-fg")
|
|
3179
|
+
}, value3));
|
|
3180
|
+
var isPlainObject = (value3) => typeof value3 === "object" && value3 !== null && !Array.isArray(value3);
|
|
3181
|
+
var formatLeaf = (value3) => {
|
|
3182
|
+
if (value3 === void 0) {
|
|
3183
|
+
return null;
|
|
3184
|
+
}
|
|
3185
|
+
if (value3 === null) {
|
|
3186
|
+
return /* @__PURE__ */ React23.createElement("span", {
|
|
3187
|
+
className: "text-description"
|
|
3188
|
+
}, "null");
|
|
3189
|
+
}
|
|
3190
|
+
switch (typeof value3) {
|
|
3191
|
+
case "string":
|
|
3192
|
+
return /* @__PURE__ */ React23.createElement("span", {
|
|
3193
|
+
className: "text-blue-text"
|
|
3194
|
+
}, JSON.stringify(value3));
|
|
3195
|
+
case "number":
|
|
3196
|
+
case "bigint":
|
|
3197
|
+
return /* @__PURE__ */ React23.createElement("span", {
|
|
3198
|
+
className: "text-green-text"
|
|
3199
|
+
}, String(value3));
|
|
3200
|
+
case "boolean":
|
|
3201
|
+
return /* @__PURE__ */ React23.createElement("span", {
|
|
3202
|
+
className: "text-purple-text"
|
|
3203
|
+
}, String(value3));
|
|
3204
|
+
default:
|
|
3205
|
+
try {
|
|
3206
|
+
return JSON.stringify(value3);
|
|
3207
|
+
} catch {
|
|
3208
|
+
return String(value3);
|
|
3209
|
+
}
|
|
3210
|
+
}
|
|
3211
|
+
};
|
|
3212
|
+
|
|
3213
|
+
// src/components/Settings/Settings.tsx
|
|
3214
|
+
import React26 from "react";
|
|
3215
|
+
import { ScrollArea as ScrollArea2, toLocalizedString as toLocalizedString2, useTranslation as useTranslation12 } from "@dxos/react-ui";
|
|
3216
|
+
import { composable as composable4, composableProps as composableProps4 } from "@dxos/react-ui";
|
|
3217
|
+
import { mx as mx7 } from "@dxos/ui-theme";
|
|
3218
|
+
import { translationKey as translationKey14 } from "#translations";
|
|
3219
|
+
|
|
3220
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
3221
|
+
import * as SchemaAST8 from "effect/SchemaAST";
|
|
3222
|
+
import * as String4 from "effect/String";
|
|
3223
|
+
import React25, { useCallback as useCallback19, useMemo as useMemo13 } from "react";
|
|
3224
|
+
import { getAnnotation as getAnnotation4 } from "@dxos/effect";
|
|
3225
|
+
import { Input as Input17, Select as Select2 } from "@dxos/react-ui";
|
|
3226
|
+
|
|
3227
|
+
// src/components/Settings/SettingsItem.tsx
|
|
3228
|
+
import React24 from "react";
|
|
3229
|
+
import { Input as Input16, toLocalizedString, useTranslation as useTranslation11 } from "@dxos/react-ui";
|
|
3230
|
+
import { mx as mx6 } from "@dxos/ui-theme";
|
|
3231
|
+
import { translationKey as translationKey13 } from "#translations";
|
|
3232
|
+
var SETTINGS_PANEL_NAME = "Settings.Panel";
|
|
3233
|
+
var SETTINGS_ITEM_NAME = "Settings.Item";
|
|
3234
|
+
var SettingsPanel = ({ classNames, children }) => {
|
|
3235
|
+
return /* @__PURE__ */ React24.createElement("div", {
|
|
3236
|
+
className: mx6("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
|
|
2230
3237
|
}, children);
|
|
2231
3238
|
};
|
|
2232
|
-
|
|
3239
|
+
SettingsPanel.displayName = SETTINGS_PANEL_NAME;
|
|
2233
3240
|
var SettingsItem = ({ title, description = "", children }) => {
|
|
2234
|
-
const { t } =
|
|
2235
|
-
return /* @__PURE__ */
|
|
2236
|
-
classNames:
|
|
2237
|
-
}, /* @__PURE__ */
|
|
2238
|
-
|
|
2239
|
-
}, toLocalizedString(title, t)), /* @__PURE__ */
|
|
2240
|
-
|
|
2241
|
-
}, toLocalizedString(description, t)), /* @__PURE__ */
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
}, children));
|
|
3241
|
+
const { t } = useTranslation11(translationKey13);
|
|
3242
|
+
return /* @__PURE__ */ React24.createElement(Input16.Root, null, /* @__PURE__ */ React24.createElement(SettingsPanel, {
|
|
3243
|
+
classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
|
|
3244
|
+
}, /* @__PURE__ */ React24.createElement(Input16.Label, {
|
|
3245
|
+
classNames: "pb-trim-md text-base-fg text-lg md:col-span-2"
|
|
3246
|
+
}, toLocalizedString(title, t)), /* @__PURE__ */ React24.createElement(Input16.DescriptionAndValidation, null, /* @__PURE__ */ React24.createElement(Input16.Description, {
|
|
3247
|
+
classNames: "text-base text-description"
|
|
3248
|
+
}, toLocalizedString(description, t))), /* @__PURE__ */ React24.createElement("div", {
|
|
3249
|
+
className: "text-end py-1"
|
|
3250
|
+
}, children)));
|
|
2245
3251
|
};
|
|
2246
3252
|
SettingsItem.displayName = SETTINGS_ITEM_NAME;
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
3253
|
+
|
|
3254
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
3255
|
+
var SettingsFieldSet = ({ schema, values, onValuesChanged, readonly, fieldMap, visible, sort, pathPrefix = "" }) => {
|
|
3256
|
+
const properties = useMemo13(() => {
|
|
3257
|
+
const props = getFormProperties(schema.ast);
|
|
3258
|
+
if (!sort) {
|
|
3259
|
+
return props;
|
|
3260
|
+
}
|
|
3261
|
+
const rank = (name) => {
|
|
3262
|
+
const idx = sort.indexOf(name);
|
|
3263
|
+
return idx === -1 ? Number.POSITIVE_INFINITY : idx;
|
|
3264
|
+
};
|
|
3265
|
+
return [
|
|
3266
|
+
...props
|
|
3267
|
+
].sort(({ name: a }, { name: b }) => rank(a.toString()) - rank(b.toString()));
|
|
3268
|
+
}, [
|
|
3269
|
+
schema,
|
|
3270
|
+
sort
|
|
3271
|
+
]);
|
|
3272
|
+
const handleChange = useCallback19((name, value3) => {
|
|
3273
|
+
onValuesChanged?.({
|
|
3274
|
+
...values,
|
|
3275
|
+
[name]: value3
|
|
3276
|
+
});
|
|
3277
|
+
}, [
|
|
3278
|
+
values,
|
|
3279
|
+
onValuesChanged
|
|
3280
|
+
]);
|
|
3281
|
+
return /* @__PURE__ */ React25.createElement(React25.Fragment, null, properties.map((property) => {
|
|
3282
|
+
const name = property.name.toString();
|
|
3283
|
+
const path = pathPrefix ? `${pathPrefix}.${name}` : name;
|
|
3284
|
+
if (visible && !visible(path, values)) {
|
|
3285
|
+
return null;
|
|
3286
|
+
}
|
|
3287
|
+
const entry = fieldMap?.[name];
|
|
3288
|
+
return /* @__PURE__ */ React25.createElement(SettingsFieldItem, {
|
|
3289
|
+
key: name,
|
|
3290
|
+
path,
|
|
3291
|
+
property,
|
|
3292
|
+
value: values[name],
|
|
3293
|
+
onChange: (value3) => handleChange(name, value3),
|
|
3294
|
+
readonly,
|
|
3295
|
+
customField: typeof entry === "function" ? entry : void 0,
|
|
3296
|
+
nestedFieldMap: typeof entry === "object" ? entry : void 0,
|
|
3297
|
+
visible,
|
|
3298
|
+
sort
|
|
3299
|
+
});
|
|
3300
|
+
}));
|
|
3301
|
+
};
|
|
3302
|
+
SettingsFieldSet.displayName = "Settings.FieldSet";
|
|
3303
|
+
var SettingsFieldItem = ({ property, path, value: value3, onChange, readonly, customField, nestedFieldMap, visible, sort }) => {
|
|
3304
|
+
const { type } = property;
|
|
3305
|
+
const name = property.name.toString();
|
|
3306
|
+
const title = getAnnotation4(SchemaAST8.TitleAnnotationId)(type) ?? String4.capitalize(name);
|
|
3307
|
+
const description = getAnnotation4(SchemaAST8.DescriptionAnnotationId)(type);
|
|
3308
|
+
if (customField) {
|
|
3309
|
+
const CustomField = customField;
|
|
3310
|
+
return /* @__PURE__ */ React25.createElement(SettingsItem, {
|
|
3311
|
+
title,
|
|
3312
|
+
description
|
|
3313
|
+
}, /* @__PURE__ */ React25.createElement(CustomField, {
|
|
3314
|
+
value: value3,
|
|
3315
|
+
onChange,
|
|
3316
|
+
readonly
|
|
3317
|
+
}));
|
|
3318
|
+
}
|
|
3319
|
+
const fieldType = detectFieldType(type);
|
|
3320
|
+
switch (fieldType) {
|
|
3321
|
+
case "struct":
|
|
3322
|
+
return /* @__PURE__ */ React25.createElement(SettingsFieldSet, {
|
|
3323
|
+
schema: {
|
|
3324
|
+
ast: type
|
|
3325
|
+
},
|
|
3326
|
+
values: value3 ?? {},
|
|
3327
|
+
onValuesChanged: onChange,
|
|
3328
|
+
readonly,
|
|
3329
|
+
fieldMap: nestedFieldMap,
|
|
3330
|
+
visible,
|
|
3331
|
+
sort,
|
|
3332
|
+
pathPrefix: path
|
|
3333
|
+
});
|
|
3334
|
+
case "boolean":
|
|
3335
|
+
return /* @__PURE__ */ React25.createElement(SettingsItem, {
|
|
3336
|
+
title,
|
|
3337
|
+
description
|
|
3338
|
+
}, /* @__PURE__ */ React25.createElement(Input17.Switch, {
|
|
3339
|
+
disabled: readonly,
|
|
3340
|
+
checked: !!value3,
|
|
3341
|
+
onCheckedChange: (checked) => onChange(!!checked)
|
|
3342
|
+
}));
|
|
3343
|
+
case "select": {
|
|
3344
|
+
const options = getSelectOptionsFromAst(type) ?? [];
|
|
3345
|
+
return /* @__PURE__ */ React25.createElement(SettingsItem, {
|
|
3346
|
+
title,
|
|
3347
|
+
description
|
|
3348
|
+
}, /* @__PURE__ */ React25.createElement(Select2.Root, {
|
|
3349
|
+
disabled: readonly,
|
|
3350
|
+
value: value3 == null ? "" : globalThis.String(value3),
|
|
3351
|
+
onValueChange: (selected) => {
|
|
3352
|
+
const matched = options.find((option) => globalThis.String(option.value) === selected);
|
|
3353
|
+
onChange(matched?.value ?? selected);
|
|
3354
|
+
}
|
|
3355
|
+
}, /* @__PURE__ */ React25.createElement(Select2.TriggerButton, {
|
|
3356
|
+
disabled: readonly
|
|
3357
|
+
}), /* @__PURE__ */ React25.createElement(Select2.Portal, null, /* @__PURE__ */ React25.createElement(Select2.Content, null, /* @__PURE__ */ React25.createElement(Select2.Viewport, null, options.map((option) => /* @__PURE__ */ React25.createElement(Select2.Option, {
|
|
3358
|
+
key: globalThis.String(option.value),
|
|
3359
|
+
value: globalThis.String(option.value)
|
|
3360
|
+
}, option.label ?? globalThis.String(option.value)))), /* @__PURE__ */ React25.createElement(Select2.Arrow, null)))));
|
|
3361
|
+
}
|
|
3362
|
+
case "string":
|
|
3363
|
+
return /* @__PURE__ */ React25.createElement(SettingsItem, {
|
|
3364
|
+
title,
|
|
3365
|
+
description
|
|
3366
|
+
}, /* @__PURE__ */ React25.createElement(Input17.TextInput, {
|
|
3367
|
+
disabled: readonly,
|
|
3368
|
+
value: value3 ?? "",
|
|
3369
|
+
onChange: (event) => onChange(event.target.value)
|
|
3370
|
+
}));
|
|
3371
|
+
case "number":
|
|
3372
|
+
return /* @__PURE__ */ React25.createElement(SettingsItem, {
|
|
3373
|
+
title,
|
|
3374
|
+
description
|
|
3375
|
+
}, /* @__PURE__ */ React25.createElement(Input17.TextInput, {
|
|
3376
|
+
disabled: readonly,
|
|
3377
|
+
type: "number",
|
|
3378
|
+
value: value3 ?? "",
|
|
3379
|
+
onChange: (event) => {
|
|
3380
|
+
if (event.target.value === "") {
|
|
3381
|
+
onChange(void 0);
|
|
3382
|
+
return;
|
|
3383
|
+
}
|
|
3384
|
+
const parsed = Number(event.target.value);
|
|
3385
|
+
onChange(Number.isNaN(parsed) ? void 0 : parsed);
|
|
3386
|
+
}
|
|
3387
|
+
}));
|
|
3388
|
+
default:
|
|
3389
|
+
return null;
|
|
3390
|
+
}
|
|
3391
|
+
};
|
|
3392
|
+
|
|
3393
|
+
// src/components/Settings/Settings.tsx
|
|
3394
|
+
var SETTINGS_ROOT_NAME = "Settings.Root";
|
|
3395
|
+
var SETTINGS_VIEWPORT_NAME = "Settings.Viewport";
|
|
3396
|
+
var SETTINGS_SECTION_NAME = "Settings.Section";
|
|
3397
|
+
var SettingsRoot = ({ children, classNames }) => {
|
|
3398
|
+
return /* @__PURE__ */ React26.createElement("div", {
|
|
3399
|
+
className: mx7("flex flex-col gap-2", classNames)
|
|
3400
|
+
}, children);
|
|
3401
|
+
};
|
|
3402
|
+
SettingsRoot.displayName = SETTINGS_ROOT_NAME;
|
|
3403
|
+
var SettingsViewport = composable4(({ children, ...props }, forwardedRef) => {
|
|
3404
|
+
return /* @__PURE__ */ React26.createElement(ScrollArea2.Root, {
|
|
3405
|
+
...composableProps4(props),
|
|
3406
|
+
orientation: "vertical",
|
|
3407
|
+
centered: true,
|
|
3408
|
+
thin: true,
|
|
3409
|
+
ref: forwardedRef
|
|
3410
|
+
}, /* @__PURE__ */ React26.createElement(ScrollArea2.Viewport, {
|
|
3411
|
+
classNames: "px-4 pointer-coarse:px-2"
|
|
3412
|
+
}, /* @__PURE__ */ React26.createElement("div", {
|
|
3413
|
+
className: "dx-document flex flex-col gap-2 py-4"
|
|
2258
3414
|
}, children)));
|
|
3415
|
+
});
|
|
3416
|
+
SettingsViewport.displayName = SETTINGS_VIEWPORT_NAME;
|
|
3417
|
+
var SettingsSection = ({ title, description, children }) => {
|
|
3418
|
+
const { t } = useTranslation12(translationKey14);
|
|
3419
|
+
return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement("h2", {
|
|
3420
|
+
className: "px-trim-md mt-trim-md text-xl"
|
|
3421
|
+
}, toLocalizedString2(title, t)), description && /* @__PURE__ */ React26.createElement("p", {
|
|
3422
|
+
className: "px-trim-md text-description"
|
|
3423
|
+
}, toLocalizedString2(description, t)), /* @__PURE__ */ React26.createElement("div", {
|
|
3424
|
+
className: "w-full pt-trim-md space-y-trim-md"
|
|
3425
|
+
}, children));
|
|
2259
3426
|
};
|
|
2260
|
-
|
|
3427
|
+
SettingsSection.displayName = SETTINGS_SECTION_NAME;
|
|
2261
3428
|
var Settings = {
|
|
2262
3429
|
Root: SettingsRoot,
|
|
3430
|
+
Viewport: SettingsViewport,
|
|
2263
3431
|
Section: SettingsSection,
|
|
2264
|
-
|
|
2265
|
-
Group: SettingsGroup,
|
|
2266
|
-
GroupButton: SettingsGroupButton,
|
|
2267
|
-
Container: SettingsContainer,
|
|
2268
|
-
Frame: SettingsFrame,
|
|
2269
|
-
FrameItem: SettingsFrameItem,
|
|
3432
|
+
Panel: SettingsPanel,
|
|
2270
3433
|
Item: SettingsItem,
|
|
2271
|
-
|
|
3434
|
+
FieldSet: SettingsFieldSet
|
|
3435
|
+
};
|
|
3436
|
+
|
|
3437
|
+
// src/components/Settings/SettingsSelectField.tsx
|
|
3438
|
+
import React27 from "react";
|
|
3439
|
+
import { Select as Select3 } from "@dxos/react-ui";
|
|
3440
|
+
var createSelectField = ({ options, defaultLabel = "Default" }) => {
|
|
3441
|
+
const normalized = options.map((option) => typeof option === "string" ? {
|
|
3442
|
+
value: option,
|
|
3443
|
+
label: option
|
|
3444
|
+
} : option);
|
|
3445
|
+
const hasDefault = defaultLabel !== null;
|
|
3446
|
+
const sentinel = hasDefault ? `__default__${Math.random().toString(36).slice(2)}` : "";
|
|
3447
|
+
return ({ value: value3, onChange, readonly }) => /* @__PURE__ */ React27.createElement(Select3.Root, {
|
|
3448
|
+
disabled: readonly,
|
|
3449
|
+
value: value3 ?? sentinel,
|
|
3450
|
+
onValueChange: (next) => onChange(hasDefault && next === sentinel ? void 0 : next)
|
|
3451
|
+
}, /* @__PURE__ */ React27.createElement(Select3.TriggerButton, {
|
|
3452
|
+
disabled: readonly
|
|
3453
|
+
}), /* @__PURE__ */ React27.createElement(Select3.Portal, null, /* @__PURE__ */ React27.createElement(Select3.Content, null, /* @__PURE__ */ React27.createElement(Select3.Viewport, null, hasDefault && /* @__PURE__ */ React27.createElement(Select3.Option, {
|
|
3454
|
+
value: sentinel
|
|
3455
|
+
}, defaultLabel), normalized.map((option) => /* @__PURE__ */ React27.createElement(Select3.Option, {
|
|
3456
|
+
key: option.value,
|
|
3457
|
+
value: option.value
|
|
3458
|
+
}, option.label ?? option.value))), /* @__PURE__ */ React27.createElement(Select3.Arrow, null))));
|
|
2272
3459
|
};
|
|
2273
3460
|
|
|
2274
3461
|
// src/components/ViewEditor/ViewEditor.tsx
|
|
2275
3462
|
import { RegistryContext } from "@effect-atom/atom-react";
|
|
2276
|
-
import * as Array2 from "effect/Array";
|
|
2277
3463
|
import * as Match2 from "effect/Match";
|
|
2278
|
-
import * as
|
|
2279
|
-
import * as
|
|
2280
|
-
import
|
|
2281
|
-
import { Entity as Entity2, Feed, Filter as
|
|
2282
|
-
import {
|
|
2283
|
-
import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
|
|
2284
|
-
import { invariant } from "@dxos/invariant";
|
|
3464
|
+
import * as Option8 from "effect/Option";
|
|
3465
|
+
import * as Schema5 from "effect/Schema";
|
|
3466
|
+
import React28, { forwardRef as forwardRef2, useCallback as useCallback20, useContext as useContext2, useImperativeHandle, useMemo as useMemo14, useState as useState7 } from "react";
|
|
3467
|
+
import { Entity as Entity2, Feed, Filter as Filter3, Format as Format7, Obj as Obj7, Query, QueryAST, Ref as Ref8, Type as Type7, View } from "@dxos/echo";
|
|
3468
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
2285
3469
|
import { useObject, useQuery as useQuery2 } from "@dxos/react-client/echo";
|
|
2286
|
-
import { IconButton as IconButton4, Input as
|
|
3470
|
+
import { IconButton as IconButton4, Input as Input18, Message, useTranslation as useTranslation13 } from "@dxos/react-ui";
|
|
2287
3471
|
import { QueryForm } from "@dxos/react-ui-components";
|
|
2288
3472
|
import { List as List2 } from "@dxos/react-ui-list";
|
|
2289
3473
|
import { ParentLabelAnnotation, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
|
|
2290
|
-
import { mx as
|
|
2291
|
-
|
|
2292
|
-
var
|
|
2293
|
-
|
|
2294
|
-
const
|
|
2295
|
-
const
|
|
2296
|
-
const
|
|
2297
|
-
|
|
2298
|
-
const
|
|
3474
|
+
import { mx as mx8, osTranslations as osTranslations2 } from "@dxos/ui-theme";
|
|
3475
|
+
import { translationKey as translationKey15 } from "#translations";
|
|
3476
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
|
|
3477
|
+
var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, type, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
|
|
3478
|
+
const atomRegistry = useContext2(RegistryContext);
|
|
3479
|
+
const schemaReadonly = Type7.getDatabase(type) == null;
|
|
3480
|
+
const { t } = useTranslation13(translationKey15);
|
|
3481
|
+
const projectionModel = useMemo14(() => {
|
|
3482
|
+
const jsonSchema = type.jsonSchema;
|
|
3483
|
+
const change = createEchoChangeCallback(view, Type7.getDatabase(type) != null ? type : void 0);
|
|
2299
3484
|
const model = new ProjectionModel({
|
|
2300
3485
|
registry: atomRegistry,
|
|
2301
3486
|
view,
|
|
@@ -2305,7 +3490,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2305
3490
|
return model;
|
|
2306
3491
|
}, [
|
|
2307
3492
|
atomRegistry,
|
|
2308
|
-
|
|
3493
|
+
type,
|
|
2309
3494
|
view
|
|
2310
3495
|
]);
|
|
2311
3496
|
useImperativeHandle(forwardedRef, () => projectionModel, [
|
|
@@ -2317,41 +3502,42 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2317
3502
|
if (from._tag !== "scope") {
|
|
2318
3503
|
return void 0;
|
|
2319
3504
|
}
|
|
2320
|
-
|
|
3505
|
+
const feedScope = from.scopes.find((s) => s._tag === "feed");
|
|
3506
|
+
return Option8.fromNullable(feedScope).pipe(Option8.map((s) => s.feedUri), Option8.getOrUndefined);
|
|
2321
3507
|
}), Match2.orElse(() => void 0));
|
|
2322
|
-
const feeds = useQuery2(db,
|
|
2323
|
-
const targetRef =
|
|
3508
|
+
const feeds = useQuery2(db, Filter3.type(Feed.Feed));
|
|
3509
|
+
const targetRef = useMemo14(() => {
|
|
2324
3510
|
if (!queueTarget) {
|
|
2325
3511
|
return void 0;
|
|
2326
3512
|
}
|
|
2327
|
-
const feed = feeds.find((feed2) => Feed.
|
|
2328
|
-
return feed ?
|
|
3513
|
+
const feed = feeds.find((feed2) => Feed.getQueueUri(feed2)?.toString() === queueTarget);
|
|
3514
|
+
return feed ? Ref8.fromURI(Entity2.getURI(feed)) : void 0;
|
|
2329
3515
|
}, [
|
|
2330
3516
|
queueTarget,
|
|
2331
3517
|
feeds
|
|
2332
3518
|
]);
|
|
2333
|
-
const viewSchema =
|
|
2334
|
-
const base =
|
|
2335
|
-
query: mode === "schema" ?
|
|
3519
|
+
const viewSchema = useMemo14(() => {
|
|
3520
|
+
const base = Schema5.Struct({
|
|
3521
|
+
query: mode === "schema" ? Format7.URL.annotations({
|
|
2336
3522
|
title: "Record type"
|
|
2337
3523
|
}) : QueryAST.Query.annotations({
|
|
2338
3524
|
title: "Query"
|
|
2339
3525
|
})
|
|
2340
3526
|
});
|
|
2341
3527
|
if (mode === "tag") {
|
|
2342
|
-
return
|
|
3528
|
+
return Schema5.Struct({
|
|
2343
3529
|
...base.fields,
|
|
2344
3530
|
// TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
|
|
2345
|
-
target:
|
|
3531
|
+
target: Ref8.Ref(Feed.Feed).pipe(Schema5.annotations({
|
|
2346
3532
|
title: "Target Feed"
|
|
2347
|
-
}), ParentLabelAnnotation.set(true),
|
|
2348
|
-
}).pipe(
|
|
3533
|
+
}), ParentLabelAnnotation.set(true), Schema5.optional)
|
|
3534
|
+
}).pipe(Schema5.mutable);
|
|
2349
3535
|
}
|
|
2350
|
-
return base.pipe(
|
|
3536
|
+
return base.pipe(Schema5.mutable);
|
|
2351
3537
|
}, [
|
|
2352
3538
|
mode
|
|
2353
3539
|
]);
|
|
2354
|
-
const viewValues =
|
|
3540
|
+
const viewValues = useMemo14(() => ({
|
|
2355
3541
|
query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
|
|
2356
3542
|
target: targetRef
|
|
2357
3543
|
}), [
|
|
@@ -2359,7 +3545,7 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2359
3545
|
view.query.ast,
|
|
2360
3546
|
targetRef
|
|
2361
3547
|
]);
|
|
2362
|
-
const fieldMap =
|
|
3548
|
+
const fieldMap = useMemo14(() => mode === "tag" ? customFields({
|
|
2363
3549
|
types,
|
|
2364
3550
|
tags
|
|
2365
3551
|
}) : void 0, [
|
|
@@ -2367,55 +3553,46 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2367
3553
|
types,
|
|
2368
3554
|
tags
|
|
2369
3555
|
]);
|
|
2370
|
-
const handleUpdate =
|
|
3556
|
+
const handleUpdate = useCallback20((values) => {
|
|
2371
3557
|
const targetValue = values.target;
|
|
2372
3558
|
let queueDxn;
|
|
2373
|
-
if (
|
|
2374
|
-
const
|
|
2375
|
-
const feed = feeds.find((feed2) =>
|
|
3559
|
+
if (Ref8.isRef(targetValue)) {
|
|
3560
|
+
const feedUri = targetValue.uri;
|
|
3561
|
+
const feed = feeds.find((feed2) => Obj7.getURI(feed2) === feedUri);
|
|
2376
3562
|
if (feed) {
|
|
2377
|
-
queueDxn = Feed.
|
|
3563
|
+
queueDxn = Feed.getQueueUri(feed);
|
|
2378
3564
|
}
|
|
2379
3565
|
}
|
|
2380
|
-
const query = mode === "schema" ? Query.select(
|
|
3566
|
+
const query = mode === "schema" ? Query.select(Filter3.typename(values.query)).ast : JSON.parse(JSON.stringify(values.query));
|
|
2381
3567
|
onQueryChanged?.(query, queueDxn);
|
|
2382
3568
|
}, [
|
|
2383
3569
|
onQueryChanged,
|
|
2384
3570
|
mode,
|
|
2385
3571
|
feeds
|
|
2386
3572
|
]);
|
|
2387
|
-
const handleDelete =
|
|
2388
|
-
|
|
2389
|
-
F: __dxlog_file3,
|
|
2390
|
-
L: 185,
|
|
2391
|
-
S: void 0,
|
|
2392
|
-
A: [
|
|
2393
|
-
"!readonly",
|
|
2394
|
-
""
|
|
2395
|
-
]
|
|
2396
|
-
});
|
|
3573
|
+
const handleDelete = useCallback20((fieldId) => {
|
|
3574
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 124, S: void 0, A: ["!readonly", ""] });
|
|
2397
3575
|
onDelete?.(fieldId);
|
|
2398
3576
|
}, [
|
|
2399
3577
|
onDelete,
|
|
2400
3578
|
readonly
|
|
2401
3579
|
]);
|
|
2402
|
-
return /* @__PURE__ */
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
}, schemaReadonly && !readonly && /* @__PURE__ */ React19.createElement(Message.Root, {
|
|
3580
|
+
return /* @__PURE__ */ React28.createElement("div", {
|
|
3581
|
+
className: mx8(classNames)
|
|
3582
|
+
}, schemaReadonly && !readonly && /* @__PURE__ */ React28.createElement(Message.Root, {
|
|
2406
3583
|
valence: "info",
|
|
2407
3584
|
classNames: "my-form-padding"
|
|
2408
|
-
}, /* @__PURE__ */
|
|
3585
|
+
}, /* @__PURE__ */ React28.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React28.createElement(Form.Root, {
|
|
2409
3586
|
schema: viewSchema,
|
|
2410
3587
|
values: viewValues,
|
|
2411
3588
|
fieldMap,
|
|
2412
3589
|
db,
|
|
2413
3590
|
onValuesChanged: handleUpdate
|
|
2414
|
-
}, /* @__PURE__ */
|
|
2415
|
-
label: t("fields
|
|
3591
|
+
}, /* @__PURE__ */ React28.createElement(Form.FieldSet, null), /* @__PURE__ */ React28.createElement(FormFieldLabel, {
|
|
3592
|
+
label: t("fields.label"),
|
|
2416
3593
|
asChild: true
|
|
2417
|
-
}), /* @__PURE__ */
|
|
2418
|
-
|
|
3594
|
+
}), /* @__PURE__ */ React28.createElement(FieldList, {
|
|
3595
|
+
type,
|
|
2419
3596
|
view,
|
|
2420
3597
|
registry,
|
|
2421
3598
|
readonly,
|
|
@@ -2423,14 +3600,14 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2423
3600
|
onDelete: handleDelete
|
|
2424
3601
|
})));
|
|
2425
3602
|
});
|
|
2426
|
-
var FieldList = ({
|
|
2427
|
-
const atomRegistry =
|
|
2428
|
-
const schemaReadonly =
|
|
2429
|
-
const { t } =
|
|
3603
|
+
var FieldList = ({ type, view, registry, readonly, showHeading = false, onDelete }) => {
|
|
3604
|
+
const atomRegistry = useContext2(RegistryContext);
|
|
3605
|
+
const schemaReadonly = Type7.getDatabase(type) == null;
|
|
3606
|
+
const { t } = useTranslation13(translationKey15);
|
|
2430
3607
|
const [viewSnapshot] = useObject(view);
|
|
2431
|
-
const projectionModel =
|
|
2432
|
-
const jsonSchema =
|
|
2433
|
-
const change = createEchoChangeCallback(view,
|
|
3608
|
+
const projectionModel = useMemo14(() => {
|
|
3609
|
+
const jsonSchema = type.jsonSchema;
|
|
3610
|
+
const change = createEchoChangeCallback(view, Type7.getDatabase(type) != null ? type : void 0);
|
|
2434
3611
|
const model = new ProjectionModel({
|
|
2435
3612
|
registry: atomRegistry,
|
|
2436
3613
|
view,
|
|
@@ -2440,41 +3617,25 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2440
3617
|
return model;
|
|
2441
3618
|
}, [
|
|
2442
3619
|
atomRegistry,
|
|
2443
|
-
|
|
3620
|
+
type,
|
|
2444
3621
|
view
|
|
2445
3622
|
]);
|
|
2446
|
-
const [expandedField, setExpandedField] =
|
|
2447
|
-
const handleAdd =
|
|
2448
|
-
|
|
2449
|
-
F: __dxlog_file3,
|
|
2450
|
-
L: 250,
|
|
2451
|
-
S: void 0,
|
|
2452
|
-
A: [
|
|
2453
|
-
"!readonly",
|
|
2454
|
-
""
|
|
2455
|
-
]
|
|
2456
|
-
});
|
|
3623
|
+
const [expandedField, setExpandedField] = useState7();
|
|
3624
|
+
const handleAdd = useCallback20(() => {
|
|
3625
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 178, S: void 0, A: ["!readonly", ""] });
|
|
2457
3626
|
const field = projectionModel.createFieldProjection();
|
|
2458
3627
|
setExpandedField(field.id);
|
|
2459
3628
|
}, [
|
|
2460
3629
|
projectionModel,
|
|
2461
3630
|
readonly
|
|
2462
3631
|
]);
|
|
2463
|
-
const handleToggleField =
|
|
3632
|
+
const handleToggleField = useCallback20((field) => {
|
|
2464
3633
|
setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
|
|
2465
3634
|
}, [
|
|
2466
3635
|
readonly
|
|
2467
3636
|
]);
|
|
2468
|
-
const handleDelete =
|
|
2469
|
-
|
|
2470
|
-
F: __dxlog_file3,
|
|
2471
|
-
L: 264,
|
|
2472
|
-
S: void 0,
|
|
2473
|
-
A: [
|
|
2474
|
-
"!readonly",
|
|
2475
|
-
""
|
|
2476
|
-
]
|
|
2477
|
-
});
|
|
3637
|
+
const handleDelete = useCallback20((fieldId) => {
|
|
3638
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 191, S: void 0, A: ["!readonly", ""] });
|
|
2478
3639
|
if (fieldId === expandedField) {
|
|
2479
3640
|
setExpandedField(void 0);
|
|
2480
3641
|
}
|
|
@@ -2484,36 +3645,28 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2484
3645
|
onDelete,
|
|
2485
3646
|
readonly
|
|
2486
3647
|
]);
|
|
2487
|
-
const handleMove =
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
L: 276,
|
|
2491
|
-
S: void 0,
|
|
2492
|
-
A: [
|
|
2493
|
-
"!readonly",
|
|
2494
|
-
""
|
|
2495
|
-
]
|
|
2496
|
-
});
|
|
2497
|
-
Obj3.change(view, (v) => {
|
|
3648
|
+
const handleMove = useCallback20((fromIndex, toIndex) => {
|
|
3649
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 202, S: void 0, A: ["!readonly", ""] });
|
|
3650
|
+
Obj7.update(view, (view2) => {
|
|
2498
3651
|
const fields = [
|
|
2499
|
-
...
|
|
3652
|
+
...view2.projection.fields
|
|
2500
3653
|
];
|
|
2501
3654
|
const [moved] = fields.splice(fromIndex, 1);
|
|
2502
3655
|
fields.splice(toIndex, 0, moved);
|
|
2503
|
-
|
|
3656
|
+
view2.projection.fields = fields;
|
|
2504
3657
|
});
|
|
2505
3658
|
}, [
|
|
2506
3659
|
view,
|
|
2507
3660
|
readonly
|
|
2508
3661
|
]);
|
|
2509
|
-
const handleClose =
|
|
2510
|
-
const handleHide =
|
|
3662
|
+
const handleClose = useCallback20(() => setExpandedField(void 0), []);
|
|
3663
|
+
const handleHide = useCallback20((fieldId) => {
|
|
2511
3664
|
setExpandedField(void 0);
|
|
2512
3665
|
projectionModel.hideFieldProjection(fieldId);
|
|
2513
3666
|
}, [
|
|
2514
3667
|
projectionModel
|
|
2515
3668
|
]);
|
|
2516
|
-
const handleShow =
|
|
3669
|
+
const handleShow = useCallback20((property) => {
|
|
2517
3670
|
setExpandedField(void 0);
|
|
2518
3671
|
projectionModel.showFieldProjection(property);
|
|
2519
3672
|
}, [
|
|
@@ -2522,70 +3675,67 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2522
3675
|
if (!viewSnapshot) {
|
|
2523
3676
|
return null;
|
|
2524
3677
|
}
|
|
2525
|
-
return /* @__PURE__ */
|
|
3678
|
+
return /* @__PURE__ */ React28.createElement(List2.Root, {
|
|
2526
3679
|
items: viewSnapshot.projection.fields,
|
|
2527
|
-
isItem:
|
|
3680
|
+
isItem: Schema5.is(View.FieldSchema),
|
|
2528
3681
|
getId: (field) => field.id,
|
|
2529
3682
|
onMove: readonly ? void 0 : handleMove,
|
|
2530
3683
|
readonly
|
|
2531
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
3684
|
+
}, ({ items: fields }) => /* @__PURE__ */ React28.createElement(React28.Fragment, null, showHeading && /* @__PURE__ */ React28.createElement("h3", {
|
|
2532
3685
|
className: "text-sm"
|
|
2533
|
-
}, t("field
|
|
3686
|
+
}, t("field-path.label")), /* @__PURE__ */ React28.createElement("div", {
|
|
2534
3687
|
role: "list",
|
|
2535
3688
|
className: "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]"
|
|
2536
3689
|
}, fields?.map((field) => {
|
|
2537
3690
|
const hidden = field.visible === false;
|
|
2538
|
-
return /* @__PURE__ */
|
|
3691
|
+
return /* @__PURE__ */ React28.createElement(List2.Item, {
|
|
2539
3692
|
key: field.id,
|
|
2540
3693
|
item: field,
|
|
2541
3694
|
classNames: "grid grid-cols-subgrid col-span-5",
|
|
2542
3695
|
"aria-expanded": expandedField === field.id
|
|
2543
|
-
}, /* @__PURE__ */
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
}, /* @__PURE__ */ React19.createElement(List2.ItemDragHandle, {
|
|
3696
|
+
}, /* @__PURE__ */ React28.createElement("div", {
|
|
3697
|
+
className: "grid grid-cols-subgrid col-span-5 rounded-xs cursor-pointer min-h-10 dx-hover"
|
|
3698
|
+
}, /* @__PURE__ */ React28.createElement(List2.ItemDragHandle, {
|
|
2547
3699
|
disabled: readonly || schemaReadonly
|
|
2548
|
-
}), /* @__PURE__ */
|
|
3700
|
+
}), /* @__PURE__ */ React28.createElement(List2.ItemTitle, {
|
|
2549
3701
|
classNames: hidden && "text-subdued",
|
|
2550
3702
|
onClick: () => handleToggleField(field)
|
|
2551
|
-
}, field.path), /* @__PURE__ */
|
|
2552
|
-
label: t(hidden ? "show
|
|
3703
|
+
}, field.path), /* @__PURE__ */ React28.createElement(List2.ItemIconButton, {
|
|
3704
|
+
label: t(hidden ? "show-field.label" : "hide-field.label"),
|
|
2553
3705
|
"data-testid": hidden ? "show-field-button" : "hide-field-button",
|
|
2554
3706
|
icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
|
|
2555
3707
|
autoHide: false,
|
|
2556
3708
|
disabled: readonly || !hidden && projectionModel.getFields().length <= 1,
|
|
2557
3709
|
onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
|
|
2558
|
-
}), !readonly && /* @__PURE__ */
|
|
2559
|
-
label: t("delete
|
|
3710
|
+
}), !readonly && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement(List2.ItemDeleteButton, {
|
|
3711
|
+
label: t("delete-field.label"),
|
|
2560
3712
|
autoHide: false,
|
|
2561
3713
|
disabled: readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1,
|
|
2562
3714
|
onClick: () => handleDelete(field.id),
|
|
2563
3715
|
"data-testid": "field.delete"
|
|
2564
|
-
}), /* @__PURE__ */
|
|
3716
|
+
}), /* @__PURE__ */ React28.createElement(List2.ItemIconButton, {
|
|
2565
3717
|
iconOnly: true,
|
|
2566
3718
|
variant: "ghost",
|
|
2567
|
-
label: t("toggle
|
|
3719
|
+
label: t("toggle-expand.label", {
|
|
2568
3720
|
ns: osTranslations2
|
|
2569
3721
|
}),
|
|
2570
3722
|
icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
2571
3723
|
onClick: () => handleToggleField(field),
|
|
2572
3724
|
"data-testid": "field.toggle"
|
|
2573
|
-
}))), expandedField === field.id && !readonly && /* @__PURE__ */
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
}, /* @__PURE__ */ React19.createElement(FieldEditor, {
|
|
3725
|
+
}))), expandedField === field.id && !readonly && /* @__PURE__ */ React28.createElement("div", {
|
|
3726
|
+
className: "col-span-full mt-1 mb-1 border border-separator rounded-md"
|
|
3727
|
+
}, /* @__PURE__ */ React28.createElement(FieldEditor, {
|
|
2577
3728
|
readonly: readonly || schemaReadonly,
|
|
2578
3729
|
registry,
|
|
2579
3730
|
projection: projectionModel,
|
|
2580
3731
|
field,
|
|
2581
3732
|
onSave: handleClose
|
|
2582
3733
|
})));
|
|
2583
|
-
})), !readonly && !expandedField && /* @__PURE__ */
|
|
2584
|
-
role: "none",
|
|
3734
|
+
})), !readonly && !expandedField && /* @__PURE__ */ React28.createElement("div", {
|
|
2585
3735
|
className: "my-form-padding"
|
|
2586
|
-
}, /* @__PURE__ */
|
|
3736
|
+
}, /* @__PURE__ */ React28.createElement(IconButton4, {
|
|
2587
3737
|
icon: "ph--plus--regular",
|
|
2588
|
-
label: t("add
|
|
3738
|
+
label: t("add-property-button.label"),
|
|
2589
3739
|
onClick: handleAdd,
|
|
2590
3740
|
disabled: viewSnapshot.projection.fields.length >= VIEW_FIELD_LIMIT,
|
|
2591
3741
|
classNames: "w-full"
|
|
@@ -2593,13 +3743,13 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2593
3743
|
};
|
|
2594
3744
|
var customFields = ({ types, tags }) => ({
|
|
2595
3745
|
query: ({ type, readonly, label, getValue, onValueChange }) => {
|
|
2596
|
-
const handleChange =
|
|
3746
|
+
const handleChange = useCallback20((query) => onValueChange(type, query.ast), [
|
|
2597
3747
|
onValueChange
|
|
2598
3748
|
]);
|
|
2599
|
-
return /* @__PURE__ */
|
|
3749
|
+
return /* @__PURE__ */ React28.createElement(Input18.Root, null, /* @__PURE__ */ React28.createElement(FormFieldLabel, {
|
|
2600
3750
|
readonly,
|
|
2601
3751
|
label
|
|
2602
|
-
}), /* @__PURE__ */
|
|
3752
|
+
}), /* @__PURE__ */ React28.createElement(QueryForm, {
|
|
2603
3753
|
initialQuery: getValue(),
|
|
2604
3754
|
types,
|
|
2605
3755
|
tags,
|
|
@@ -2610,15 +3760,27 @@ var customFields = ({ types, tags }) => ({
|
|
|
2610
3760
|
export {
|
|
2611
3761
|
ArrayField,
|
|
2612
3762
|
BooleanField,
|
|
3763
|
+
DEFAULT_LAYOUT_NAME,
|
|
3764
|
+
DateField,
|
|
2613
3765
|
FieldEditor,
|
|
2614
3766
|
Form,
|
|
2615
3767
|
FormFieldErrorBoundary,
|
|
2616
3768
|
FormFieldLabel,
|
|
2617
3769
|
FormFieldWrapper,
|
|
3770
|
+
FormLayout,
|
|
3771
|
+
FormLayoutAnnotation,
|
|
3772
|
+
FormLayoutAnnotationId,
|
|
3773
|
+
FormTooltipsContext,
|
|
2618
3774
|
GeoPointField,
|
|
3775
|
+
InlineRefField,
|
|
3776
|
+
LayoutParseError,
|
|
3777
|
+
META_TAGS_KEY,
|
|
2619
3778
|
MarkdownField,
|
|
2620
3779
|
NumberField,
|
|
3780
|
+
ObjectForm,
|
|
2621
3781
|
ObjectPicker,
|
|
3782
|
+
ObjectProperties,
|
|
3783
|
+
ObjectTree,
|
|
2622
3784
|
RefField,
|
|
2623
3785
|
SelectField,
|
|
2624
3786
|
SelectOptionField,
|
|
@@ -2628,19 +3790,25 @@ export {
|
|
|
2628
3790
|
TupleField,
|
|
2629
3791
|
ViewEditor,
|
|
2630
3792
|
cellClassesForFieldType,
|
|
3793
|
+
createSelectField,
|
|
3794
|
+
detectFieldType,
|
|
2631
3795
|
formatForDisplay,
|
|
2632
3796
|
formatForEditing,
|
|
2633
3797
|
getDefaultValue,
|
|
2634
3798
|
getFormProperties,
|
|
2635
3799
|
getRefProps,
|
|
3800
|
+
getSelectOptionsFromAst,
|
|
3801
|
+
omitHiddenFormFields,
|
|
2636
3802
|
omitId,
|
|
3803
|
+
parseLayout,
|
|
2637
3804
|
parseValue,
|
|
2638
3805
|
pathNotUniqueError,
|
|
2639
|
-
translations,
|
|
2640
3806
|
useFormContext,
|
|
2641
3807
|
useFormFieldState,
|
|
2642
3808
|
useFormHandler,
|
|
3809
|
+
useFormTooltips,
|
|
2643
3810
|
useFormValues,
|
|
2644
|
-
useKeyHandler
|
|
3811
|
+
useKeyHandler,
|
|
3812
|
+
withMetaTags
|
|
2645
3813
|
};
|
|
2646
3814
|
//# sourceMappingURL=index.mjs.map
|