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