@dxos/react-ui-form 0.8.4-main.3eb6e50203 → 0.8.4-main.3fbcb4aa9b
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/README.md +0 -1
- package/dist/lib/browser/index.mjs +1134 -682
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/translations.mjs +82 -0
- package/dist/lib/browser/translations.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +1134 -682
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/translations.mjs +84 -0
- package/dist/lib/node-esm/translations.mjs.map +7 -0
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts +3 -3
- package/dist/types/src/components/FieldEditor/FieldEditor.d.ts.map +1 -1
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts +63 -61
- package/dist/types/src/components/FieldEditor/FieldEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.d.ts +44 -16
- package/dist/types/src/components/Form/Form.d.ts.map +1 -1
- package/dist/types/src/components/Form/Form.stories.d.ts +75 -73
- package/dist/types/src/components/Form/Form.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormField.d.ts +11 -5
- package/dist/types/src/components/Form/FormField.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormFieldComponent.d.ts +8 -7
- package/dist/types/src/components/Form/FormFieldComponent.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts +2 -2
- package/dist/types/src/components/Form/FormFieldComponent.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/FormFieldSet.d.ts +6 -10
- package/dist/types/src/components/Form/FormFieldSet.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/ArrayField.d.ts +4 -4
- package/dist/types/src/components/Form/fields/ArrayField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/BooleanField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/GeoPointField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/MarkdownField.d.ts +8 -1
- package/dist/types/src/components/Form/fields/MarkdownField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts +84 -0
- package/dist/types/src/components/Form/fields/MarkdownField.stories.d.ts.map +1 -0
- package/dist/types/src/components/Form/fields/NumberField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/RefField.d.ts +15 -7
- package/dist/types/src/components/Form/fields/RefField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts +63 -61
- package/dist/types/src/components/Form/fields/SelectOptionField.stories.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TextAreaField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TextField.d.ts +1 -1
- package/dist/types/src/components/Form/fields/TextField.d.ts.map +1 -1
- package/dist/types/src/components/Form/fields/TupleField.d.ts.map +1 -1
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts +9 -0
- package/dist/types/src/components/ObjectForm/ObjectForm.d.ts.map +1 -0
- package/dist/types/src/components/ObjectForm/index.d.ts +2 -0
- package/dist/types/src/components/ObjectForm/index.d.ts.map +1 -0
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts +26 -4
- package/dist/types/src/components/ObjectPicker/ObjectPicker.d.ts.map +1 -1
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts +63 -61
- package/dist/types/src/components/ObjectPicker/ObjectPicker.stories.d.ts.map +1 -1
- package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts +9 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts +127 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.stories.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts +2 -0
- package/dist/types/src/components/ObjectProperties/ObjectProperties.test.d.ts.map +1 -0
- package/dist/types/src/components/ObjectProperties/index.d.ts +2 -0
- package/dist/types/src/components/ObjectProperties/index.d.ts.map +1 -0
- package/dist/types/src/components/Settings/Settings.d.ts +28 -33
- package/dist/types/src/components/Settings/Settings.d.ts.map +1 -1
- package/dist/types/src/components/Settings/Settings.stories.d.ts +64 -61
- package/dist/types/src/components/Settings/Settings.stories.d.ts.map +1 -1
- package/dist/types/src/components/Settings/SettingsFieldSet.d.ts +43 -0
- package/dist/types/src/components/Settings/SettingsFieldSet.d.ts.map +1 -0
- package/dist/types/src/components/Settings/SettingsItem.d.ts +16 -0
- package/dist/types/src/components/Settings/SettingsItem.d.ts.map +1 -0
- package/dist/types/src/components/Settings/SettingsSelectField.d.ts +18 -0
- package/dist/types/src/components/Settings/SettingsSelectField.d.ts.map +1 -0
- package/dist/types/src/components/Settings/index.d.ts +2 -0
- package/dist/types/src/components/Settings/index.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts +6 -6
- package/dist/types/src/components/ViewEditor/ViewEditor.d.ts.map +1 -1
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts +67 -64
- package/dist/types/src/components/ViewEditor/ViewEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +2 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +4 -4
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/hooks/useFormHandler.d.ts.map +1 -1
- package/dist/types/src/hooks/useKeyHandler.d.ts +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 +63 -61
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/util/field-type.d.ts +19 -0
- package/dist/types/src/util/field-type.d.ts.map +1 -0
- package/dist/types/src/util/field.d.ts.map +1 -1
- package/dist/types/src/util/formatting.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/properties.d.ts.map +1 -1
- package/dist/types/src/util/refs.d.ts +1 -0
- package/dist/types/src/util/refs.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +42 -42
- package/src/components/FieldEditor/FieldEditor.stories.tsx +6 -8
- package/src/components/FieldEditor/FieldEditor.test.tsx +0 -1
- package/src/components/FieldEditor/FieldEditor.tsx +6 -6
- package/src/components/Form/AUDIT.md +17 -0
- package/src/components/Form/Form.stories.tsx +29 -44
- package/src/components/Form/Form.tsx +101 -54
- package/src/components/Form/FormField.tsx +39 -19
- package/src/components/Form/FormFieldComponent.stories.tsx +4 -4
- package/src/components/Form/FormFieldComponent.tsx +11 -11
- package/src/components/Form/FormFieldSet.tsx +121 -104
- package/src/components/Form/fields/ArrayField.tsx +10 -9
- package/src/components/Form/fields/GeoPointField.tsx +8 -7
- 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 +85 -45
- package/src/components/Form/fields/SelectField.tsx +1 -1
- package/src/components/Form/fields/SelectOptionField.stories.tsx +10 -8
- package/src/components/Form/fields/SelectOptionField.tsx +13 -13
- package/src/components/Form/fields/TextField.tsx +2 -2
- package/src/components/Form/fields/TupleField.tsx +1 -1
- package/src/components/ObjectForm/ObjectForm.tsx +114 -0
- package/src/components/ObjectForm/index.ts +5 -0
- package/src/components/ObjectPicker/ObjectPicker.stories.tsx +16 -18
- package/src/components/ObjectPicker/ObjectPicker.tsx +92 -65
- package/src/components/ObjectProperties/ObjectProperties.stories.tsx +362 -0
- package/src/components/ObjectProperties/ObjectProperties.test.tsx +101 -0
- package/src/components/ObjectProperties/ObjectProperties.tsx +141 -0
- package/src/components/ObjectProperties/index.ts +5 -0
- package/src/components/Settings/AUDIT.md +52 -0
- package/src/components/Settings/Settings.stories.tsx +69 -21
- package/src/components/Settings/Settings.tsx +33 -187
- 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 +21 -19
- package/src/components/ViewEditor/ViewEditor.test.tsx +2 -2
- package/src/components/ViewEditor/ViewEditor.tsx +87 -50
- package/src/components/index.ts +2 -0
- package/src/components/testing.tsx +23 -12
- package/src/hooks/useFormHandler.ts +42 -24
- package/src/hooks/useKeyHandler.tsx +7 -7
- package/src/index.ts +0 -4
- package/src/translations.ts +66 -63
- package/src/util/field-type.ts +60 -0
- package/src/util/index.ts +1 -1
- package/src/util/refs.ts +7 -3
- package/dist/types/src/components/Form/Form-old.stories.d.ts +0 -131
- package/dist/types/src/components/Form/Form-old.stories.d.ts.map +0 -1
- package/dist/types/src/util/echo.d.ts +0 -6
- package/dist/types/src/util/echo.d.ts.map +0 -1
- package/src/components/Form/Form-old.stories.tsx +0 -314
- package/src/util/echo.ts +0 -25
|
@@ -1,102 +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 React17, { useCallback as useCallback14, useEffect as
|
|
4
|
+
import React17, { useCallback as useCallback14, useEffect as useEffect5, useMemo as useMemo8, useState as useState6 } from "react";
|
|
82
5
|
import { Obj as Obj3 } from "@dxos/echo";
|
|
83
6
|
import { Format as Format4, 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 useTranslation9 } from "@dxos/react-ui";
|
|
86
9
|
import { formatToAdditionalPropertyAttributes, getFormatSchema } from "@dxos/schema";
|
|
87
|
-
|
|
88
|
-
// src/util/echo.ts
|
|
89
|
-
import { Obj } from "@dxos/echo";
|
|
90
|
-
import { setValue as setValuePlain, splitJsonPath } from "@dxos/effect";
|
|
91
|
-
var setValueEchoAware = (obj, path, value3) => {
|
|
92
|
-
if (Obj.isObject(obj)) {
|
|
93
|
-
Obj.change(obj, (mutableObj) => {
|
|
94
|
-
Obj.setValue(mutableObj, splitJsonPath(path), value3);
|
|
95
|
-
});
|
|
96
|
-
return obj;
|
|
97
|
-
}
|
|
98
|
-
return setValuePlain(obj, path, value3);
|
|
99
|
-
};
|
|
10
|
+
import { translationKey as translationKey9 } from "#translations";
|
|
100
11
|
|
|
101
12
|
// src/util/field.ts
|
|
102
13
|
import { Format, GeoLocation, TypeEnum } from "@dxos/echo/internal";
|
|
@@ -219,6 +130,46 @@ var pathNotUniqueError = (path) => ({
|
|
|
219
130
|
message: `'${path}' is already present`
|
|
220
131
|
});
|
|
221
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
|
+
|
|
222
173
|
// src/util/formatting.ts
|
|
223
174
|
import { format as formatDate } from "date-fns/format";
|
|
224
175
|
import { Format as Format2, GeoLocation as GeoLocation2, TypeEnum as TypeEnum2 } from "@dxos/echo/internal";
|
|
@@ -367,48 +318,57 @@ var getFormProperties = (ast) => {
|
|
|
367
318
|
|
|
368
319
|
// src/util/refs.ts
|
|
369
320
|
import { Ref } from "@dxos/echo";
|
|
370
|
-
import {
|
|
321
|
+
import { ReferenceAnnotationId } from "@dxos/echo/internal";
|
|
322
|
+
import { findAnnotation, getArrayElementType, isArrayType } from "@dxos/effect";
|
|
371
323
|
var getRefProps = (ast) => {
|
|
372
324
|
if (isArrayType(ast)) {
|
|
373
325
|
const elementType = getArrayElementType(ast);
|
|
374
326
|
if (elementType) {
|
|
375
327
|
if (Ref.isRefType(elementType)) {
|
|
328
|
+
const typename = findAnnotation(elementType, ReferenceAnnotationId)?.typename;
|
|
376
329
|
return {
|
|
377
330
|
ast: elementType,
|
|
378
|
-
isArray: true
|
|
331
|
+
isArray: true,
|
|
332
|
+
typename
|
|
379
333
|
};
|
|
380
334
|
}
|
|
381
335
|
}
|
|
382
336
|
}
|
|
383
337
|
if (Ref.isRefType(ast)) {
|
|
338
|
+
const typename = findAnnotation(ast, ReferenceAnnotationId)?.typename;
|
|
384
339
|
return {
|
|
385
340
|
ast,
|
|
386
|
-
isArray: false
|
|
341
|
+
isArray: false,
|
|
342
|
+
typename
|
|
387
343
|
};
|
|
388
344
|
}
|
|
389
345
|
return void 0;
|
|
390
346
|
};
|
|
391
347
|
|
|
392
348
|
// src/components/Form/fields/ArrayField.tsx
|
|
393
|
-
import * as
|
|
394
|
-
import * as
|
|
349
|
+
import * as Option4 from "effect/Option";
|
|
350
|
+
import * as SchemaAST4 from "effect/SchemaAST";
|
|
395
351
|
import React5, { useCallback as useCallback3 } from "react";
|
|
396
352
|
import { findNode as findNode2, getArrayElementType as getArrayElementType2, getDiscriminatedType as getDiscriminatedType2, isDiscriminatedUnion as isDiscriminatedUnion2, isNestedType as isNestedType2 } from "@dxos/effect";
|
|
397
353
|
import { IconButton as IconButton2, useTranslation as useTranslation3 } from "@dxos/react-ui";
|
|
354
|
+
import { translationKey as translationKey3 } from "#translations";
|
|
398
355
|
|
|
399
356
|
// src/components/Form/Form.tsx
|
|
400
357
|
import { createContext } from "@radix-ui/react-context";
|
|
358
|
+
import * as Option3 from "effect/Option";
|
|
401
359
|
import * as Schema2 from "effect/Schema";
|
|
402
|
-
import
|
|
360
|
+
import * as SchemaAST3 from "effect/SchemaAST";
|
|
361
|
+
import React4, { useEffect as useEffect2, useMemo as useMemo4, useRef } from "react";
|
|
362
|
+
import { Annotation as EchoAnnotation } from "@dxos/echo";
|
|
403
363
|
import { createJsonPath as createJsonPath3, getValue as getValue$2 } from "@dxos/effect";
|
|
404
|
-
import { IconButton, ScrollArea, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
405
|
-
import { mx
|
|
364
|
+
import { IconButton, ScrollArea, useMergeRefs, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
365
|
+
import { composable, composableProps, mx, withColumn } from "@dxos/ui-theme";
|
|
366
|
+
import { translationKey as translationKey2 } from "#translations";
|
|
406
367
|
|
|
407
368
|
// src/hooks/useFormHandler.ts
|
|
408
369
|
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
409
370
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
410
|
-
import {
|
|
411
|
-
import { createJsonPath, fromEffectValidationPath, getValue as getValue$, setValue as setValue$ } from "@dxos/effect";
|
|
371
|
+
import { createJsonPath, fromEffectValidationPath, getValue as getValue$ } from "@dxos/effect";
|
|
412
372
|
import { log } from "@dxos/log";
|
|
413
373
|
import { useDefaultValue } from "@dxos/react-ui";
|
|
414
374
|
import { validateSchema } from "@dxos/schema";
|
|
@@ -423,11 +383,13 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
423
383
|
prop: valuesProp,
|
|
424
384
|
defaultProp: defaultValues,
|
|
425
385
|
onChange: () => {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
386
|
+
if (valuesProp !== void 0) {
|
|
387
|
+
setValues(valuesProp ?? defaultValues);
|
|
388
|
+
setChanged({});
|
|
389
|
+
setTouched({});
|
|
390
|
+
setErrors({});
|
|
391
|
+
setSaving(false);
|
|
392
|
+
}
|
|
431
393
|
}
|
|
432
394
|
});
|
|
433
395
|
const values = values$;
|
|
@@ -439,12 +401,7 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
439
401
|
log("validate", {
|
|
440
402
|
values: values2,
|
|
441
403
|
errors: errors2
|
|
442
|
-
}, {
|
|
443
|
-
F: __dxlog_file,
|
|
444
|
-
L: 160,
|
|
445
|
-
S: void 0,
|
|
446
|
-
C: (f, a) => f(...a)
|
|
447
|
-
});
|
|
404
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 42, S: void 0 });
|
|
448
405
|
if (errors2.length === 0 && onValidate) {
|
|
449
406
|
const validatedValues = values2;
|
|
450
407
|
errors2 = onValidate(validatedValues) ?? [];
|
|
@@ -532,48 +489,39 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
532
489
|
log("onValueChange", {
|
|
533
490
|
path,
|
|
534
491
|
value: value3
|
|
535
|
-
}, {
|
|
536
|
-
F: __dxlog_file,
|
|
537
|
-
L: 259,
|
|
538
|
-
S: void 0,
|
|
539
|
-
C: (f, a) => f(...a)
|
|
540
|
-
});
|
|
492
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 138, S: void 0 });
|
|
541
493
|
const jsonPath = createJsonPath(path);
|
|
494
|
+
const pathArray = path;
|
|
542
495
|
let parsedValue = value3;
|
|
543
496
|
try {
|
|
544
497
|
if (type._tag === "NumberKeyword") {
|
|
545
498
|
parsedValue = parseFloat(value3) || 0;
|
|
546
499
|
}
|
|
547
500
|
} catch (err) {
|
|
548
|
-
log.catch(err, void 0, {
|
|
549
|
-
F: __dxlog_file,
|
|
550
|
-
L: 268,
|
|
551
|
-
S: void 0,
|
|
552
|
-
C: (f, a) => f(...a)
|
|
553
|
-
});
|
|
501
|
+
log.catch(err, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 150, S: void 0 });
|
|
554
502
|
parsedValue = void 0;
|
|
555
503
|
}
|
|
556
|
-
const newValues =
|
|
557
|
-
...setValue$(values, jsonPath, parsedValue)
|
|
558
|
-
};
|
|
559
|
-
setValues(newValues);
|
|
504
|
+
const newValues = mergeAtPath(values, pathArray, parsedValue);
|
|
560
505
|
const newChanged = {
|
|
561
506
|
[jsonPath]: true
|
|
562
507
|
};
|
|
563
|
-
setChanged({
|
|
564
|
-
...
|
|
508
|
+
setChanged((prev) => ({
|
|
509
|
+
...prev,
|
|
565
510
|
...newChanged
|
|
566
|
-
});
|
|
511
|
+
}));
|
|
567
512
|
const isValid2 = validate(newValues);
|
|
568
513
|
onValuesChanged?.(newValues, {
|
|
569
514
|
isValid: isValid2,
|
|
570
515
|
changed: newChanged
|
|
571
516
|
});
|
|
517
|
+
if (valuesProp === void 0) {
|
|
518
|
+
setValues(newValues);
|
|
519
|
+
}
|
|
572
520
|
}, [
|
|
573
521
|
values,
|
|
574
|
-
changed,
|
|
575
522
|
validate,
|
|
576
|
-
onValuesChanged
|
|
523
|
+
onValuesChanged,
|
|
524
|
+
valuesProp
|
|
577
525
|
]);
|
|
578
526
|
const onBlur = useCallback(async (path) => {
|
|
579
527
|
const jsonPath = createJsonPath(path);
|
|
@@ -630,6 +578,24 @@ var useFormHandler = ({ schema, autoSave, values: valuesProp, defaultValues: def
|
|
|
630
578
|
onCancel
|
|
631
579
|
]);
|
|
632
580
|
};
|
|
581
|
+
var mergeAtPath = (obj, path, value3) => {
|
|
582
|
+
if (path.length === 0) {
|
|
583
|
+
return value3;
|
|
584
|
+
}
|
|
585
|
+
const [head2, ...rest] = path;
|
|
586
|
+
const child = rest.length === 0 ? value3 : mergeAtPath(obj?.[head2], rest, value3);
|
|
587
|
+
if (Array.isArray(obj)) {
|
|
588
|
+
const copy = [
|
|
589
|
+
...obj
|
|
590
|
+
];
|
|
591
|
+
copy[head2] = child;
|
|
592
|
+
return copy;
|
|
593
|
+
}
|
|
594
|
+
return {
|
|
595
|
+
...obj,
|
|
596
|
+
[head2]: child
|
|
597
|
+
};
|
|
598
|
+
};
|
|
633
599
|
var flatMap = (errors) => {
|
|
634
600
|
return errors.reduce((result, { path, message }) => {
|
|
635
601
|
const jsonPath = fromEffectValidationPath(path);
|
|
@@ -641,9 +607,9 @@ var flatMap = (errors) => {
|
|
|
641
607
|
};
|
|
642
608
|
|
|
643
609
|
// src/hooks/useKeyHandler.tsx
|
|
644
|
-
import { useCallback as useCallback2,
|
|
610
|
+
import { useCallback as useCallback2, useLayoutEffect } from "react";
|
|
645
611
|
import { addEventListener } from "@dxos/async";
|
|
646
|
-
var useKeyHandler = (
|
|
612
|
+
var useKeyHandler = (elRef, form) => {
|
|
647
613
|
const handleKeyDown = useCallback2((event) => {
|
|
648
614
|
switch (event.key) {
|
|
649
615
|
case "Enter": {
|
|
@@ -659,13 +625,14 @@ var useKeyHandler = (formElement, form) => {
|
|
|
659
625
|
form.onSave,
|
|
660
626
|
form.autoSave
|
|
661
627
|
]);
|
|
662
|
-
|
|
663
|
-
|
|
628
|
+
useLayoutEffect(() => {
|
|
629
|
+
const el = elRef.current;
|
|
630
|
+
if (!el) {
|
|
664
631
|
return;
|
|
665
632
|
}
|
|
666
|
-
return addEventListener(
|
|
633
|
+
return addEventListener(el, "keydown", handleKeyDown);
|
|
667
634
|
}, [
|
|
668
|
-
|
|
635
|
+
elRef,
|
|
669
636
|
handleKeyDown
|
|
670
637
|
]);
|
|
671
638
|
};
|
|
@@ -673,17 +640,21 @@ var useKeyHandler = (formElement, form) => {
|
|
|
673
640
|
// src/components/Form/FormFieldComponent.tsx
|
|
674
641
|
import React, { Component } from "react";
|
|
675
642
|
import { Icon, Input, Tooltip } from "@dxos/react-ui";
|
|
676
|
-
import {
|
|
643
|
+
import { inputTextLabel } from "@dxos/ui-theme";
|
|
677
644
|
var FormFieldLabel = ({ label, error, readonly, asChild }) => {
|
|
678
645
|
const Label = readonly || asChild ? "span" : Input.Label;
|
|
679
|
-
return /* @__PURE__ */ React.createElement(
|
|
646
|
+
return /* @__PURE__ */ React.createElement("div", {
|
|
647
|
+
className: "flex items-center justify-between"
|
|
648
|
+
}, /* @__PURE__ */ React.createElement(Label, {
|
|
649
|
+
className: inputTextLabel
|
|
650
|
+
}, label), error && /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
|
|
680
651
|
asChild: true,
|
|
681
652
|
content: error,
|
|
682
653
|
side: "bottom"
|
|
683
654
|
}, /* @__PURE__ */ React.createElement(Icon, {
|
|
684
655
|
icon: "ph--warning--regular",
|
|
685
656
|
size: 4,
|
|
686
|
-
classNames:
|
|
657
|
+
classNames: "text-error-text"
|
|
687
658
|
})));
|
|
688
659
|
};
|
|
689
660
|
FormFieldLabel.displayName = "Form.FieldLabel";
|
|
@@ -696,7 +667,6 @@ var FormFieldWrapper = (props) => {
|
|
|
696
667
|
}
|
|
697
668
|
const str = String(value3 ?? "");
|
|
698
669
|
return /* @__PURE__ */ React.createElement("div", {
|
|
699
|
-
role: "none",
|
|
700
670
|
className: "contents"
|
|
701
671
|
}, /* @__PURE__ */ React.createElement(Input.Root, {
|
|
702
672
|
validationValence: status
|
|
@@ -725,9 +695,9 @@ var FormFieldErrorBoundary = class extends Component {
|
|
|
725
695
|
render() {
|
|
726
696
|
if (this.state.error) {
|
|
727
697
|
return /* @__PURE__ */ React.createElement("div", {
|
|
728
|
-
className: "flex gap-2 border border-
|
|
698
|
+
className: "flex gap-2 border border-rose-fill font-mono text-sm"
|
|
729
699
|
}, /* @__PURE__ */ React.createElement("span", {
|
|
730
|
-
className: "bg-
|
|
700
|
+
className: "bg-rose-fill text-surface-text px-1 font-thin"
|
|
731
701
|
}, "ERROR"), String(this.props.path?.join(".")));
|
|
732
702
|
}
|
|
733
703
|
return this.props.children;
|
|
@@ -740,20 +710,19 @@ var FormFieldErrorBoundary = class extends Component {
|
|
|
740
710
|
};
|
|
741
711
|
|
|
742
712
|
// src/components/Form/FormFieldSet.tsx
|
|
743
|
-
import React3, {
|
|
744
|
-
import { mx } from "@dxos/ui-theme";
|
|
745
|
-
import { isTruthy } from "@dxos/util";
|
|
713
|
+
import React3, { useMemo as useMemo3 } from "react";
|
|
746
714
|
|
|
747
715
|
// src/components/Form/FormField.tsx
|
|
748
716
|
import * as Match from "effect/Match";
|
|
749
717
|
import * as Option2 from "effect/Option";
|
|
750
718
|
import * as Schema from "effect/Schema";
|
|
751
|
-
import * as
|
|
719
|
+
import * as SchemaAST2 from "effect/SchemaAST";
|
|
752
720
|
import * as String2 from "effect/String";
|
|
753
721
|
import React2, { useMemo as useMemo2 } from "react";
|
|
754
722
|
import { Format as Format3 } from "@dxos/echo";
|
|
755
|
-
import { createJsonPath as createJsonPath2, findNode, getAnnotation, getDiscriminatedType, isArrayType as isArrayType2, isDiscriminatedUnion, isLiteralUnion, isNestedType } from "@dxos/effect";
|
|
723
|
+
import { createJsonPath as createJsonPath2, findNode, getAnnotation as getAnnotation2, getDiscriminatedType, isArrayType as isArrayType2, isDiscriminatedUnion, isLiteralUnion as isLiteralUnion2, isNestedType } from "@dxos/effect";
|
|
756
724
|
import { useTranslation } from "@dxos/react-ui";
|
|
725
|
+
import { translationKey } from "#translations";
|
|
757
726
|
var FormField = (props) => {
|
|
758
727
|
const {
|
|
759
728
|
type,
|
|
@@ -765,23 +734,25 @@ var FormField = (props) => {
|
|
|
765
734
|
readonly,
|
|
766
735
|
layout,
|
|
767
736
|
// RefFieldProps
|
|
737
|
+
createTypename,
|
|
768
738
|
createOptionLabel,
|
|
769
739
|
createOptionIcon,
|
|
770
740
|
createInitialValuePath,
|
|
741
|
+
createFieldMap: createFieldMap3,
|
|
771
742
|
db,
|
|
772
|
-
schemaHook,
|
|
773
|
-
getOptions
|
|
743
|
+
useSchema: schemaHook,
|
|
744
|
+
getOptions,
|
|
774
745
|
onCreate
|
|
775
746
|
} = props;
|
|
776
747
|
const { t } = useTranslation(translationKey);
|
|
777
|
-
const title =
|
|
778
|
-
const description =
|
|
779
|
-
const examples =
|
|
748
|
+
const title = getAnnotation2(SchemaAST2.TitleAnnotationId)(type);
|
|
749
|
+
const description = getAnnotation2(SchemaAST2.DescriptionAnnotationId)(type);
|
|
750
|
+
const examples = getAnnotation2(SchemaAST2.ExamplesAnnotationId)(type);
|
|
780
751
|
const label = useMemo2(() => title ?? String2.capitalize(name), [
|
|
781
752
|
title,
|
|
782
753
|
name
|
|
783
754
|
]);
|
|
784
|
-
const placeholder = useMemo2(() => examples?.length ? `${t("example
|
|
755
|
+
const placeholder = useMemo2(() => examples?.length ? `${t("example.placeholder")}: ${examples[0]}` : description ?? label, [
|
|
785
756
|
examples,
|
|
786
757
|
description,
|
|
787
758
|
label
|
|
@@ -794,6 +765,7 @@ var FormField = (props) => {
|
|
|
794
765
|
label,
|
|
795
766
|
placeholder,
|
|
796
767
|
layout,
|
|
768
|
+
db,
|
|
797
769
|
...fieldState
|
|
798
770
|
};
|
|
799
771
|
const jsonPath = createJsonPath2(path ?? []);
|
|
@@ -820,33 +792,41 @@ var FormField = (props) => {
|
|
|
820
792
|
if (Field) {
|
|
821
793
|
return /* @__PURE__ */ React2.createElement(Field, fieldProps);
|
|
822
794
|
}
|
|
823
|
-
const options =
|
|
795
|
+
const options = getSelectOptions(type);
|
|
824
796
|
if (options) {
|
|
797
|
+
const fieldProjections = projection?.getFieldProjections();
|
|
798
|
+
const fieldProjection = fieldProjections?.find((fp) => fp.field.path === name);
|
|
799
|
+
const selectOptions = fieldProjection?.props.options;
|
|
825
800
|
return /* @__PURE__ */ React2.createElement(SelectField, {
|
|
826
801
|
...fieldProps,
|
|
827
|
-
options: options.map((option) =>
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
802
|
+
options: options.map((option) => {
|
|
803
|
+
const selectOption = selectOptions?.find((so) => so.id === globalThis.String(option));
|
|
804
|
+
return {
|
|
805
|
+
value: option,
|
|
806
|
+
label: selectOption?.title ?? option.toString()
|
|
807
|
+
};
|
|
808
|
+
})
|
|
831
809
|
});
|
|
832
810
|
}
|
|
833
811
|
const refProps = getRefProps(type);
|
|
834
812
|
if (refProps) {
|
|
813
|
+
const isCreateTarget = !createTypename || refProps.typename === createTypename;
|
|
835
814
|
return /* @__PURE__ */ React2.createElement(RefField, {
|
|
836
815
|
...fieldProps,
|
|
837
816
|
...refProps,
|
|
838
|
-
createOptionLabel,
|
|
839
|
-
createOptionIcon,
|
|
840
|
-
createInitialValuePath,
|
|
817
|
+
createOptionLabel: isCreateTarget ? createOptionLabel : void 0,
|
|
818
|
+
createOptionIcon: isCreateTarget ? createOptionIcon : void 0,
|
|
819
|
+
createInitialValuePath: isCreateTarget ? createInitialValuePath : void 0,
|
|
820
|
+
createFieldMap: isCreateTarget ? createFieldMap3 : void 0,
|
|
841
821
|
db,
|
|
842
|
-
schemaHook,
|
|
843
|
-
getOptions
|
|
822
|
+
useSchema: schemaHook,
|
|
823
|
+
getOptions,
|
|
844
824
|
onCreate
|
|
845
825
|
});
|
|
846
826
|
}
|
|
847
827
|
if (isNestedType(type)) {
|
|
848
828
|
const baseNode = findNode(type, isDiscriminatedUnion);
|
|
849
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type,
|
|
829
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST2.isTypeLiteral);
|
|
850
830
|
if (typeLiteral) {
|
|
851
831
|
const schema = Schema.make(typeLiteral);
|
|
852
832
|
return /* @__PURE__ */ React2.createElement(FormFieldSet, {
|
|
@@ -862,8 +842,8 @@ var FormField = (props) => {
|
|
|
862
842
|
createOptionIcon,
|
|
863
843
|
createInitialValuePath,
|
|
864
844
|
db,
|
|
865
|
-
schemaHook,
|
|
866
|
-
getOptions
|
|
845
|
+
useSchema: schemaHook,
|
|
846
|
+
getOptions,
|
|
867
847
|
onCreate
|
|
868
848
|
});
|
|
869
849
|
}
|
|
@@ -887,8 +867,8 @@ var getFormField = ({ type, format }) => {
|
|
|
887
867
|
return BooleanField;
|
|
888
868
|
}
|
|
889
869
|
};
|
|
890
|
-
var
|
|
891
|
-
if (
|
|
870
|
+
var getSelectOptions = (ast) => {
|
|
871
|
+
if (isLiteralUnion2(ast)) {
|
|
892
872
|
return ast.types.map((type) => type.literal).filter((v) => v !== null);
|
|
893
873
|
}
|
|
894
874
|
return Format3.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option2.getOrUndefined(annotation));
|
|
@@ -896,47 +876,19 @@ var getOptions = (ast) => {
|
|
|
896
876
|
|
|
897
877
|
// src/components/Form/FormFieldSet.tsx
|
|
898
878
|
var FORM_FIELDSET_NAME = "Form.FieldSet";
|
|
899
|
-
var FormFieldSet =
|
|
879
|
+
var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection, layout, ...props }) => {
|
|
900
880
|
const values = useFormValues(FORM_FIELDSET_NAME, path);
|
|
901
|
-
const properties =
|
|
902
|
-
if (!schema) {
|
|
903
|
-
return [];
|
|
904
|
-
}
|
|
905
|
-
const props2 = getFormProperties(schema.ast);
|
|
906
|
-
if (projection) {
|
|
907
|
-
const fieldProjections = projection.getFieldProjections();
|
|
908
|
-
const hiddenProperties = new Set(projection.getHiddenProperties());
|
|
909
|
-
const visibleProps = props2.filter((prop) => !hiddenProperties.has(prop.name.toString()));
|
|
910
|
-
const orderedProps = [];
|
|
911
|
-
for (const fieldProjection of fieldProjections) {
|
|
912
|
-
const fieldPath = String(fieldProjection.field.path);
|
|
913
|
-
const prop = visibleProps.find((p) => p.name === fieldPath);
|
|
914
|
-
if (prop) {
|
|
915
|
-
orderedProps.push(prop);
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
|
|
919
|
-
const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
|
|
920
|
-
orderedProps.push(...remainingProps);
|
|
921
|
-
return orderedProps;
|
|
922
|
-
}
|
|
923
|
-
const filtered = exclude ? exclude(props2) : props2;
|
|
924
|
-
return sort ? filtered.sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filtered;
|
|
925
|
-
}, [
|
|
881
|
+
const properties = useFormFieldSetProperties({
|
|
926
882
|
schema,
|
|
927
883
|
values,
|
|
928
884
|
exclude,
|
|
929
885
|
sort,
|
|
930
|
-
projection
|
|
931
|
-
|
|
886
|
+
projection
|
|
887
|
+
});
|
|
932
888
|
if ((readonly || layout === "static") && values == null) {
|
|
933
889
|
return null;
|
|
934
890
|
}
|
|
935
|
-
return /* @__PURE__ */ React3.createElement("
|
|
936
|
-
role: "form",
|
|
937
|
-
className: mx("is-full", layout === "inline" && "flex flex-col gap-2", classNames),
|
|
938
|
-
ref: forwardRef4
|
|
939
|
-
}, layout !== "inline" && label && /* @__PURE__ */ React3.createElement(FormFieldLabel, {
|
|
891
|
+
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, layout !== "inline" && label && /* @__PURE__ */ React3.createElement(FormFieldLabel, {
|
|
940
892
|
label,
|
|
941
893
|
asChild: true
|
|
942
894
|
}), properties.map((property) => {
|
|
@@ -959,24 +911,72 @@ var FormFieldSet = /* @__PURE__ */ forwardRef(({ classNames, label, schema, read
|
|
|
959
911
|
projection,
|
|
960
912
|
...props
|
|
961
913
|
}));
|
|
962
|
-
})
|
|
963
|
-
}
|
|
914
|
+
}));
|
|
915
|
+
};
|
|
964
916
|
FormFieldSet.displayName = FORM_FIELDSET_NAME;
|
|
917
|
+
var useFormFieldSetProperties = ({ schema, exclude, projection, values, sort }) => {
|
|
918
|
+
return useMemo3(() => {
|
|
919
|
+
if (!schema) {
|
|
920
|
+
return [];
|
|
921
|
+
}
|
|
922
|
+
const schemaProps = getFormProperties(schema.ast);
|
|
923
|
+
const filteredProps = exclude ? exclude(schemaProps) : schemaProps;
|
|
924
|
+
if (projection) {
|
|
925
|
+
const fieldProjections = projection.getFieldProjections();
|
|
926
|
+
const hiddenProperties = new Set(projection.getHiddenProperties());
|
|
927
|
+
const visibleProps = filteredProps.filter((prop) => !hiddenProperties.has(prop.name.toString()));
|
|
928
|
+
const orderedProps = [];
|
|
929
|
+
for (const fieldProjection of fieldProjections) {
|
|
930
|
+
const fieldPath = String(fieldProjection.field.path);
|
|
931
|
+
const prop = visibleProps.find((prop2) => prop2.name === fieldPath);
|
|
932
|
+
if (prop) {
|
|
933
|
+
orderedProps.push(prop);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
|
|
937
|
+
const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
|
|
938
|
+
orderedProps.push(...remainingProps);
|
|
939
|
+
return orderedProps;
|
|
940
|
+
}
|
|
941
|
+
return sort ? [
|
|
942
|
+
...filteredProps
|
|
943
|
+
].sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filteredProps;
|
|
944
|
+
}, [
|
|
945
|
+
schema,
|
|
946
|
+
values,
|
|
947
|
+
exclude,
|
|
948
|
+
sort,
|
|
949
|
+
projection
|
|
950
|
+
]);
|
|
951
|
+
};
|
|
965
952
|
|
|
966
953
|
// src/components/Form/Form.tsx
|
|
967
954
|
var omitId = (schema) => schema.pipe(Schema2.omit("id"));
|
|
955
|
+
var omitHiddenFormFields = (schema) => {
|
|
956
|
+
const properties = SchemaAST3.getPropertySignatures(schema.ast);
|
|
957
|
+
const hidden = properties.filter((prop) => Option3.getOrElse(EchoAnnotation.FormInputAnnotation.getFromAst(prop.type), () => true) === false).map((prop) => prop.name);
|
|
958
|
+
return hidden.length === 0 ? schema : schema.pipe(Schema2.omit(...hidden));
|
|
959
|
+
};
|
|
968
960
|
var [FormContextProvider, useFormContext] = createContext("Form");
|
|
969
|
-
var useFormValues = (componentName, path
|
|
970
|
-
const
|
|
971
|
-
|
|
961
|
+
var useFormValues = (componentName, path, defaultValue) => {
|
|
962
|
+
const stablePath = useMemo4(() => path ?? [], [
|
|
963
|
+
path ? path.join(".") : void 0
|
|
964
|
+
]);
|
|
965
|
+
const jsonPath = createJsonPath3(stablePath);
|
|
966
|
+
const { form: { values, onValueChange } } = useFormContext(componentName);
|
|
972
967
|
const value3 = getValue$2(values, jsonPath);
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
968
|
+
const lastAppliedPathRef = useRef(null);
|
|
969
|
+
useEffect2(() => {
|
|
970
|
+
if (value3 == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {
|
|
971
|
+
lastAppliedPathRef.current = jsonPath;
|
|
972
|
+
onValueChange(stablePath, SchemaAST3.stringKeyword, defaultValue());
|
|
976
973
|
}
|
|
977
974
|
}, [
|
|
978
975
|
value3,
|
|
979
|
-
defaultValue
|
|
976
|
+
defaultValue,
|
|
977
|
+
onValueChange,
|
|
978
|
+
stablePath,
|
|
979
|
+
jsonPath
|
|
980
980
|
]);
|
|
981
981
|
return value3;
|
|
982
982
|
};
|
|
@@ -1013,49 +1013,59 @@ var FormRoot = ({ children, schema, values, onSave, onCancel, ...props }) => {
|
|
|
1013
1013
|
};
|
|
1014
1014
|
FormRoot.displayName = "Form.Root";
|
|
1015
1015
|
var FORM_VIEWPORT_NAME = "Form.Viewport";
|
|
1016
|
-
var FormViewport = ({ children }) => {
|
|
1016
|
+
var FormViewport = composable(({ children, ...props }, forwardedRef) => {
|
|
1017
1017
|
return /* @__PURE__ */ React4.createElement(ScrollArea.Root, {
|
|
1018
|
-
|
|
1018
|
+
...composableProps(props),
|
|
1019
|
+
orientation: "vertical",
|
|
1020
|
+
centered: true,
|
|
1021
|
+
padding: true,
|
|
1022
|
+
thin: true,
|
|
1023
|
+
ref: forwardedRef
|
|
1019
1024
|
}, /* @__PURE__ */ React4.createElement(ScrollArea.Viewport, null, children));
|
|
1020
|
-
};
|
|
1025
|
+
});
|
|
1021
1026
|
FormViewport.displayName = FORM_VIEWPORT_NAME;
|
|
1022
1027
|
var FORM_CONTENT_NAME = "Form.Content";
|
|
1023
|
-
var FormContent = ({
|
|
1028
|
+
var FormContent = composable(({ children, ...props }, forwardedRef) => {
|
|
1024
1029
|
const { form, testId } = useFormContext(FORM_CONTENT_NAME);
|
|
1025
|
-
const
|
|
1026
|
-
|
|
1030
|
+
const localRef = useRef(null);
|
|
1031
|
+
const mergedRef = useMergeRefs([
|
|
1032
|
+
forwardedRef,
|
|
1033
|
+
localRef
|
|
1034
|
+
]);
|
|
1035
|
+
useKeyHandler(localRef, form);
|
|
1027
1036
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1037
|
+
...composableProps(props, {
|
|
1038
|
+
role: "form",
|
|
1039
|
+
classNames: mx(withColumn.center(), "flex flex-col w-full pb-form-gap")
|
|
1040
|
+
}),
|
|
1041
|
+
"data-testid": testId,
|
|
1042
|
+
ref: mergedRef
|
|
1032
1043
|
}, children);
|
|
1033
|
-
};
|
|
1044
|
+
});
|
|
1034
1045
|
FormContent.displayName = FORM_CONTENT_NAME;
|
|
1035
1046
|
var FORM_FIELDSET_NAME2 = "Form.FieldSet";
|
|
1036
|
-
var FormFieldSet2 = (
|
|
1037
|
-
const { form, ...
|
|
1047
|
+
var FormFieldSet2 = (props) => {
|
|
1048
|
+
const { form, ...contextProps } = useFormContext(FORM_FIELDSET_NAME2);
|
|
1038
1049
|
return /* @__PURE__ */ React4.createElement(FormFieldSet, {
|
|
1039
|
-
classNames,
|
|
1040
1050
|
schema: form.schema,
|
|
1051
|
+
...contextProps,
|
|
1041
1052
|
...props
|
|
1042
1053
|
});
|
|
1043
1054
|
};
|
|
1044
1055
|
FormFieldSet2.displayName = FORM_FIELDSET_NAME2;
|
|
1045
1056
|
var FORM_ACTIONS_NAME = "Form.Actions";
|
|
1046
1057
|
var FormActions = ({ classNames }) => {
|
|
1047
|
-
const { t } = useTranslation2(
|
|
1058
|
+
const { t } = useTranslation2(translationKey2);
|
|
1048
1059
|
const { form: { canSave, onSave, onCancel }, readonly, layout } = useFormContext(FORM_ACTIONS_NAME);
|
|
1049
1060
|
if (readonly || layout === "static") {
|
|
1050
1061
|
return null;
|
|
1051
1062
|
}
|
|
1052
1063
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1053
|
-
|
|
1054
|
-
className: mx2("grid grid-flow-col auto-cols-fr gap-2 pbs-cardSpacingBlock", classNames)
|
|
1064
|
+
className: mx(withColumn.center(), "grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding", classNames)
|
|
1055
1065
|
}, onCancel && /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1056
1066
|
icon: "ph--x--regular",
|
|
1057
1067
|
iconEnd: true,
|
|
1058
|
-
label: t("cancel
|
|
1068
|
+
label: t("cancel-button.label"),
|
|
1059
1069
|
onClick: onCancel,
|
|
1060
1070
|
"data-testid": "cancel-button"
|
|
1061
1071
|
}), onSave && /* @__PURE__ */ React4.createElement(IconButton, {
|
|
@@ -1064,29 +1074,42 @@ var FormActions = ({ classNames }) => {
|
|
|
1064
1074
|
disabled: !canSave,
|
|
1065
1075
|
icon: "ph--check--regular",
|
|
1066
1076
|
iconEnd: true,
|
|
1067
|
-
label: t("save
|
|
1077
|
+
label: t("save-button.label"),
|
|
1068
1078
|
onClick: onSave,
|
|
1069
1079
|
"data-testid": "save-button"
|
|
1070
1080
|
}));
|
|
1071
1081
|
};
|
|
1072
1082
|
FormActions.displayName = FORM_ACTIONS_NAME;
|
|
1083
|
+
var FORM_SECTION_NAME = "Form.Section";
|
|
1084
|
+
var FormSection = composable(({ children, label, description, ...props }, forwardedRef) => {
|
|
1085
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
1086
|
+
...composableProps(props, {
|
|
1087
|
+
classNames: "flex flex-col pt-form-section-gap first:pt-0"
|
|
1088
|
+
}),
|
|
1089
|
+
ref: forwardedRef
|
|
1090
|
+
}, /* @__PURE__ */ React4.createElement("h2", {
|
|
1091
|
+
className: "text-lg"
|
|
1092
|
+
}, label), description && /* @__PURE__ */ React4.createElement("p", {
|
|
1093
|
+
className: "text-description"
|
|
1094
|
+
}, description), children);
|
|
1095
|
+
});
|
|
1096
|
+
FormSection.displayName = FORM_SECTION_NAME;
|
|
1073
1097
|
var FORM_SUBMIT_NAME = "Form.Submit";
|
|
1074
1098
|
var FormSubmit = ({ classNames, label, icon, disabled }) => {
|
|
1075
|
-
const { t } = useTranslation2(
|
|
1099
|
+
const { t } = useTranslation2(translationKey2);
|
|
1076
1100
|
const { form: { canSave, onSave }, readonly, layout } = useFormContext(FORM_SUBMIT_NAME);
|
|
1077
1101
|
if (readonly || layout === "static") {
|
|
1078
1102
|
return null;
|
|
1079
1103
|
}
|
|
1080
1104
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1081
|
-
|
|
1082
|
-
className: mx2("flex is-full pbs-cardSpacingBlock", classNames)
|
|
1105
|
+
className: mx("flex w-full pt-form-padding", classNames)
|
|
1083
1106
|
}, /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1084
|
-
classNames: "
|
|
1107
|
+
classNames: "w-full",
|
|
1085
1108
|
type: "submit",
|
|
1086
1109
|
variant: "primary",
|
|
1087
1110
|
disabled: disabled ?? !canSave,
|
|
1088
1111
|
icon: icon ?? "ph--check--regular",
|
|
1089
|
-
label: label ?? t("save
|
|
1112
|
+
label: label ?? t("save-button.label"),
|
|
1090
1113
|
onClick: onSave,
|
|
1091
1114
|
"data-testid": "save-button"
|
|
1092
1115
|
}));
|
|
@@ -1096,26 +1119,27 @@ var Form = {
|
|
|
1096
1119
|
Root: FormRoot,
|
|
1097
1120
|
Viewport: FormViewport,
|
|
1098
1121
|
Content: FormContent,
|
|
1122
|
+
Section: FormSection,
|
|
1099
1123
|
FieldSet: FormFieldSet2,
|
|
1124
|
+
Label: FormFieldLabel,
|
|
1100
1125
|
Actions: FormActions,
|
|
1101
|
-
Submit: FormSubmit
|
|
1102
|
-
Label: FormFieldLabel
|
|
1126
|
+
Submit: FormSubmit
|
|
1103
1127
|
};
|
|
1104
1128
|
|
|
1105
1129
|
// src/components/Form/fields/ArrayField.tsx
|
|
1106
1130
|
var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps, ...props }) => {
|
|
1107
|
-
const { t } = useTranslation3(
|
|
1131
|
+
const { t } = useTranslation3(translationKey3);
|
|
1108
1132
|
const elementType = getArrayElementType2(type);
|
|
1109
1133
|
const { onValueChange } = inputProps;
|
|
1110
1134
|
const values = useFormValues(ArrayField.displayName, path, () => []);
|
|
1111
1135
|
const getDefaultObjectValue = (typeNode) => {
|
|
1112
1136
|
const baseNode = findNode2(typeNode, isDiscriminatedUnion2);
|
|
1113
|
-
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode,
|
|
1137
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST4.isTypeLiteral);
|
|
1114
1138
|
if (!typeLiteral) {
|
|
1115
1139
|
return {};
|
|
1116
1140
|
}
|
|
1117
1141
|
return Object.fromEntries(getFormProperties(typeLiteral).map((prop) => {
|
|
1118
|
-
const defaultValue =
|
|
1142
|
+
const defaultValue = SchemaAST4.getDefaultAnnotation(prop.type).pipe((annotation) => Option4.getOrUndefined(annotation));
|
|
1119
1143
|
return [
|
|
1120
1144
|
prop.name,
|
|
1121
1145
|
defaultValue
|
|
@@ -1149,13 +1173,11 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1149
1173
|
label,
|
|
1150
1174
|
asChild: true
|
|
1151
1175
|
}), /* @__PURE__ */ React5.createElement("div", {
|
|
1152
|
-
|
|
1153
|
-
className: "flex flex-col gap-2"
|
|
1176
|
+
className: "flex flex-col gap-form-gap"
|
|
1154
1177
|
}, values?.map((_, index) => {
|
|
1155
1178
|
return /* @__PURE__ */ React5.createElement("div", {
|
|
1156
|
-
role: "none",
|
|
1157
1179
|
key: index,
|
|
1158
|
-
className: "grid grid-cols-[1fr_min-content] gap-
|
|
1180
|
+
className: "grid grid-cols-[1fr_min-content] gap-form-gap last:mb-form-gap items-center"
|
|
1159
1181
|
}, /* @__PURE__ */ React5.createElement(FormField, {
|
|
1160
1182
|
autoFocus: index === values.length - 1,
|
|
1161
1183
|
type: elementType,
|
|
@@ -1167,22 +1189,20 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1167
1189
|
layout: "inline",
|
|
1168
1190
|
...props
|
|
1169
1191
|
}), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement("div", {
|
|
1170
|
-
|
|
1171
|
-
className: "flex flex-col bs-full justify-end"
|
|
1192
|
+
className: "flex flex-col h-full justify-end"
|
|
1172
1193
|
}, /* @__PURE__ */ React5.createElement("div", {
|
|
1173
|
-
|
|
1174
|
-
className: "flex items-center bs-[var(--line-height)]"
|
|
1194
|
+
className: "flex items-center h-[2rem]"
|
|
1175
1195
|
}, /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1176
1196
|
icon: "ph--x--regular",
|
|
1177
1197
|
iconOnly: true,
|
|
1178
|
-
label: t("button
|
|
1198
|
+
label: t("remove.button"),
|
|
1179
1199
|
onClick: () => handleDelete(index),
|
|
1180
1200
|
classNames: "self-center"
|
|
1181
1201
|
}))));
|
|
1182
1202
|
})), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1183
|
-
classNames: "flex
|
|
1203
|
+
classNames: "flex w-full",
|
|
1184
1204
|
icon: "ph--plus--regular",
|
|
1185
|
-
label: t("add
|
|
1205
|
+
label: t("add-item.button"),
|
|
1186
1206
|
onClick: handleAdd
|
|
1187
1207
|
}));
|
|
1188
1208
|
};
|
|
@@ -1230,12 +1250,13 @@ var BooleanField = ({ type, readonly, onValueChange, ...props }) => {
|
|
|
1230
1250
|
};
|
|
1231
1251
|
|
|
1232
1252
|
// src/components/Form/fields/GeoPointField.tsx
|
|
1233
|
-
import React7, { useCallback as useCallback5, useEffect as
|
|
1253
|
+
import React7, { useCallback as useCallback5, useEffect as useEffect3, useMemo as useMemo5, useState as useState2 } from "react";
|
|
1234
1254
|
import { GeoLocation as GeoLocation3 } from "@dxos/echo/internal";
|
|
1235
1255
|
import { Input as Input3, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
1236
1256
|
import { safeParseFloat } from "@dxos/util";
|
|
1257
|
+
import { translationKey as translationKey4 } from "#translations";
|
|
1237
1258
|
var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onValueChange, onBlur }) => {
|
|
1238
|
-
const { t } = useTranslation4(
|
|
1259
|
+
const { t } = useTranslation4(translationKey4);
|
|
1239
1260
|
const { status, error } = getStatus();
|
|
1240
1261
|
const geoPoint = useMemo5(() => getValue() ?? [
|
|
1241
1262
|
0,
|
|
@@ -1248,7 +1269,7 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
|
|
|
1248
1269
|
]);
|
|
1249
1270
|
const [longitudeText, setLongitudeText] = useState2(value3.longitude?.toString());
|
|
1250
1271
|
const [latitudeText, setLatitudeText] = useState2(value3.latitude?.toString());
|
|
1251
|
-
|
|
1272
|
+
useEffect3(() => {
|
|
1252
1273
|
const location = GeoLocation3.fromGeoPoint(geoPoint);
|
|
1253
1274
|
setLongitudeText(location.longitude?.toString());
|
|
1254
1275
|
setLatitudeText(location.latitude?.toString());
|
|
@@ -1289,25 +1310,24 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
|
|
|
1289
1310
|
label,
|
|
1290
1311
|
asChild: true
|
|
1291
1312
|
}), layout === "static" ? /* @__PURE__ */ React7.createElement(LatLng, value3) : /* @__PURE__ */ React7.createElement("div", {
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
}, /* @__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, {
|
|
1313
|
+
className: "grid grid-cols-2 gap-form-gap"
|
|
1314
|
+
}, /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement(Input3.Root, null, layout !== "inline" && /* @__PURE__ */ React7.createElement(Input3.Label, null, t("latitude.label")), /* @__PURE__ */ React7.createElement(Input3.TextInput, {
|
|
1295
1315
|
type: "number",
|
|
1296
1316
|
step: "0.00001",
|
|
1297
1317
|
min: "-90",
|
|
1298
1318
|
max: "90",
|
|
1299
1319
|
disabled: !!readonly,
|
|
1300
|
-
placeholder: t("latitude
|
|
1320
|
+
placeholder: t("latitude.placeholder"),
|
|
1301
1321
|
value: latitudeText ?? "",
|
|
1302
1322
|
onChange: handleChange("latitude", setLatitudeText),
|
|
1303
1323
|
onBlur
|
|
1304
|
-
}))), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement(Input3.Root, null, layout !== "inline" && /* @__PURE__ */ React7.createElement(Input3.Label, null, t("longitude
|
|
1324
|
+
}))), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement(Input3.Root, null, layout !== "inline" && /* @__PURE__ */ React7.createElement(Input3.Label, null, t("longitude.label")), /* @__PURE__ */ React7.createElement(Input3.TextInput, {
|
|
1305
1325
|
type: "number",
|
|
1306
1326
|
step: "0.00001",
|
|
1307
1327
|
min: "-180",
|
|
1308
1328
|
max: "180",
|
|
1309
1329
|
disabled: !!readonly,
|
|
1310
|
-
placeholder: t("longitude
|
|
1330
|
+
placeholder: t("longitude.placeholder"),
|
|
1311
1331
|
value: longitudeText ?? "",
|
|
1312
1332
|
onChange: handleChange("longitude", setLongitudeText),
|
|
1313
1333
|
onBlur
|
|
@@ -1317,7 +1337,7 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
|
|
|
1317
1337
|
const latHem = latitude >= 0 ? "N" : "S";
|
|
1318
1338
|
const lngHem = longitude >= 0 ? "E" : "W";
|
|
1319
1339
|
return /* @__PURE__ */ React7.createElement("span", {
|
|
1320
|
-
className: "inline-flex items-center gap-
|
|
1340
|
+
className: "inline-flex items-center gap-form-gap"
|
|
1321
1341
|
}, /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(latitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
|
|
1322
1342
|
className: "text-subdued"
|
|
1323
1343
|
}, "\xB0", latHem)), /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(longitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
|
|
@@ -1326,56 +1346,141 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
|
|
|
1326
1346
|
};
|
|
1327
1347
|
|
|
1328
1348
|
// src/components/Form/fields/MarkdownField.tsx
|
|
1329
|
-
import
|
|
1330
|
-
import {
|
|
1331
|
-
|
|
1349
|
+
import { useAtomValue } from "@effect-atom/atom-react";
|
|
1350
|
+
import React8, { useCallback as useCallback6, useMemo as useMemo6 } from "react";
|
|
1351
|
+
import { Obj, Ref as Ref2 } from "@dxos/echo";
|
|
1352
|
+
import { AtomRef } from "@dxos/echo-atom";
|
|
1353
|
+
import { createDocAccessor } from "@dxos/echo-db";
|
|
1354
|
+
import { Button, Icon as Icon2, Input as Input4, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
1355
|
+
import { Editor, useBasicMarkdownExtensions } from "@dxos/react-ui-editor";
|
|
1356
|
+
import { Text } from "@dxos/schema";
|
|
1357
|
+
import { createDataExtensions } from "@dxos/ui-editor";
|
|
1358
|
+
import { translationKey as translationKey5 } from "#translations";
|
|
1359
|
+
var editorClassNames = "transition-colors bg-input-surface focus-within:bg-focus-surface border border-separator rounded-xs p-1 px-2";
|
|
1360
|
+
var MarkdownField = ({ type, readonly, label, placeholder, layout, db, getStatus, getValue, onValueChange }) => {
|
|
1332
1361
|
const { status, error } = getStatus();
|
|
1333
|
-
const
|
|
1334
|
-
const adjustHeight = useCallback6(() => {
|
|
1335
|
-
const textarea = textareaRef.current;
|
|
1336
|
-
if (textarea) {
|
|
1337
|
-
textarea.style.blockSize = "auto";
|
|
1338
|
-
textarea.style.blockSize = `${textarea.scrollHeight + 2}px`;
|
|
1339
|
-
}
|
|
1340
|
-
}, []);
|
|
1341
|
-
useEffect5(() => {
|
|
1342
|
-
adjustHeight();
|
|
1343
|
-
}, [
|
|
1344
|
-
adjustHeight
|
|
1345
|
-
]);
|
|
1346
|
-
useEffect5(() => {
|
|
1347
|
-
adjustHeight();
|
|
1348
|
-
}, [
|
|
1349
|
-
getValue(),
|
|
1350
|
-
adjustHeight
|
|
1351
|
-
]);
|
|
1352
|
-
const handleChange = useCallback6((event) => onValueChange(type, event.target.value), [
|
|
1353
|
-
type,
|
|
1354
|
-
onValueChange
|
|
1355
|
-
]);
|
|
1362
|
+
const isRef = Ref2.isRefType(type);
|
|
1356
1363
|
const value3 = getValue();
|
|
1357
|
-
if ((readonly || layout === "static") &&
|
|
1364
|
+
if ((readonly || layout === "static") && value3 == null) {
|
|
1358
1365
|
return null;
|
|
1359
1366
|
}
|
|
1367
|
+
const renderEditor = () => {
|
|
1368
|
+
if (isRef) {
|
|
1369
|
+
const reference = value3;
|
|
1370
|
+
if (reference) {
|
|
1371
|
+
return /* @__PURE__ */ React8.createElement(RefMarkdownEditor, {
|
|
1372
|
+
reference,
|
|
1373
|
+
placeholder
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
if (readonly) {
|
|
1377
|
+
return null;
|
|
1378
|
+
}
|
|
1379
|
+
return /* @__PURE__ */ React8.createElement(CreateTextButton, {
|
|
1380
|
+
db,
|
|
1381
|
+
disabled: !db,
|
|
1382
|
+
onCreate: (ref) => onValueChange(type, ref)
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
return /* @__PURE__ */ React8.createElement(StringMarkdownEditor, {
|
|
1386
|
+
value: value3 ?? "",
|
|
1387
|
+
placeholder,
|
|
1388
|
+
readonly: !!readonly,
|
|
1389
|
+
onChange: (next) => onValueChange(type, next)
|
|
1390
|
+
});
|
|
1391
|
+
};
|
|
1392
|
+
const renderStatic = () => {
|
|
1393
|
+
if (isRef) {
|
|
1394
|
+
const reference = value3;
|
|
1395
|
+
return reference ? /* @__PURE__ */ React8.createElement(RefStaticText, {
|
|
1396
|
+
reference
|
|
1397
|
+
}) : null;
|
|
1398
|
+
}
|
|
1399
|
+
return /* @__PURE__ */ React8.createElement("p", {
|
|
1400
|
+
className: "whitespace-pre-wrap"
|
|
1401
|
+
}, value3 ?? "");
|
|
1402
|
+
};
|
|
1360
1403
|
return /* @__PURE__ */ React8.createElement(Input4.Root, {
|
|
1361
1404
|
validationValence: status
|
|
1362
1405
|
}, layout !== "inline" && /* @__PURE__ */ React8.createElement(FormFieldLabel, {
|
|
1363
1406
|
error,
|
|
1364
1407
|
readonly,
|
|
1365
1408
|
label
|
|
1366
|
-
}), layout === "static" ?
|
|
1367
|
-
|
|
1368
|
-
|
|
1409
|
+
}), layout === "static" ? renderStatic() : renderEditor(), layout === "full" && /* @__PURE__ */ React8.createElement(Input4.Validation, null, error));
|
|
1410
|
+
};
|
|
1411
|
+
var RefStaticText = ({ reference }) => {
|
|
1412
|
+
const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
|
|
1413
|
+
reference
|
|
1414
|
+
]));
|
|
1415
|
+
if (!text?.content) {
|
|
1416
|
+
return null;
|
|
1417
|
+
}
|
|
1418
|
+
return /* @__PURE__ */ React8.createElement("p", {
|
|
1419
|
+
className: "whitespace-pre-wrap"
|
|
1420
|
+
}, text.content);
|
|
1421
|
+
};
|
|
1422
|
+
var RefMarkdownEditor = ({ reference, placeholder }) => {
|
|
1423
|
+
const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
|
|
1424
|
+
reference
|
|
1425
|
+
]));
|
|
1426
|
+
const dataExtensions = useMemo6(() => text ? [
|
|
1427
|
+
createDataExtensions({
|
|
1428
|
+
id: reference.dxn.toString(),
|
|
1429
|
+
text: createDocAccessor(text, [
|
|
1430
|
+
"content"
|
|
1431
|
+
])
|
|
1432
|
+
})
|
|
1433
|
+
] : [], [
|
|
1434
|
+
text,
|
|
1435
|
+
reference
|
|
1436
|
+
]);
|
|
1437
|
+
const extensions = useBasicMarkdownExtensions({
|
|
1369
1438
|
placeholder,
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
})
|
|
1439
|
+
extensions: dataExtensions
|
|
1440
|
+
});
|
|
1441
|
+
if (!text) {
|
|
1442
|
+
return null;
|
|
1443
|
+
}
|
|
1444
|
+
return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
|
|
1445
|
+
classNames: editorClassNames,
|
|
1446
|
+
extensions
|
|
1447
|
+
}));
|
|
1448
|
+
};
|
|
1449
|
+
var StringMarkdownEditor = ({ value: value3, placeholder, readonly, onChange }) => {
|
|
1450
|
+
const extensions = useBasicMarkdownExtensions({
|
|
1451
|
+
placeholder
|
|
1452
|
+
});
|
|
1453
|
+
const handleChange = useCallback6((next) => onChange(next), [
|
|
1454
|
+
onChange
|
|
1455
|
+
]);
|
|
1456
|
+
return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
|
|
1457
|
+
classNames: editorClassNames,
|
|
1458
|
+
extensions,
|
|
1459
|
+
value: value3,
|
|
1460
|
+
onChange: readonly ? void 0 : handleChange
|
|
1461
|
+
}));
|
|
1462
|
+
};
|
|
1463
|
+
var CreateTextButton = ({ db, disabled, onCreate }) => {
|
|
1464
|
+
const { t } = useTranslation5(translationKey5);
|
|
1465
|
+
const handleClick = useCallback6(() => {
|
|
1466
|
+
if (!db) {
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1469
|
+
const text = db.add(Obj.make(Text.Text, {
|
|
1470
|
+
content: ""
|
|
1471
|
+
}));
|
|
1472
|
+
onCreate(Ref2.make(text));
|
|
1473
|
+
}, [
|
|
1474
|
+
db,
|
|
1475
|
+
onCreate
|
|
1476
|
+
]);
|
|
1477
|
+
return /* @__PURE__ */ React8.createElement(Button, {
|
|
1478
|
+
onClick: handleClick,
|
|
1479
|
+
disabled
|
|
1480
|
+
}, /* @__PURE__ */ React8.createElement(Icon2, {
|
|
1481
|
+
icon: "ph--plus--regular",
|
|
1482
|
+
size: 4
|
|
1483
|
+
}), /* @__PURE__ */ React8.createElement("span", null, t("create-text.label")));
|
|
1379
1484
|
};
|
|
1380
1485
|
|
|
1381
1486
|
// src/components/Form/fields/NumberField.tsx
|
|
@@ -1401,47 +1506,33 @@ var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...prop
|
|
|
1401
1506
|
};
|
|
1402
1507
|
|
|
1403
1508
|
// src/components/Form/fields/RefField.tsx
|
|
1509
|
+
import React11, { useCallback as useCallback9, useMemo as useMemo7, useState as useState4 } from "react";
|
|
1404
1510
|
import "@dxos/lit-ui/dx-tag-picker.pcss";
|
|
1405
|
-
import
|
|
1406
|
-
import {
|
|
1407
|
-
import { ReferenceAnnotationId } from "@dxos/echo/internal";
|
|
1408
|
-
import {
|
|
1409
|
-
import { findAnnotation } from "@dxos/effect";
|
|
1511
|
+
import { Entity, Filter, Obj as Obj2, Ref as Ref3, Type } from "@dxos/echo";
|
|
1512
|
+
import { useQuery, useSchema as defaultUseSchema } from "@dxos/echo-react";
|
|
1513
|
+
import { ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo/internal";
|
|
1514
|
+
import { findAnnotation as findAnnotation2 } from "@dxos/effect";
|
|
1410
1515
|
import { DXN } from "@dxos/keys";
|
|
1411
1516
|
import { DxAnchor } from "@dxos/lit-ui/react";
|
|
1412
|
-
import { Button, Icon as
|
|
1413
|
-
import {
|
|
1517
|
+
import { Button as Button2, Icon as Icon3, Input as Input6, useTranslation as useTranslation7 } from "@dxos/react-ui";
|
|
1518
|
+
import { ParentLabelAnnotationId } from "@dxos/schema";
|
|
1519
|
+
import { translationKey as translationKey7 } from "#translations";
|
|
1414
1520
|
|
|
1415
1521
|
// src/components/ObjectPicker/ObjectPicker.tsx
|
|
1416
|
-
import React10, { forwardRef
|
|
1417
|
-
import { Popover, useTranslation as
|
|
1418
|
-
import { Combobox
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
value: "__create__",
|
|
1424
|
-
label: t(createOptionLabel[0], {
|
|
1425
|
-
ns: createOptionLabel[1].ns,
|
|
1426
|
-
text: query
|
|
1427
|
-
}),
|
|
1428
|
-
icon: createOptionIcon,
|
|
1429
|
-
classNames: "flex items-center gap-2",
|
|
1430
|
-
closeOnSelect: false,
|
|
1431
|
-
onSelect: () => {
|
|
1432
|
-
onCreateItemSelect(query);
|
|
1433
|
-
}
|
|
1434
|
-
});
|
|
1435
|
-
};
|
|
1436
|
-
var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, onSelect, onCreate, ...props }, ref) => {
|
|
1437
|
-
const { t } = useTranslation5(translationKey);
|
|
1522
|
+
import React10, { forwardRef, useCallback as useCallback8, useState as useState3 } from "react";
|
|
1523
|
+
import { Popover, useTranslation as useTranslation6 } from "@dxos/react-ui";
|
|
1524
|
+
import { Combobox } from "@dxos/react-ui-list";
|
|
1525
|
+
import { useSearchListResults } from "@dxos/react-ui-search";
|
|
1526
|
+
import { translationKey as translationKey6 } from "#translations";
|
|
1527
|
+
var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, onSelect, onCreate, ...props }, forwardedRef) => {
|
|
1528
|
+
const { t } = useTranslation6(translationKey6);
|
|
1438
1529
|
const [showForm, setShowForm] = useState3(false);
|
|
1439
1530
|
const [formInitialValue, setFormInitialValue] = useState3("");
|
|
1440
|
-
const { results, handleSearch } = useSearchListResults({
|
|
1531
|
+
const { results, query, handleSearch } = useSearchListResults({
|
|
1441
1532
|
items: options
|
|
1442
1533
|
});
|
|
1443
|
-
const handleFormSave = useCallback8((values) => {
|
|
1444
|
-
onCreate?.(values);
|
|
1534
|
+
const handleFormSave = useCallback8(async (values) => {
|
|
1535
|
+
await onCreate?.(values);
|
|
1445
1536
|
setShowForm(false);
|
|
1446
1537
|
setFormInitialValue("");
|
|
1447
1538
|
}, [
|
|
@@ -1463,22 +1554,31 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
|
|
|
1463
1554
|
}, [
|
|
1464
1555
|
createSchema
|
|
1465
1556
|
]);
|
|
1557
|
+
if (showForm && createSchema) {
|
|
1558
|
+
return /* @__PURE__ */ React10.createElement(Combobox.Content, {
|
|
1559
|
+
...props,
|
|
1560
|
+
onKeyDownCapture: handleKeyDown,
|
|
1561
|
+
ref: forwardedRef
|
|
1562
|
+
}, /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Root, {
|
|
1563
|
+
testId: "create-referenced-object-form",
|
|
1564
|
+
schema: createSchema,
|
|
1565
|
+
defaultValues: createInitialValuePath ? {
|
|
1566
|
+
[createInitialValuePath]: formInitialValue
|
|
1567
|
+
} : {},
|
|
1568
|
+
fieldMap: createFieldMap3,
|
|
1569
|
+
onSave: handleFormSave,
|
|
1570
|
+
onCancel: handleFormCancel
|
|
1571
|
+
}, /* @__PURE__ */ React10.createElement(Form.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Content, null, /* @__PURE__ */ React10.createElement(Form.FieldSet, null), /* @__PURE__ */ React10.createElement(Form.Actions, null))))), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
|
|
1572
|
+
}
|
|
1466
1573
|
return /* @__PURE__ */ React10.createElement(Combobox.Content, {
|
|
1467
1574
|
...props,
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
[createInitialValuePath]: formInitialValue
|
|
1476
|
-
} : {},
|
|
1477
|
-
onSave: handleFormSave,
|
|
1478
|
-
onCancel: handleFormCancel
|
|
1479
|
-
}, /* @__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, {
|
|
1480
|
-
placeholder: t("ref field combobox input placeholder"),
|
|
1481
|
-
autoFocus: true
|
|
1575
|
+
onKeyDownCapture: handleKeyDown,
|
|
1576
|
+
ref: forwardedRef
|
|
1577
|
+
}, /* @__PURE__ */ React10.createElement(Combobox.Input, {
|
|
1578
|
+
placeholder: t("ref-field-combobox-input.placeholder"),
|
|
1579
|
+
autoFocus: true,
|
|
1580
|
+
value: query,
|
|
1581
|
+
onValueChange: handleSearch
|
|
1482
1582
|
}), /* @__PURE__ */ React10.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
|
|
1483
1583
|
key: option.id,
|
|
1484
1584
|
value: option.id,
|
|
@@ -1486,16 +1586,34 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
|
|
|
1486
1586
|
checked: selectedIds?.includes(option.id),
|
|
1487
1587
|
onSelect: () => onSelect(option.id),
|
|
1488
1588
|
classNames: "flex items-center gap-2"
|
|
1489
|
-
})),
|
|
1589
|
+
})), createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
|
|
1590
|
+
query,
|
|
1490
1591
|
createOptionLabel,
|
|
1491
|
-
createOptionIcon,
|
|
1492
|
-
onCreateItemSelect: (
|
|
1493
|
-
setFormInitialValue(
|
|
1592
|
+
createOptionIcon: createOptionIcon ?? "ph--plus--regular",
|
|
1593
|
+
onCreateItemSelect: (currentQuery) => {
|
|
1594
|
+
setFormInitialValue(currentQuery);
|
|
1494
1595
|
setShowForm(true);
|
|
1495
1596
|
}
|
|
1496
|
-
}))
|
|
1597
|
+
})), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
|
|
1497
1598
|
});
|
|
1498
|
-
|
|
1599
|
+
var CreateItem = ({ query, createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
|
|
1600
|
+
const { t } = useTranslation6(translationKey6);
|
|
1601
|
+
const label = createOptionLabel ? t(createOptionLabel[0], {
|
|
1602
|
+
ns: createOptionLabel[1].ns,
|
|
1603
|
+
text: query
|
|
1604
|
+
}) : t("create-option.label");
|
|
1605
|
+
return /* @__PURE__ */ React10.createElement(Combobox.Item, {
|
|
1606
|
+
value: "__create__",
|
|
1607
|
+
label,
|
|
1608
|
+
icon: createOptionIcon,
|
|
1609
|
+
classNames: "flex items-center gap-2",
|
|
1610
|
+
closeOnSelect: false,
|
|
1611
|
+
onSelect: () => {
|
|
1612
|
+
onCreateItemSelect(query);
|
|
1613
|
+
}
|
|
1614
|
+
});
|
|
1615
|
+
};
|
|
1616
|
+
ObjectPickerContent.displayName = "ObjectPicker.Content";
|
|
1499
1617
|
var ObjectPicker = {
|
|
1500
1618
|
Root: Combobox.Root,
|
|
1501
1619
|
Portal: Combobox.Portal,
|
|
@@ -1508,34 +1626,43 @@ var ObjectPicker = {
|
|
|
1508
1626
|
var isRefSnapshot = (val) => {
|
|
1509
1627
|
return typeof val === "object" && typeof val?.["/"] === "string";
|
|
1510
1628
|
};
|
|
1511
|
-
var defaultGetOptions = (results) => results.map((result) => {
|
|
1629
|
+
var defaultGetOptions = (results, { parentLabel } = {}) => results.map((result) => {
|
|
1512
1630
|
const id = Entity.getDXN(result).toString();
|
|
1513
|
-
const
|
|
1631
|
+
const parent = parentLabel ? Obj2.getParent(result) : void 0;
|
|
1632
|
+
const label = parent ? Entity.getLabel(parent) : Entity.getLabel(result);
|
|
1514
1633
|
return {
|
|
1515
1634
|
id,
|
|
1516
1635
|
label: label ?? id
|
|
1517
1636
|
};
|
|
1518
1637
|
});
|
|
1519
|
-
var
|
|
1638
|
+
var defaultUseResults = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Obj2.Unknown) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
|
|
1520
1639
|
var RefField = (props) => {
|
|
1521
|
-
const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, db,
|
|
1522
|
-
const { t } =
|
|
1640
|
+
const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, db, useSchema = defaultUseSchema, useResults = defaultUseResults, getOptions = defaultGetOptions, onCreate, onValueChange } = props;
|
|
1641
|
+
const { t } = useTranslation7(translationKey7);
|
|
1523
1642
|
const { status, error } = getStatus();
|
|
1524
|
-
const typename =
|
|
1643
|
+
const typename = useMemo7(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
|
|
1525
1644
|
type
|
|
1526
1645
|
]);
|
|
1527
1646
|
const results = useResults(db, typename);
|
|
1528
|
-
const options =
|
|
1647
|
+
const options = useMemo7(() => {
|
|
1648
|
+
const parentLabel = type ? findAnnotation2(type, ParentLabelAnnotationId) === true : false;
|
|
1649
|
+
return getOptions(results, {
|
|
1650
|
+
parentLabel
|
|
1651
|
+
});
|
|
1652
|
+
}, [
|
|
1529
1653
|
results,
|
|
1530
|
-
|
|
1654
|
+
getOptions,
|
|
1655
|
+
type
|
|
1531
1656
|
]);
|
|
1532
1657
|
const handleGetValue = useCallback9(() => {
|
|
1533
1658
|
const formValue = getValue();
|
|
1659
|
+
const dxnToObjectId = (dxn) => dxn.split(":").pop() ?? dxn;
|
|
1534
1660
|
const unknownToRefOption = (value3) => {
|
|
1535
|
-
const isRef =
|
|
1661
|
+
const isRef = Ref3.isRef(value3);
|
|
1536
1662
|
if (isRef || isRefSnapshot(value3)) {
|
|
1537
1663
|
const dxnString = isRef ? value3.dxn.toString() : value3["/"];
|
|
1538
|
-
const
|
|
1664
|
+
const objectId = dxnToObjectId(dxnString);
|
|
1665
|
+
const matchingOption = options.find((option) => dxnToObjectId(option.id) === objectId);
|
|
1539
1666
|
if (matchingOption) {
|
|
1540
1667
|
return matchingOption;
|
|
1541
1668
|
}
|
|
@@ -1547,29 +1674,37 @@ var RefField = (props) => {
|
|
|
1547
1674
|
options,
|
|
1548
1675
|
getValue
|
|
1549
1676
|
]);
|
|
1550
|
-
const handleUpdate = useCallback9((id) => {
|
|
1551
|
-
const item2 = options.find((option) => option.id === id);
|
|
1552
|
-
const ref = item2 ? Ref2.fromDXN(DXN.parse(item2.id)) : void 0;
|
|
1553
|
-
onValueChange(type, ref);
|
|
1554
|
-
}, [
|
|
1555
|
-
options,
|
|
1556
|
-
type,
|
|
1557
|
-
onValueChange
|
|
1558
|
-
]);
|
|
1559
1677
|
const item = handleGetValue();
|
|
1560
|
-
const selectedIds =
|
|
1678
|
+
const selectedIds = useMemo7(() => item ? [
|
|
1561
1679
|
item.id
|
|
1562
1680
|
] : [], [
|
|
1563
1681
|
item
|
|
1564
1682
|
]);
|
|
1565
1683
|
const createSchema = useSchema(db, typename);
|
|
1566
|
-
const
|
|
1567
|
-
|
|
1568
|
-
|
|
1684
|
+
const [open, setOpen] = useState4(false);
|
|
1685
|
+
const handleCreate = useCallback9(async (values) => {
|
|
1686
|
+
if (!createSchema || !onCreate) {
|
|
1687
|
+
return;
|
|
1688
|
+
}
|
|
1689
|
+
const newObject = await onCreate(createSchema, values);
|
|
1690
|
+
if (newObject) {
|
|
1691
|
+
onValueChange(type, Ref3.make(newObject));
|
|
1569
1692
|
}
|
|
1693
|
+
setOpen(false);
|
|
1570
1694
|
}, [
|
|
1571
1695
|
createSchema,
|
|
1572
|
-
onCreate
|
|
1696
|
+
onCreate,
|
|
1697
|
+
type,
|
|
1698
|
+
onValueChange
|
|
1699
|
+
]);
|
|
1700
|
+
const handleUpdate = useCallback9((id) => {
|
|
1701
|
+
const item2 = options.find((option) => option.id === id);
|
|
1702
|
+
const ref = item2 ? Ref3.fromDXN(DXN.parse(item2.id)) : void 0;
|
|
1703
|
+
onValueChange(type, ref);
|
|
1704
|
+
}, [
|
|
1705
|
+
options,
|
|
1706
|
+
type,
|
|
1707
|
+
onValueChange
|
|
1573
1708
|
]);
|
|
1574
1709
|
const handleSelect = useCallback9((id) => {
|
|
1575
1710
|
if (item?.id === id) {
|
|
@@ -1591,40 +1726,46 @@ var RefField = (props) => {
|
|
|
1591
1726
|
readonly,
|
|
1592
1727
|
label
|
|
1593
1728
|
}), /* @__PURE__ */ React11.createElement("div", null, readonly ? !item ? /* @__PURE__ */ React11.createElement("p", {
|
|
1594
|
-
className:
|
|
1595
|
-
}, t("empty
|
|
1729
|
+
className: "text-description mb-2"
|
|
1730
|
+
}, t("empty-readonly-ref-field.label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
|
|
1596
1731
|
key: item.id,
|
|
1597
1732
|
dxn: item.id,
|
|
1598
|
-
rootclassname: "
|
|
1599
|
-
}, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root,
|
|
1733
|
+
rootclassname: "me-1"
|
|
1734
|
+
}, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, {
|
|
1735
|
+
open,
|
|
1736
|
+
onOpenChange: setOpen
|
|
1737
|
+
}, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
|
|
1600
1738
|
asChild: true,
|
|
1601
1739
|
classNames: "p-0"
|
|
1602
1740
|
}, item ? /* @__PURE__ */ React11.createElement("div", {
|
|
1603
|
-
className: "flex gap-
|
|
1741
|
+
className: "flex gap-form-gap w-full"
|
|
1604
1742
|
}, /* @__PURE__ */ React11.createElement(Input6.Root, {
|
|
1605
1743
|
key: item.id
|
|
1606
1744
|
}, /* @__PURE__ */ React11.createElement(Input6.TextInput, {
|
|
1607
1745
|
value: item.label,
|
|
1608
1746
|
readOnly: true,
|
|
1609
|
-
classNames: "
|
|
1610
|
-
}))) : /* @__PURE__ */ React11.createElement(
|
|
1611
|
-
classNames: "
|
|
1747
|
+
classNames: "w-full"
|
|
1748
|
+
}))) : /* @__PURE__ */ React11.createElement(Button2, {
|
|
1749
|
+
classNames: "w-full text-start gap-form-gap"
|
|
1612
1750
|
}, /* @__PURE__ */ React11.createElement("div", {
|
|
1613
|
-
role: "none",
|
|
1614
1751
|
className: "grow overflow-hidden"
|
|
1615
1752
|
}, /* @__PURE__ */ React11.createElement("span", {
|
|
1616
|
-
className: "
|
|
1617
|
-
}, placeholder ?? t("ref
|
|
1753
|
+
className: "truncate text-description"
|
|
1754
|
+
}, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon3, {
|
|
1618
1755
|
size: 3,
|
|
1619
1756
|
icon: "ph--caret-down--bold"
|
|
1620
1757
|
}))), /* @__PURE__ */ React11.createElement(ObjectPicker.Portal, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
|
|
1621
|
-
classNames: "
|
|
1758
|
+
classNames: "dx-card-popover-width",
|
|
1622
1759
|
options,
|
|
1623
1760
|
selectedIds,
|
|
1624
|
-
|
|
1761
|
+
// Strip hidden (`FormInputAnnotation.set(false)`) fields so the
|
|
1762
|
+
// form's validator doesn't reject required-but-hidden fields
|
|
1763
|
+
// such as backing-object refs supplied by a `FactoryAnnotation`.
|
|
1764
|
+
createSchema: createSchema && omitHiddenFormFields(omitId(createSchema)),
|
|
1625
1765
|
createOptionLabel,
|
|
1626
1766
|
createOptionIcon,
|
|
1627
1767
|
createInitialValuePath,
|
|
1768
|
+
createFieldMap: createFieldMap3,
|
|
1628
1769
|
onCreate: handleCreate,
|
|
1629
1770
|
onSelect: handleSelect
|
|
1630
1771
|
})))), layout === "full" && /* @__PURE__ */ React11.createElement(Input6.DescriptionAndValidation, null, error));
|
|
@@ -1653,7 +1794,7 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
|
|
|
1653
1794
|
value: value3,
|
|
1654
1795
|
onValueChange: handleValueChange
|
|
1655
1796
|
}, /* @__PURE__ */ React12.createElement(Select.TriggerButton, {
|
|
1656
|
-
classNames: "
|
|
1797
|
+
classNames: "w-full",
|
|
1657
1798
|
disabled: !!readonly,
|
|
1658
1799
|
placeholder
|
|
1659
1800
|
}), /* @__PURE__ */ React12.createElement(Select.Portal, null, /* @__PURE__ */ React12.createElement(Select.Content, null, /* @__PURE__ */ React12.createElement(Select.Viewport, null, options?.map(({ value: value4, label: label2 }) => (
|
|
@@ -1666,20 +1807,21 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
|
|
|
1666
1807
|
};
|
|
1667
1808
|
|
|
1668
1809
|
// src/components/Form/fields/SelectOptionField.tsx
|
|
1669
|
-
import React13, { useCallback as useCallback11, useEffect as
|
|
1810
|
+
import React13, { useCallback as useCallback11, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
|
|
1670
1811
|
import { PublicKey } from "@dxos/keys";
|
|
1671
|
-
import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as
|
|
1812
|
+
import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as useTranslation8 } from "@dxos/react-ui";
|
|
1672
1813
|
import { List } from "@dxos/react-ui-list";
|
|
1673
1814
|
import { HuePicker } from "@dxos/react-ui-pickers";
|
|
1674
1815
|
import { hues, osTranslations, subtleHover } from "@dxos/ui-theme";
|
|
1816
|
+
import { translationKey as translationKey8 } from "#translations";
|
|
1675
1817
|
var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueChange }) => {
|
|
1676
|
-
const { t } =
|
|
1818
|
+
const { t } = useTranslation8(translationKey8);
|
|
1677
1819
|
const { status, error } = getStatus();
|
|
1678
|
-
const [selected, setSelectedId] =
|
|
1679
|
-
const [isNewOption, setIsNewOption] =
|
|
1680
|
-
const inputRef =
|
|
1820
|
+
const [selected, setSelectedId] = useState5(null);
|
|
1821
|
+
const [isNewOption, setIsNewOption] = useState5(false);
|
|
1822
|
+
const inputRef = useRef2(null);
|
|
1681
1823
|
const options = getValue();
|
|
1682
|
-
|
|
1824
|
+
useEffect4(() => {
|
|
1683
1825
|
if (options === void 0) {
|
|
1684
1826
|
onValueChange(type, []);
|
|
1685
1827
|
}
|
|
@@ -1770,7 +1912,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1770
1912
|
type,
|
|
1771
1913
|
onValueChange
|
|
1772
1914
|
]);
|
|
1773
|
-
|
|
1915
|
+
useEffect4(() => {
|
|
1774
1916
|
if (selected && isNewOption && inputRef.current) {
|
|
1775
1917
|
inputRef.current.focus();
|
|
1776
1918
|
setIsNewOption(false);
|
|
@@ -1785,16 +1927,14 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1785
1927
|
error,
|
|
1786
1928
|
readonly,
|
|
1787
1929
|
label
|
|
1788
|
-
}), /* @__PURE__ */ React13.createElement("div", {
|
|
1789
|
-
role: "none"
|
|
1790
|
-
}, options && /* @__PURE__ */ React13.createElement(List.Root, {
|
|
1930
|
+
}), /* @__PURE__ */ React13.createElement("div", null, options && /* @__PURE__ */ React13.createElement(List.Root, {
|
|
1791
1931
|
items: options,
|
|
1792
1932
|
isItem: (_item) => true,
|
|
1793
1933
|
onMove: readonly ? void 0 : handleMove,
|
|
1794
1934
|
readonly: !!readonly
|
|
1795
1935
|
}, ({ items }) => /* @__PURE__ */ React13.createElement("div", {
|
|
1796
1936
|
role: "list",
|
|
1797
|
-
className: "
|
|
1937
|
+
className: "w-full overflow-auto"
|
|
1798
1938
|
}, items?.map((item) => /* @__PURE__ */ React13.createElement("div", {
|
|
1799
1939
|
key: item.id
|
|
1800
1940
|
}, /* @__PURE__ */ React13.createElement(List.Item, {
|
|
@@ -1802,7 +1942,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1802
1942
|
item,
|
|
1803
1943
|
classNames: [
|
|
1804
1944
|
subtleHover,
|
|
1805
|
-
"flex flex-col cursor-pointer rounded-
|
|
1945
|
+
"flex flex-col cursor-pointer rounded-xs"
|
|
1806
1946
|
],
|
|
1807
1947
|
"aria-expanded": selected === item.id
|
|
1808
1948
|
}, /* @__PURE__ */ React13.createElement("div", {
|
|
@@ -1817,20 +1957,20 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1817
1957
|
}, item.title || "\u200B")), /* @__PURE__ */ React13.createElement(IconButton3, {
|
|
1818
1958
|
iconOnly: true,
|
|
1819
1959
|
variant: "ghost",
|
|
1820
|
-
label: t(selected === item.id ? "collapse
|
|
1960
|
+
label: t(selected === item.id ? "collapse.label" : "expand.label", {
|
|
1821
1961
|
ns: osTranslations
|
|
1822
1962
|
}),
|
|
1823
1963
|
icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
1824
1964
|
onClick: () => handleClick(item.id)
|
|
1825
1965
|
})), selected === item.id && /* @__PURE__ */ React13.createElement("div", {
|
|
1826
|
-
className: "
|
|
1966
|
+
className: "flex flex-col p-form-padding gap-form-gap dx-density-fine"
|
|
1827
1967
|
}, /* @__PURE__ */ React13.createElement(Input8.Label, {
|
|
1828
1968
|
classNames: "text-xs"
|
|
1829
|
-
}, t("select
|
|
1830
|
-
className: "grid grid-cols-[1fr_min-content_min-content] gap-
|
|
1969
|
+
}, t("select-option.label")), /* @__PURE__ */ React13.createElement("div", {
|
|
1970
|
+
className: "grid grid-cols-[1fr_min-content_min-content] gap-form-gap"
|
|
1831
1971
|
}, /* @__PURE__ */ React13.createElement(Input8.TextInput, {
|
|
1832
1972
|
disabled: !!readonly,
|
|
1833
|
-
placeholder: t("select
|
|
1973
|
+
placeholder: t("select-option-label.placeholder"),
|
|
1834
1974
|
ref: selected === item.id ? inputRef : void 0,
|
|
1835
1975
|
value: item.title,
|
|
1836
1976
|
onChange: handleTitleChange(item.id),
|
|
@@ -1844,22 +1984,22 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1844
1984
|
disabled: !!readonly,
|
|
1845
1985
|
icon: "ph--trash--fill",
|
|
1846
1986
|
iconOnly: true,
|
|
1847
|
-
label: t("select
|
|
1987
|
+
label: t("select-option-delete.button"),
|
|
1848
1988
|
onClick: () => handleDelete(item.id)
|
|
1849
1989
|
})))))), /* @__PURE__ */ React13.createElement(IconButton3, {
|
|
1850
1990
|
variant: "ghost",
|
|
1851
1991
|
icon: "ph--plus--regular",
|
|
1852
|
-
label: t("select
|
|
1992
|
+
label: t("select-option-add.button"),
|
|
1853
1993
|
onClick: handleAdd,
|
|
1854
1994
|
disabled: !!readonly,
|
|
1855
|
-
classNames: "
|
|
1995
|
+
classNames: "w-full"
|
|
1856
1996
|
})))));
|
|
1857
1997
|
};
|
|
1858
1998
|
|
|
1859
1999
|
// src/components/Form/fields/TextField.tsx
|
|
1860
2000
|
import React14, { useCallback as useCallback12 } from "react";
|
|
1861
2001
|
import { Input as Input9 } from "@dxos/react-ui";
|
|
1862
|
-
var TextField = ({ type, readonly, placeholder,
|
|
2002
|
+
var TextField = ({ type, readonly, placeholder, onBlur, onValueChange, ...props }) => {
|
|
1863
2003
|
const handleChange = useCallback12((event) => onValueChange(type, event.target.value), [
|
|
1864
2004
|
type,
|
|
1865
2005
|
onValueChange
|
|
@@ -1872,8 +2012,8 @@ var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props
|
|
|
1872
2012
|
disabled: !!readonly,
|
|
1873
2013
|
placeholder,
|
|
1874
2014
|
value: value3,
|
|
1875
|
-
|
|
1876
|
-
|
|
2015
|
+
onBlur,
|
|
2016
|
+
onChange: handleChange
|
|
1877
2017
|
}));
|
|
1878
2018
|
};
|
|
1879
2019
|
|
|
@@ -1901,7 +2041,7 @@ var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...pr
|
|
|
1901
2041
|
// src/components/Form/fields/TupleField.tsx
|
|
1902
2042
|
import React16 from "react";
|
|
1903
2043
|
import { Input as Input11 } from "@dxos/react-ui";
|
|
1904
|
-
import { mx as
|
|
2044
|
+
import { mx as mx2 } from "@dxos/ui-theme";
|
|
1905
2045
|
import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
|
|
1906
2046
|
var gridCols = [
|
|
1907
2047
|
"grid-cols-1",
|
|
@@ -1919,7 +2059,7 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1919
2059
|
readonly,
|
|
1920
2060
|
label
|
|
1921
2061
|
}), /* @__PURE__ */ React16.createElement("div", {
|
|
1922
|
-
className:
|
|
2062
|
+
className: mx2("grid gap-form-gap", gridCols[binding.length - 1])
|
|
1923
2063
|
}, binding.map((prop) => /* @__PURE__ */ React16.createElement(Input11.TextInput, {
|
|
1924
2064
|
key: prop,
|
|
1925
2065
|
type: "number",
|
|
@@ -1938,13 +2078,13 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1938
2078
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
1939
2079
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
1940
2080
|
var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }) => {
|
|
1941
|
-
const { t } =
|
|
1942
|
-
const [props, setProps] =
|
|
1943
|
-
|
|
2081
|
+
const { t } = useTranslation9(translationKey9);
|
|
2082
|
+
const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
|
|
2083
|
+
useEffect5(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
1944
2084
|
field,
|
|
1945
2085
|
projection
|
|
1946
2086
|
]);
|
|
1947
|
-
const [schemas, setSchemas] =
|
|
2087
|
+
const [schemas, setSchemas] = useState6([]);
|
|
1948
2088
|
useAsyncEffect(async () => {
|
|
1949
2089
|
if (!registry) {
|
|
1950
2090
|
return;
|
|
@@ -1958,22 +2098,22 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
1958
2098
|
}, [
|
|
1959
2099
|
registry
|
|
1960
2100
|
]);
|
|
1961
|
-
const [referenceSchema, setReferenceSchema] =
|
|
1962
|
-
|
|
2101
|
+
const [referenceSchema, setReferenceSchema] = useState6();
|
|
2102
|
+
useEffect5(() => {
|
|
1963
2103
|
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
1964
2104
|
}, [
|
|
1965
2105
|
schemas,
|
|
1966
2106
|
props?.referenceSchema
|
|
1967
2107
|
]);
|
|
1968
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
2108
|
+
const [{ fieldSchema }, setFieldSchema] = useState6({
|
|
1969
2109
|
fieldSchema: getFormatSchema(props?.format)
|
|
1970
2110
|
});
|
|
1971
|
-
const fieldMap =
|
|
2111
|
+
const fieldMap = useMemo8(() => ({
|
|
1972
2112
|
["format"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
|
|
1973
2113
|
...props2,
|
|
1974
2114
|
options: FormatEnums.filter((value3) => value3 !== Format4.TypeFormat.None).map((value3) => ({
|
|
1975
2115
|
value: value3,
|
|
1976
|
-
label: t(`format
|
|
2116
|
+
label: t(`format.${value3}.label`)
|
|
1977
2117
|
}))
|
|
1978
2118
|
}),
|
|
1979
2119
|
["referenceSchema"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
|
|
@@ -2047,7 +2187,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2047
2187
|
]);
|
|
2048
2188
|
const handleSave = useCallback14((props2) => {
|
|
2049
2189
|
if (view) {
|
|
2050
|
-
Obj3.
|
|
2190
|
+
Obj3.update(view, () => {
|
|
2051
2191
|
projection.setFieldProjection({
|
|
2052
2192
|
field,
|
|
2053
2193
|
props: props2
|
|
@@ -2075,12 +2215,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2075
2215
|
if (!fieldSchema) {
|
|
2076
2216
|
log2.warn("invalid format", {
|
|
2077
2217
|
props
|
|
2078
|
-
}, {
|
|
2079
|
-
F: __dxlog_file2,
|
|
2080
|
-
L: 173,
|
|
2081
|
-
S: void 0,
|
|
2082
|
-
C: (f, a) => f(...a)
|
|
2083
|
-
});
|
|
2218
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 156, S: void 0 });
|
|
2084
2219
|
return null;
|
|
2085
2220
|
}
|
|
2086
2221
|
return /* @__PURE__ */ React17.createElement(Form.Root, {
|
|
@@ -2102,160 +2237,488 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2102
2237
|
}, /* @__PURE__ */ React17.createElement(Form.Content, null, /* @__PURE__ */ React17.createElement(Form.FieldSet, null), /* @__PURE__ */ React17.createElement(Form.Actions, null)));
|
|
2103
2238
|
};
|
|
2104
2239
|
|
|
2105
|
-
// src/components/
|
|
2106
|
-
import
|
|
2107
|
-
import
|
|
2108
|
-
import {
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
var
|
|
2115
|
-
var
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(SettingsSectionHeading, {
|
|
2134
|
-
title,
|
|
2135
|
-
description
|
|
2136
|
-
}), /* @__PURE__ */ React18.createElement("div", {
|
|
2137
|
-
className: "is-full pbs-trimMd space-y-trimMd"
|
|
2138
|
-
}, children));
|
|
2139
|
-
};
|
|
2140
|
-
SettingsSection.displayName = SETTINGS_SECTION_NAME;
|
|
2141
|
-
var SettingsSectionHeading = ({ title, description }) => {
|
|
2142
|
-
const { t } = useTranslation9(translationKey);
|
|
2143
|
-
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("h2", {
|
|
2144
|
-
className: "pli-trimMd container-max-width text-xl mbs-trimMd mbe-trimMd"
|
|
2145
|
-
}, toLocalizedString(title, t)), description && /* @__PURE__ */ React18.createElement("p", {
|
|
2146
|
-
className: "pli-trimMd mlb-trimMd container-max-width text-description"
|
|
2147
|
-
}, toLocalizedString(description, t)));
|
|
2240
|
+
// src/components/ObjectForm/ObjectForm.tsx
|
|
2241
|
+
import * as Schema3 from "effect/Schema";
|
|
2242
|
+
import React18, { useCallback as useCallback15, useMemo as useMemo9 } from "react";
|
|
2243
|
+
import { DXN as DXN2, Obj as Obj4, Ref as Ref4, Tag as Tag2, Type as Type2 } from "@dxos/echo";
|
|
2244
|
+
import { splitJsonPath } from "@dxos/echo/internal";
|
|
2245
|
+
import { invariant } from "@dxos/invariant";
|
|
2246
|
+
import { HuePicker as HuePicker2 } from "@dxos/react-ui-pickers";
|
|
2247
|
+
import { isNonNullable } from "@dxos/util";
|
|
2248
|
+
import { translationKey as translationKey10 } from "#translations";
|
|
2249
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectForm/ObjectForm.tsx";
|
|
2250
|
+
var createFieldMap = {
|
|
2251
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
2252
|
+
const handleChange = useCallback15((nextHue) => onValueChange(type, nextHue), [
|
|
2253
|
+
onValueChange,
|
|
2254
|
+
type
|
|
2255
|
+
]);
|
|
2256
|
+
const handleReset = useCallback15(() => onValueChange(type, void 0), [
|
|
2257
|
+
onValueChange,
|
|
2258
|
+
type
|
|
2259
|
+
]);
|
|
2260
|
+
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, layout !== "inline" && /* @__PURE__ */ React18.createElement(Form.Label, {
|
|
2261
|
+
label
|
|
2262
|
+
}), /* @__PURE__ */ React18.createElement(HuePicker2, {
|
|
2263
|
+
value: getValue(),
|
|
2264
|
+
onChange: handleChange,
|
|
2265
|
+
onReset: handleReset
|
|
2266
|
+
}));
|
|
2267
|
+
}
|
|
2148
2268
|
};
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2269
|
+
var ObjectForm = ({ object, schema }) => {
|
|
2270
|
+
const db = Obj4.getDatabase(object);
|
|
2271
|
+
const meta = Obj4.getMeta(object);
|
|
2272
|
+
const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN2.parse(tag))).filter(isNonNullable);
|
|
2273
|
+
const values = useMemo9(() => ({
|
|
2274
|
+
tags,
|
|
2275
|
+
...object
|
|
2276
|
+
}), [
|
|
2277
|
+
object,
|
|
2278
|
+
tags
|
|
2279
|
+
]);
|
|
2280
|
+
const formSchema = useMemo9(() => omitId(Schema3.Struct({
|
|
2281
|
+
tags: Schema3.Array(Ref4.Ref(Tag2.Tag)).pipe(Schema3.optional)
|
|
2282
|
+
}).pipe(Schema3.extend(schema))), [
|
|
2283
|
+
schema
|
|
2284
|
+
]);
|
|
2285
|
+
const handleCreate = useCallback15((schema2, values2) => {
|
|
2286
|
+
invariant(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 49, S: void 0, A: ["db", ""] });
|
|
2287
|
+
invariant(Type2.isObjectSchema(schema2), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 50, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
|
|
2288
|
+
const newObject = db.add(Obj4.make(schema2, values2));
|
|
2289
|
+
if (Obj4.instanceOf(Tag2.Tag, newObject)) {
|
|
2290
|
+
Obj4.update(object, (object2) => {
|
|
2291
|
+
Obj4.getMeta(object2).tags = [
|
|
2292
|
+
...Obj4.getMeta(object2).tags ?? [],
|
|
2293
|
+
Obj4.getDXN(newObject).toString()
|
|
2294
|
+
];
|
|
2295
|
+
});
|
|
2296
|
+
}
|
|
2297
|
+
}, []);
|
|
2298
|
+
const handleChange = useCallback15(({ tags: tags2, ...values2 }, { isValid, changed }) => {
|
|
2299
|
+
if (!isValid) {
|
|
2300
|
+
return;
|
|
2301
|
+
}
|
|
2302
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
2303
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath(path)[0] === "tags");
|
|
2304
|
+
if (hasTagsChange) {
|
|
2305
|
+
Obj4.update(object, (object2) => {
|
|
2306
|
+
Obj4.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
|
|
2307
|
+
});
|
|
2308
|
+
}
|
|
2309
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath(path)[0] !== "tags");
|
|
2310
|
+
if (nonTagPaths.length > 0) {
|
|
2311
|
+
Obj4.update(object, () => {
|
|
2312
|
+
for (const path of nonTagPaths) {
|
|
2313
|
+
const parts = splitJsonPath(path);
|
|
2314
|
+
const value3 = Obj4.getValue(values2, parts);
|
|
2315
|
+
Obj4.setValue(object, parts, value3);
|
|
2316
|
+
}
|
|
2317
|
+
});
|
|
2318
|
+
}
|
|
2319
|
+
}, [
|
|
2320
|
+
object
|
|
2321
|
+
]);
|
|
2322
|
+
return /* @__PURE__ */ React18.createElement(Form.Root, {
|
|
2323
|
+
schema: formSchema,
|
|
2324
|
+
defaultValues: values,
|
|
2325
|
+
createTypename: Type2.getTypename(Tag2.Tag),
|
|
2326
|
+
createOptionIcon: "ph--plus--regular",
|
|
2327
|
+
createOptionLabel: [
|
|
2328
|
+
"add-tag.label",
|
|
2329
|
+
{
|
|
2330
|
+
ns: translationKey10
|
|
2331
|
+
}
|
|
2332
|
+
],
|
|
2333
|
+
createInitialValuePath: "label",
|
|
2334
|
+
createFieldMap,
|
|
2335
|
+
db,
|
|
2336
|
+
onValuesChanged: handleChange,
|
|
2337
|
+
onCreate: handleCreate
|
|
2338
|
+
}, /* @__PURE__ */ React18.createElement(Form.Viewport, null, /* @__PURE__ */ React18.createElement(Form.Content, null, /* @__PURE__ */ React18.createElement(Form.FieldSet, null))));
|
|
2158
2339
|
};
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
}
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2340
|
+
|
|
2341
|
+
// src/components/ObjectProperties/ObjectProperties.tsx
|
|
2342
|
+
import * as Function from "effect/Function";
|
|
2343
|
+
import * as Option5 from "effect/Option";
|
|
2344
|
+
import * as Schema4 from "effect/Schema";
|
|
2345
|
+
import React19, { useCallback as useCallback16, useMemo as useMemo10 } from "react";
|
|
2346
|
+
import { DXN as DXN3, Obj as Obj5, Ref as Ref5, Tag as Tag3, Type as Type3 } from "@dxos/echo";
|
|
2347
|
+
import { splitJsonPath as splitJsonPath2 } from "@dxos/echo/internal";
|
|
2348
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2349
|
+
import { HuePicker as HuePicker3 } from "@dxos/react-ui-pickers";
|
|
2350
|
+
import { FactoryAnnotation } from "@dxos/schema";
|
|
2351
|
+
import { composable as composable2, composableProps as composableProps2 } from "@dxos/ui-theme";
|
|
2352
|
+
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
2353
|
+
import { translationKey as translationKey11 } from "#translations";
|
|
2354
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectProperties/ObjectProperties.tsx";
|
|
2355
|
+
var ObjectProperties = composable2(({ children, object, ...props }, forwardedRef) => {
|
|
2356
|
+
const db = Obj5.getDatabase(object);
|
|
2357
|
+
const meta = Obj5.getMeta(object);
|
|
2358
|
+
const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN3.parse(tag))).filter(isNonNullable2);
|
|
2359
|
+
const values = useMemo10(() => ({
|
|
2360
|
+
tags,
|
|
2361
|
+
...object
|
|
2362
|
+
}), [
|
|
2363
|
+
object,
|
|
2364
|
+
tags
|
|
2365
|
+
]);
|
|
2366
|
+
const formSchema = useMemo10(() => {
|
|
2367
|
+
return Function.pipe(Obj5.getSchema(object), Option5.fromNullable, Option5.map((schema) => omitId(BaseSchema.pipe(Schema4.extend(schema)))), Option5.getOrUndefined);
|
|
2368
|
+
}, [
|
|
2369
|
+
object
|
|
2370
|
+
]);
|
|
2371
|
+
const handleCreate = useCallback16((schema, values2) => {
|
|
2372
|
+
invariant2(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 45, S: void 0, A: ["db", ""] });
|
|
2373
|
+
invariant2(Type3.isObjectSchema(schema), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 46, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
|
|
2374
|
+
const factory = Option5.getOrUndefined(FactoryAnnotation.get(schema));
|
|
2375
|
+
const newObject = factory ? factory(values2) : Obj5.make(schema, values2);
|
|
2376
|
+
return db.add(newObject);
|
|
2377
|
+
}, [
|
|
2378
|
+
db
|
|
2379
|
+
]);
|
|
2380
|
+
const handleChange = useCallback16(({ tags: tags2, ...values2 }, { isValid, changed }) => {
|
|
2381
|
+
if (!isValid) {
|
|
2382
|
+
return;
|
|
2383
|
+
}
|
|
2384
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
2385
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath2(path)[0] === "tags");
|
|
2386
|
+
if (hasTagsChange) {
|
|
2387
|
+
Obj5.update(object, (object2) => {
|
|
2388
|
+
Obj5.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
|
|
2389
|
+
});
|
|
2390
|
+
}
|
|
2391
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath2(path)[0] !== "tags");
|
|
2392
|
+
if (nonTagPaths.length > 0) {
|
|
2393
|
+
Obj5.update(object, () => {
|
|
2394
|
+
for (const path of nonTagPaths) {
|
|
2395
|
+
const parts = splitJsonPath2(path);
|
|
2396
|
+
const value3 = Obj5.getValue(values2, parts);
|
|
2397
|
+
Obj5.setValue(object, parts, value3);
|
|
2398
|
+
}
|
|
2399
|
+
});
|
|
2400
|
+
}
|
|
2401
|
+
}, [
|
|
2402
|
+
object
|
|
2403
|
+
]);
|
|
2404
|
+
if (!formSchema) {
|
|
2405
|
+
return null;
|
|
2406
|
+
}
|
|
2407
|
+
return /* @__PURE__ */ React19.createElement(Form.Root, {
|
|
2408
|
+
schema: formSchema,
|
|
2409
|
+
defaultValues: values,
|
|
2410
|
+
createTypename: Type3.getTypename(Tag3.Tag),
|
|
2411
|
+
createOptionIcon: "ph--plus--regular",
|
|
2412
|
+
createOptionLabel: [
|
|
2413
|
+
"add-tag.label",
|
|
2414
|
+
{
|
|
2415
|
+
ns: translationKey11
|
|
2416
|
+
}
|
|
2417
|
+
],
|
|
2418
|
+
createInitialValuePath: "label",
|
|
2419
|
+
createFieldMap: createFieldMap2,
|
|
2420
|
+
db,
|
|
2421
|
+
onValuesChanged: handleChange,
|
|
2422
|
+
onCreate: handleCreate
|
|
2423
|
+
}, /* @__PURE__ */ React19.createElement(Form.Viewport, {
|
|
2424
|
+
...composableProps2(props),
|
|
2425
|
+
ref: forwardedRef
|
|
2426
|
+
}, /* @__PURE__ */ React19.createElement(Form.Content, null, /* @__PURE__ */ React19.createElement(Form.FieldSet, null), children)));
|
|
2427
|
+
});
|
|
2428
|
+
var createFieldMap2 = {
|
|
2429
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
2430
|
+
const handleChange = useCallback16((nextHue) => onValueChange(type, nextHue), [
|
|
2431
|
+
onValueChange,
|
|
2432
|
+
type
|
|
2433
|
+
]);
|
|
2434
|
+
const handleReset = useCallback16(() => onValueChange(type, void 0), [
|
|
2435
|
+
onValueChange,
|
|
2436
|
+
type
|
|
2437
|
+
]);
|
|
2438
|
+
return /* @__PURE__ */ React19.createElement(React19.Fragment, null, layout !== "inline" && /* @__PURE__ */ React19.createElement(Form.Label, {
|
|
2439
|
+
label
|
|
2440
|
+
}), /* @__PURE__ */ React19.createElement(HuePicker3, {
|
|
2441
|
+
value: getValue(),
|
|
2442
|
+
onChange: handleChange,
|
|
2443
|
+
onReset: handleReset
|
|
2444
|
+
}));
|
|
2445
|
+
}
|
|
2180
2446
|
};
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2447
|
+
var BaseSchema = Schema4.Struct({
|
|
2448
|
+
tags: Schema4.Array(Ref5.Ref(Tag3.Tag)).pipe(Schema4.optional)
|
|
2449
|
+
});
|
|
2450
|
+
|
|
2451
|
+
// src/components/Settings/Settings.tsx
|
|
2452
|
+
import React22 from "react";
|
|
2453
|
+
import { ScrollArea as ScrollArea2, toLocalizedString as toLocalizedString2, useTranslation as useTranslation11 } from "@dxos/react-ui";
|
|
2454
|
+
import { composable as composable3, composableProps as composableProps3, mx as mx4 } from "@dxos/ui-theme";
|
|
2455
|
+
import { translationKey as translationKey13 } from "#translations";
|
|
2456
|
+
|
|
2457
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
2458
|
+
import * as SchemaAST5 from "effect/SchemaAST";
|
|
2459
|
+
import * as String3 from "effect/String";
|
|
2460
|
+
import React21, { useCallback as useCallback17, useMemo as useMemo11 } from "react";
|
|
2461
|
+
import { getAnnotation as getAnnotation3 } from "@dxos/effect";
|
|
2462
|
+
import { Input as Input13, Select as Select2 } from "@dxos/react-ui";
|
|
2463
|
+
|
|
2464
|
+
// src/components/Settings/SettingsItem.tsx
|
|
2465
|
+
import React20 from "react";
|
|
2466
|
+
import { Input as Input12, toLocalizedString, useTranslation as useTranslation10 } from "@dxos/react-ui";
|
|
2467
|
+
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2468
|
+
import { translationKey as translationKey12 } from "#translations";
|
|
2469
|
+
var SETTINGS_PANEL_NAME = "Settings.Panel";
|
|
2470
|
+
var SETTINGS_ITEM_NAME = "Settings.Item";
|
|
2471
|
+
var SettingsPanel = ({ classNames, children }) => {
|
|
2472
|
+
return /* @__PURE__ */ React20.createElement("div", {
|
|
2473
|
+
className: mx3("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
|
|
2191
2474
|
}, children);
|
|
2192
2475
|
};
|
|
2193
|
-
|
|
2476
|
+
SettingsPanel.displayName = SETTINGS_PANEL_NAME;
|
|
2194
2477
|
var SettingsItem = ({ title, description = "", children }) => {
|
|
2195
|
-
const { t } =
|
|
2196
|
-
return /* @__PURE__ */
|
|
2197
|
-
classNames:
|
|
2198
|
-
}, /* @__PURE__ */
|
|
2199
|
-
|
|
2200
|
-
}, toLocalizedString(title, t)), /* @__PURE__ */
|
|
2201
|
-
|
|
2202
|
-
}, toLocalizedString(description, t)), /* @__PURE__ */
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
}, children));
|
|
2478
|
+
const { t } = useTranslation10(translationKey12);
|
|
2479
|
+
return /* @__PURE__ */ React20.createElement(Input12.Root, null, /* @__PURE__ */ React20.createElement(SettingsPanel, {
|
|
2480
|
+
classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
|
|
2481
|
+
}, /* @__PURE__ */ React20.createElement(Input12.Label, {
|
|
2482
|
+
classNames: "pb-trim-md text-base-surface-text text-lg md:col-span-2"
|
|
2483
|
+
}, toLocalizedString(title, t)), /* @__PURE__ */ React20.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React20.createElement(Input12.Description, {
|
|
2484
|
+
classNames: "text-base text-description"
|
|
2485
|
+
}, toLocalizedString(description, t))), /* @__PURE__ */ React20.createElement("div", {
|
|
2486
|
+
className: "text-end py-1"
|
|
2487
|
+
}, children)));
|
|
2206
2488
|
};
|
|
2207
2489
|
SettingsItem.displayName = SETTINGS_ITEM_NAME;
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2490
|
+
|
|
2491
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
2492
|
+
var SettingsFieldSet = ({ schema, values, onValuesChanged, readonly, fieldMap, visible, sort, pathPrefix = "" }) => {
|
|
2493
|
+
const properties = useMemo11(() => {
|
|
2494
|
+
const props = getFormProperties(schema.ast);
|
|
2495
|
+
if (!sort) {
|
|
2496
|
+
return props;
|
|
2497
|
+
}
|
|
2498
|
+
const rank = (name) => {
|
|
2499
|
+
const idx = sort.indexOf(name);
|
|
2500
|
+
return idx === -1 ? Number.POSITIVE_INFINITY : idx;
|
|
2501
|
+
};
|
|
2502
|
+
return [
|
|
2503
|
+
...props
|
|
2504
|
+
].sort(({ name: a }, { name: b }) => rank(a.toString()) - rank(b.toString()));
|
|
2505
|
+
}, [
|
|
2506
|
+
schema,
|
|
2507
|
+
sort
|
|
2508
|
+
]);
|
|
2509
|
+
const handleChange = useCallback17((name, value3) => {
|
|
2510
|
+
onValuesChanged?.({
|
|
2511
|
+
...values,
|
|
2512
|
+
[name]: value3
|
|
2513
|
+
});
|
|
2514
|
+
}, [
|
|
2515
|
+
values,
|
|
2516
|
+
onValuesChanged
|
|
2517
|
+
]);
|
|
2518
|
+
return /* @__PURE__ */ React21.createElement(React21.Fragment, null, properties.map((property) => {
|
|
2519
|
+
const name = property.name.toString();
|
|
2520
|
+
const path = pathPrefix ? `${pathPrefix}.${name}` : name;
|
|
2521
|
+
if (visible && !visible(path, values)) {
|
|
2522
|
+
return null;
|
|
2523
|
+
}
|
|
2524
|
+
const entry = fieldMap?.[name];
|
|
2525
|
+
return /* @__PURE__ */ React21.createElement(SettingsFieldItem, {
|
|
2526
|
+
key: name,
|
|
2527
|
+
path,
|
|
2528
|
+
property,
|
|
2529
|
+
value: values[name],
|
|
2530
|
+
onChange: (value3) => handleChange(name, value3),
|
|
2531
|
+
readonly,
|
|
2532
|
+
customField: typeof entry === "function" ? entry : void 0,
|
|
2533
|
+
nestedFieldMap: typeof entry === "object" ? entry : void 0,
|
|
2534
|
+
visible,
|
|
2535
|
+
sort
|
|
2536
|
+
});
|
|
2537
|
+
}));
|
|
2538
|
+
};
|
|
2539
|
+
SettingsFieldSet.displayName = "Settings.FieldSet";
|
|
2540
|
+
var SettingsFieldItem = ({ property, path, value: value3, onChange, readonly, customField, nestedFieldMap, visible, sort }) => {
|
|
2541
|
+
const { type } = property;
|
|
2542
|
+
const name = property.name.toString();
|
|
2543
|
+
const title = getAnnotation3(SchemaAST5.TitleAnnotationId)(type) ?? String3.capitalize(name);
|
|
2544
|
+
const description = getAnnotation3(SchemaAST5.DescriptionAnnotationId)(type);
|
|
2545
|
+
if (customField) {
|
|
2546
|
+
const CustomField = customField;
|
|
2547
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2548
|
+
title,
|
|
2549
|
+
description
|
|
2550
|
+
}, /* @__PURE__ */ React21.createElement(CustomField, {
|
|
2551
|
+
value: value3,
|
|
2552
|
+
onChange,
|
|
2553
|
+
readonly
|
|
2554
|
+
}));
|
|
2555
|
+
}
|
|
2556
|
+
const fieldType = detectFieldType(type);
|
|
2557
|
+
switch (fieldType) {
|
|
2558
|
+
case "struct":
|
|
2559
|
+
return /* @__PURE__ */ React21.createElement(SettingsFieldSet, {
|
|
2560
|
+
schema: {
|
|
2561
|
+
ast: type
|
|
2562
|
+
},
|
|
2563
|
+
values: value3 ?? {},
|
|
2564
|
+
onValuesChanged: onChange,
|
|
2565
|
+
readonly,
|
|
2566
|
+
fieldMap: nestedFieldMap,
|
|
2567
|
+
visible,
|
|
2568
|
+
sort,
|
|
2569
|
+
pathPrefix: path
|
|
2570
|
+
});
|
|
2571
|
+
case "boolean":
|
|
2572
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2573
|
+
title,
|
|
2574
|
+
description
|
|
2575
|
+
}, /* @__PURE__ */ React21.createElement(Input13.Switch, {
|
|
2576
|
+
disabled: readonly,
|
|
2577
|
+
checked: !!value3,
|
|
2578
|
+
onCheckedChange: (checked) => onChange(!!checked)
|
|
2579
|
+
}));
|
|
2580
|
+
case "select": {
|
|
2581
|
+
const options = getSelectOptionsFromAst(type) ?? [];
|
|
2582
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2583
|
+
title,
|
|
2584
|
+
description
|
|
2585
|
+
}, /* @__PURE__ */ React21.createElement(Select2.Root, {
|
|
2586
|
+
disabled: readonly,
|
|
2587
|
+
value: value3 == null ? "" : globalThis.String(value3),
|
|
2588
|
+
onValueChange: (selected) => {
|
|
2589
|
+
const matched = options.find((option) => globalThis.String(option.value) === selected);
|
|
2590
|
+
onChange(matched?.value ?? selected);
|
|
2591
|
+
}
|
|
2592
|
+
}, /* @__PURE__ */ React21.createElement(Select2.TriggerButton, {
|
|
2593
|
+
disabled: readonly
|
|
2594
|
+
}), /* @__PURE__ */ React21.createElement(Select2.Portal, null, /* @__PURE__ */ React21.createElement(Select2.Content, null, /* @__PURE__ */ React21.createElement(Select2.Viewport, null, options.map((option) => /* @__PURE__ */ React21.createElement(Select2.Option, {
|
|
2595
|
+
key: globalThis.String(option.value),
|
|
2596
|
+
value: globalThis.String(option.value)
|
|
2597
|
+
}, option.label ?? globalThis.String(option.value)))), /* @__PURE__ */ React21.createElement(Select2.Arrow, null)))));
|
|
2598
|
+
}
|
|
2599
|
+
case "string":
|
|
2600
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2601
|
+
title,
|
|
2602
|
+
description
|
|
2603
|
+
}, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
|
|
2604
|
+
disabled: readonly,
|
|
2605
|
+
value: value3 ?? "",
|
|
2606
|
+
onChange: (event) => onChange(event.target.value)
|
|
2607
|
+
}));
|
|
2608
|
+
case "number":
|
|
2609
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2610
|
+
title,
|
|
2611
|
+
description
|
|
2612
|
+
}, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
|
|
2613
|
+
disabled: readonly,
|
|
2614
|
+
type: "number",
|
|
2615
|
+
value: value3 ?? "",
|
|
2616
|
+
onChange: (event) => {
|
|
2617
|
+
if (event.target.value === "") {
|
|
2618
|
+
onChange(void 0);
|
|
2619
|
+
return;
|
|
2620
|
+
}
|
|
2621
|
+
const parsed = Number(event.target.value);
|
|
2622
|
+
onChange(Number.isNaN(parsed) ? void 0 : parsed);
|
|
2623
|
+
}
|
|
2624
|
+
}));
|
|
2625
|
+
default:
|
|
2626
|
+
return null;
|
|
2627
|
+
}
|
|
2628
|
+
};
|
|
2629
|
+
|
|
2630
|
+
// src/components/Settings/Settings.tsx
|
|
2631
|
+
var SETTINGS_ROOT_NAME = "Settings.Root";
|
|
2632
|
+
var SETTINGS_VIEWPORT_NAME = "Settings.Viewport";
|
|
2633
|
+
var SETTINGS_SECTION_NAME = "Settings.Section";
|
|
2634
|
+
var SettingsRoot = ({ children, classNames }) => {
|
|
2635
|
+
return /* @__PURE__ */ React22.createElement("div", {
|
|
2636
|
+
className: mx4("flex flex-col gap-2", classNames)
|
|
2637
|
+
}, children);
|
|
2638
|
+
};
|
|
2639
|
+
SettingsRoot.displayName = SETTINGS_ROOT_NAME;
|
|
2640
|
+
var SettingsViewport = composable3(({ children, ...props }, forwardedRef) => {
|
|
2641
|
+
return /* @__PURE__ */ React22.createElement(ScrollArea2.Root, {
|
|
2642
|
+
...composableProps3(props),
|
|
2643
|
+
orientation: "vertical",
|
|
2644
|
+
centered: true,
|
|
2645
|
+
thin: true,
|
|
2646
|
+
ref: forwardedRef
|
|
2647
|
+
}, /* @__PURE__ */ React22.createElement(ScrollArea2.Viewport, {
|
|
2648
|
+
classNames: "px-4 pointer-coarse:px-2"
|
|
2649
|
+
}, /* @__PURE__ */ React22.createElement("div", {
|
|
2650
|
+
className: "dx-document flex flex-col gap-2 py-4"
|
|
2219
2651
|
}, children)));
|
|
2652
|
+
});
|
|
2653
|
+
SettingsViewport.displayName = SETTINGS_VIEWPORT_NAME;
|
|
2654
|
+
var SettingsSection = ({ title, description, children }) => {
|
|
2655
|
+
const { t } = useTranslation11(translationKey13);
|
|
2656
|
+
return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("h2", {
|
|
2657
|
+
className: "px-trim-md mt-trim-md text-xl"
|
|
2658
|
+
}, toLocalizedString2(title, t)), description && /* @__PURE__ */ React22.createElement("p", {
|
|
2659
|
+
className: "px-trim-md text-description"
|
|
2660
|
+
}, toLocalizedString2(description, t)), /* @__PURE__ */ React22.createElement("div", {
|
|
2661
|
+
className: "w-full pt-trim-md space-y-trim-md"
|
|
2662
|
+
}, children));
|
|
2220
2663
|
};
|
|
2221
|
-
|
|
2664
|
+
SettingsSection.displayName = SETTINGS_SECTION_NAME;
|
|
2222
2665
|
var Settings = {
|
|
2223
2666
|
Root: SettingsRoot,
|
|
2667
|
+
Viewport: SettingsViewport,
|
|
2224
2668
|
Section: SettingsSection,
|
|
2225
|
-
|
|
2226
|
-
Group: SettingsGroup,
|
|
2227
|
-
GroupButton: SettingsGroupButton,
|
|
2228
|
-
Container: SettingsContainer,
|
|
2229
|
-
Frame: SettingsFrame,
|
|
2230
|
-
FrameItem: SettingsFrameItem,
|
|
2669
|
+
Panel: SettingsPanel,
|
|
2231
2670
|
Item: SettingsItem,
|
|
2232
|
-
|
|
2671
|
+
FieldSet: SettingsFieldSet
|
|
2672
|
+
};
|
|
2673
|
+
|
|
2674
|
+
// src/components/Settings/SettingsSelectField.tsx
|
|
2675
|
+
import React23 from "react";
|
|
2676
|
+
import { Select as Select3 } from "@dxos/react-ui";
|
|
2677
|
+
var createSelectField = ({ options, defaultLabel = "Default" }) => {
|
|
2678
|
+
const normalized = options.map((option) => typeof option === "string" ? {
|
|
2679
|
+
value: option,
|
|
2680
|
+
label: option
|
|
2681
|
+
} : option);
|
|
2682
|
+
const hasDefault = defaultLabel !== null;
|
|
2683
|
+
const sentinel = hasDefault ? `__default__${Math.random().toString(36).slice(2)}` : "";
|
|
2684
|
+
return ({ value: value3, onChange, readonly }) => /* @__PURE__ */ React23.createElement(Select3.Root, {
|
|
2685
|
+
disabled: readonly,
|
|
2686
|
+
value: value3 ?? sentinel,
|
|
2687
|
+
onValueChange: (next) => onChange(hasDefault && next === sentinel ? void 0 : next)
|
|
2688
|
+
}, /* @__PURE__ */ React23.createElement(Select3.TriggerButton, {
|
|
2689
|
+
disabled: readonly
|
|
2690
|
+
}), /* @__PURE__ */ React23.createElement(Select3.Portal, null, /* @__PURE__ */ React23.createElement(Select3.Content, null, /* @__PURE__ */ React23.createElement(Select3.Viewport, null, hasDefault && /* @__PURE__ */ React23.createElement(Select3.Option, {
|
|
2691
|
+
value: sentinel
|
|
2692
|
+
}, defaultLabel), normalized.map((option) => /* @__PURE__ */ React23.createElement(Select3.Option, {
|
|
2693
|
+
key: option.value,
|
|
2694
|
+
value: option.value
|
|
2695
|
+
}, option.label ?? option.value))), /* @__PURE__ */ React23.createElement(Select3.Arrow, null))));
|
|
2233
2696
|
};
|
|
2234
2697
|
|
|
2235
2698
|
// src/components/ViewEditor/ViewEditor.tsx
|
|
2236
2699
|
import { RegistryContext } from "@effect-atom/atom-react";
|
|
2237
|
-
import * as
|
|
2700
|
+
import * as Array4 from "effect/Array";
|
|
2238
2701
|
import * as Match2 from "effect/Match";
|
|
2239
|
-
import * as
|
|
2240
|
-
import * as
|
|
2241
|
-
import
|
|
2242
|
-
import { Filter as Filter2, Format as Format5, Obj as
|
|
2702
|
+
import * as Option6 from "effect/Option";
|
|
2703
|
+
import * as Schema5 from "effect/Schema";
|
|
2704
|
+
import React24, { forwardRef as forwardRef2, useCallback as useCallback18, useContext, useImperativeHandle, useMemo as useMemo12, useState as useState7 } from "react";
|
|
2705
|
+
import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as Obj6, Query, QueryAST, Ref as Ref6 } from "@dxos/echo";
|
|
2706
|
+
import { View } from "@dxos/echo";
|
|
2243
2707
|
import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
|
|
2244
|
-
import { invariant } from "@dxos/invariant";
|
|
2245
|
-
import { useObject } from "@dxos/react-client/echo";
|
|
2246
|
-
import {
|
|
2708
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
2709
|
+
import { useObject, useQuery as useQuery2 } from "@dxos/react-client/echo";
|
|
2710
|
+
import { IconButton as IconButton4, Input as Input14, Message, useTranslation as useTranslation12 } from "@dxos/react-ui";
|
|
2247
2711
|
import { QueryForm } from "@dxos/react-ui-components";
|
|
2248
2712
|
import { List as List2 } from "@dxos/react-ui-list";
|
|
2249
|
-
import {
|
|
2250
|
-
import { mx as
|
|
2251
|
-
|
|
2252
|
-
var
|
|
2253
|
-
var
|
|
2254
|
-
var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode = "schema", registry, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
|
|
2713
|
+
import { ParentLabelAnnotation, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
|
|
2714
|
+
import { mx as mx5, osTranslations as osTranslations2, subtleHover as subtleHover2 } from "@dxos/ui-theme";
|
|
2715
|
+
import { translationKey as translationKey14 } from "#translations";
|
|
2716
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
|
|
2717
|
+
var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
|
|
2255
2718
|
const atomRegistry = useContext(RegistryContext);
|
|
2256
2719
|
const schemaReadonly = !isMutable(schema);
|
|
2257
|
-
const { t } =
|
|
2258
|
-
const projectionModel =
|
|
2720
|
+
const { t } = useTranslation12(translationKey14);
|
|
2721
|
+
const projectionModel = useMemo12(() => {
|
|
2259
2722
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2260
2723
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2261
2724
|
const model = new ProjectionModel({
|
|
@@ -2274,12 +2737,26 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2274
2737
|
projectionModel
|
|
2275
2738
|
]);
|
|
2276
2739
|
const queueTarget = Match2.value(view.query.ast).pipe(Match2.when({
|
|
2277
|
-
type: "
|
|
2278
|
-
}, ({
|
|
2279
|
-
|
|
2740
|
+
type: "from"
|
|
2741
|
+
}, ({ from }) => {
|
|
2742
|
+
if (from._tag !== "scope") {
|
|
2743
|
+
return void 0;
|
|
2744
|
+
}
|
|
2745
|
+
return Option6.fromNullable(from.scope.queues).pipe(Option6.flatMap((queues) => Array4.head(queues)), Option6.map(String), Option6.getOrUndefined);
|
|
2280
2746
|
}), Match2.orElse(() => void 0));
|
|
2281
|
-
const
|
|
2282
|
-
|
|
2747
|
+
const feeds = useQuery2(db, Filter2.type(Feed.Feed));
|
|
2748
|
+
const targetRef = useMemo12(() => {
|
|
2749
|
+
if (!queueTarget) {
|
|
2750
|
+
return void 0;
|
|
2751
|
+
}
|
|
2752
|
+
const feed = feeds.find((feed2) => Feed.getQueueDxn(feed2)?.toString() === queueTarget);
|
|
2753
|
+
return feed ? Ref6.fromDXN(Entity2.getDXN(feed)) : void 0;
|
|
2754
|
+
}, [
|
|
2755
|
+
queueTarget,
|
|
2756
|
+
feeds
|
|
2757
|
+
]);
|
|
2758
|
+
const viewSchema = useMemo12(() => {
|
|
2759
|
+
const base = Schema5.Struct({
|
|
2283
2760
|
query: mode === "schema" ? Format5.URL.annotations({
|
|
2284
2761
|
title: "Record type"
|
|
2285
2762
|
}) : QueryAST.Query.annotations({
|
|
@@ -2287,26 +2764,27 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2287
2764
|
})
|
|
2288
2765
|
});
|
|
2289
2766
|
if (mode === "tag") {
|
|
2290
|
-
return
|
|
2767
|
+
return Schema5.Struct({
|
|
2291
2768
|
...base.fields,
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2769
|
+
// TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
|
|
2770
|
+
target: Ref6.Ref(Feed.Feed).pipe(Schema5.annotations({
|
|
2771
|
+
title: "Target Feed"
|
|
2772
|
+
}), ParentLabelAnnotation.set(true), Schema5.optional)
|
|
2773
|
+
}).pipe(Schema5.mutable);
|
|
2296
2774
|
}
|
|
2297
|
-
return base.pipe(
|
|
2775
|
+
return base.pipe(Schema5.mutable);
|
|
2298
2776
|
}, [
|
|
2299
2777
|
mode
|
|
2300
2778
|
]);
|
|
2301
|
-
const viewValues =
|
|
2779
|
+
const viewValues = useMemo12(() => ({
|
|
2302
2780
|
query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
|
|
2303
|
-
target:
|
|
2781
|
+
target: targetRef
|
|
2304
2782
|
}), [
|
|
2305
2783
|
mode,
|
|
2306
2784
|
view.query.ast,
|
|
2307
|
-
|
|
2785
|
+
targetRef
|
|
2308
2786
|
]);
|
|
2309
|
-
const fieldMap =
|
|
2787
|
+
const fieldMap = useMemo12(() => mode === "tag" ? customFields({
|
|
2310
2788
|
types,
|
|
2311
2789
|
tags
|
|
2312
2790
|
}) : void 0, [
|
|
@@ -2314,48 +2792,45 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2314
2792
|
types,
|
|
2315
2793
|
tags
|
|
2316
2794
|
]);
|
|
2317
|
-
const handleUpdate =
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2795
|
+
const handleUpdate = useCallback18((values) => {
|
|
2796
|
+
const targetValue = values.target;
|
|
2797
|
+
let queueDxn;
|
|
2798
|
+
if (Ref6.isRef(targetValue)) {
|
|
2799
|
+
const feedDxn = targetValue.dxn.toString();
|
|
2800
|
+
const feed = feeds.find((feed2) => Obj6.getDXN(feed2).toString() === feedDxn);
|
|
2801
|
+
if (feed) {
|
|
2802
|
+
queueDxn = Feed.getQueueDxn(feed)?.toString();
|
|
2803
|
+
}
|
|
2804
|
+
}
|
|
2805
|
+
const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : JSON.parse(JSON.stringify(values.query));
|
|
2806
|
+
onQueryChanged?.(query, queueDxn);
|
|
2322
2807
|
}, [
|
|
2323
2808
|
onQueryChanged,
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
mode
|
|
2809
|
+
mode,
|
|
2810
|
+
feeds
|
|
2327
2811
|
]);
|
|
2328
|
-
const handleDelete =
|
|
2329
|
-
|
|
2330
|
-
F: __dxlog_file3,
|
|
2331
|
-
L: 155,
|
|
2332
|
-
S: void 0,
|
|
2333
|
-
A: [
|
|
2334
|
-
"!readonly",
|
|
2335
|
-
""
|
|
2336
|
-
]
|
|
2337
|
-
});
|
|
2812
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2813
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 127, S: void 0, A: ["!readonly", ""] });
|
|
2338
2814
|
onDelete?.(fieldId);
|
|
2339
2815
|
}, [
|
|
2340
2816
|
onDelete,
|
|
2341
2817
|
readonly
|
|
2342
2818
|
]);
|
|
2343
|
-
return /* @__PURE__ */
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
}, schemaReadonly && !readonly && /* @__PURE__ */ React19.createElement(Callout.Root, {
|
|
2819
|
+
return /* @__PURE__ */ React24.createElement("div", {
|
|
2820
|
+
className: mx5(classNames)
|
|
2821
|
+
}, schemaReadonly && !readonly && /* @__PURE__ */ React24.createElement(Message.Root, {
|
|
2347
2822
|
valence: "info",
|
|
2348
|
-
classNames: "
|
|
2349
|
-
}, /* @__PURE__ */
|
|
2823
|
+
classNames: "my-form-padding"
|
|
2824
|
+
}, /* @__PURE__ */ React24.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React24.createElement(Form.Root, {
|
|
2350
2825
|
schema: viewSchema,
|
|
2351
2826
|
values: viewValues,
|
|
2352
2827
|
fieldMap,
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
}, /* @__PURE__ */
|
|
2356
|
-
label: t("fields
|
|
2828
|
+
db,
|
|
2829
|
+
onValuesChanged: handleUpdate
|
|
2830
|
+
}, /* @__PURE__ */ React24.createElement(Form.FieldSet, null), /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2831
|
+
label: t("fields.label"),
|
|
2357
2832
|
asChild: true
|
|
2358
|
-
}), /* @__PURE__ */
|
|
2833
|
+
}), /* @__PURE__ */ React24.createElement(FieldList, {
|
|
2359
2834
|
schema,
|
|
2360
2835
|
view,
|
|
2361
2836
|
registry,
|
|
@@ -2367,9 +2842,9 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2367
2842
|
var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDelete }) => {
|
|
2368
2843
|
const atomRegistry = useContext(RegistryContext);
|
|
2369
2844
|
const schemaReadonly = !isMutable(schema);
|
|
2370
|
-
const { t } =
|
|
2845
|
+
const { t } = useTranslation12(translationKey14);
|
|
2371
2846
|
const [viewSnapshot] = useObject(view);
|
|
2372
|
-
const projectionModel =
|
|
2847
|
+
const projectionModel = useMemo12(() => {
|
|
2373
2848
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2374
2849
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2375
2850
|
const model = new ProjectionModel({
|
|
@@ -2384,38 +2859,22 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2384
2859
|
schema,
|
|
2385
2860
|
view
|
|
2386
2861
|
]);
|
|
2387
|
-
const [expandedField, setExpandedField] =
|
|
2388
|
-
const handleAdd =
|
|
2389
|
-
|
|
2390
|
-
F: __dxlog_file3,
|
|
2391
|
-
L: 220,
|
|
2392
|
-
S: void 0,
|
|
2393
|
-
A: [
|
|
2394
|
-
"!readonly",
|
|
2395
|
-
""
|
|
2396
|
-
]
|
|
2397
|
-
});
|
|
2862
|
+
const [expandedField, setExpandedField] = useState7();
|
|
2863
|
+
const handleAdd = useCallback18(() => {
|
|
2864
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 182, S: void 0, A: ["!readonly", ""] });
|
|
2398
2865
|
const field = projectionModel.createFieldProjection();
|
|
2399
2866
|
setExpandedField(field.id);
|
|
2400
2867
|
}, [
|
|
2401
2868
|
projectionModel,
|
|
2402
2869
|
readonly
|
|
2403
2870
|
]);
|
|
2404
|
-
const handleToggleField =
|
|
2871
|
+
const handleToggleField = useCallback18((field) => {
|
|
2405
2872
|
setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
|
|
2406
2873
|
}, [
|
|
2407
2874
|
readonly
|
|
2408
2875
|
]);
|
|
2409
|
-
const handleDelete =
|
|
2410
|
-
|
|
2411
|
-
F: __dxlog_file3,
|
|
2412
|
-
L: 234,
|
|
2413
|
-
S: void 0,
|
|
2414
|
-
A: [
|
|
2415
|
-
"!readonly",
|
|
2416
|
-
""
|
|
2417
|
-
]
|
|
2418
|
-
});
|
|
2876
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2877
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 195, S: void 0, A: ["!readonly", ""] });
|
|
2419
2878
|
if (fieldId === expandedField) {
|
|
2420
2879
|
setExpandedField(void 0);
|
|
2421
2880
|
}
|
|
@@ -2425,36 +2884,28 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2425
2884
|
onDelete,
|
|
2426
2885
|
readonly
|
|
2427
2886
|
]);
|
|
2428
|
-
const handleMove =
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
L: 246,
|
|
2432
|
-
S: void 0,
|
|
2433
|
-
A: [
|
|
2434
|
-
"!readonly",
|
|
2435
|
-
""
|
|
2436
|
-
]
|
|
2437
|
-
});
|
|
2438
|
-
Obj4.change(view, (v) => {
|
|
2887
|
+
const handleMove = useCallback18((fromIndex, toIndex) => {
|
|
2888
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 206, S: void 0, A: ["!readonly", ""] });
|
|
2889
|
+
Obj6.update(view, (view2) => {
|
|
2439
2890
|
const fields = [
|
|
2440
|
-
...
|
|
2891
|
+
...view2.projection.fields
|
|
2441
2892
|
];
|
|
2442
2893
|
const [moved] = fields.splice(fromIndex, 1);
|
|
2443
2894
|
fields.splice(toIndex, 0, moved);
|
|
2444
|
-
|
|
2895
|
+
view2.projection.fields = fields;
|
|
2445
2896
|
});
|
|
2446
2897
|
}, [
|
|
2447
2898
|
view,
|
|
2448
2899
|
readonly
|
|
2449
2900
|
]);
|
|
2450
|
-
const handleClose =
|
|
2451
|
-
const handleHide =
|
|
2901
|
+
const handleClose = useCallback18(() => setExpandedField(void 0), []);
|
|
2902
|
+
const handleHide = useCallback18((fieldId) => {
|
|
2452
2903
|
setExpandedField(void 0);
|
|
2453
2904
|
projectionModel.hideFieldProjection(fieldId);
|
|
2454
2905
|
}, [
|
|
2455
2906
|
projectionModel
|
|
2456
2907
|
]);
|
|
2457
|
-
const handleShow =
|
|
2908
|
+
const handleShow = useCallback18((property) => {
|
|
2458
2909
|
setExpandedField(void 0);
|
|
2459
2910
|
projectionModel.showFieldProjection(property);
|
|
2460
2911
|
}, [
|
|
@@ -2463,84 +2914,81 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2463
2914
|
if (!viewSnapshot) {
|
|
2464
2915
|
return null;
|
|
2465
2916
|
}
|
|
2466
|
-
return /* @__PURE__ */
|
|
2917
|
+
return /* @__PURE__ */ React24.createElement(List2.Root, {
|
|
2467
2918
|
items: viewSnapshot.projection.fields,
|
|
2468
|
-
isItem:
|
|
2919
|
+
isItem: Schema5.is(View.FieldSchema),
|
|
2469
2920
|
getId: (field) => field.id,
|
|
2470
2921
|
onMove: readonly ? void 0 : handleMove,
|
|
2471
2922
|
readonly
|
|
2472
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
2923
|
+
}, ({ items: fields }) => /* @__PURE__ */ React24.createElement(React24.Fragment, null, showHeading && /* @__PURE__ */ React24.createElement("h3", {
|
|
2473
2924
|
className: "text-sm"
|
|
2474
|
-
}, t("field
|
|
2925
|
+
}, t("field-path.label")), /* @__PURE__ */ React24.createElement("div", {
|
|
2475
2926
|
role: "list",
|
|
2476
|
-
className:
|
|
2927
|
+
className: "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]"
|
|
2477
2928
|
}, fields?.map((field) => {
|
|
2478
2929
|
const hidden = field.visible === false;
|
|
2479
|
-
return /* @__PURE__ */
|
|
2930
|
+
return /* @__PURE__ */ React24.createElement(List2.Item, {
|
|
2480
2931
|
key: field.id,
|
|
2481
2932
|
item: field,
|
|
2482
|
-
classNames:
|
|
2933
|
+
classNames: "grid grid-cols-subgrid col-span-5",
|
|
2483
2934
|
"aria-expanded": expandedField === field.id
|
|
2484
|
-
}, /* @__PURE__ */
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
}, /* @__PURE__ */ React19.createElement(List2.ItemDragHandle, {
|
|
2935
|
+
}, /* @__PURE__ */ React24.createElement("div", {
|
|
2936
|
+
className: mx5(subtleHover2, "grid grid-cols-subgrid col-span-5", "rounded-xs cursor-pointer min-h-10")
|
|
2937
|
+
}, /* @__PURE__ */ React24.createElement(List2.ItemDragHandle, {
|
|
2488
2938
|
disabled: readonly || schemaReadonly
|
|
2489
|
-
}), /* @__PURE__ */
|
|
2939
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemTitle, {
|
|
2490
2940
|
classNames: hidden && "text-subdued",
|
|
2491
2941
|
onClick: () => handleToggleField(field)
|
|
2492
|
-
}, field.path), /* @__PURE__ */
|
|
2493
|
-
label: t(hidden ? "show
|
|
2942
|
+
}, field.path), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2943
|
+
label: t(hidden ? "show-field.label" : "hide-field.label"),
|
|
2494
2944
|
"data-testid": hidden ? "show-field-button" : "hide-field-button",
|
|
2495
2945
|
icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
|
|
2496
2946
|
autoHide: false,
|
|
2497
2947
|
disabled: readonly || !hidden && projectionModel.getFields().length <= 1,
|
|
2498
2948
|
onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
|
|
2499
|
-
}), !readonly && /* @__PURE__ */
|
|
2500
|
-
label: t("delete
|
|
2949
|
+
}), !readonly && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(List2.ItemDeleteButton, {
|
|
2950
|
+
label: t("delete-field.label"),
|
|
2501
2951
|
autoHide: false,
|
|
2502
2952
|
disabled: readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1,
|
|
2503
2953
|
onClick: () => handleDelete(field.id),
|
|
2504
2954
|
"data-testid": "field.delete"
|
|
2505
|
-
}), /* @__PURE__ */
|
|
2955
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2506
2956
|
iconOnly: true,
|
|
2507
2957
|
variant: "ghost",
|
|
2508
|
-
label: t("toggle
|
|
2958
|
+
label: t("toggle-expand.label", {
|
|
2509
2959
|
ns: osTranslations2
|
|
2510
2960
|
}),
|
|
2511
2961
|
icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
2512
2962
|
onClick: () => handleToggleField(field),
|
|
2513
2963
|
"data-testid": "field.toggle"
|
|
2514
|
-
}))), expandedField === field.id && !readonly && /* @__PURE__ */
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
}, /* @__PURE__ */ React19.createElement(FieldEditor, {
|
|
2964
|
+
}))), expandedField === field.id && !readonly && /* @__PURE__ */ React24.createElement("div", {
|
|
2965
|
+
className: "col-span-full mt-1 mb-1 border border-separator rounded-md"
|
|
2966
|
+
}, /* @__PURE__ */ React24.createElement(FieldEditor, {
|
|
2518
2967
|
readonly: readonly || schemaReadonly,
|
|
2519
2968
|
registry,
|
|
2520
2969
|
projection: projectionModel,
|
|
2521
2970
|
field,
|
|
2522
2971
|
onSave: handleClose
|
|
2523
2972
|
})));
|
|
2524
|
-
})), !readonly && !expandedField && /* @__PURE__ */
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
}, /* @__PURE__ */ React19.createElement(IconButton4, {
|
|
2973
|
+
})), !readonly && !expandedField && /* @__PURE__ */ React24.createElement("div", {
|
|
2974
|
+
className: "my-form-padding"
|
|
2975
|
+
}, /* @__PURE__ */ React24.createElement(IconButton4, {
|
|
2528
2976
|
icon: "ph--plus--regular",
|
|
2529
|
-
label: t("add
|
|
2977
|
+
label: t("add-property-button.label"),
|
|
2530
2978
|
onClick: handleAdd,
|
|
2531
2979
|
disabled: viewSnapshot.projection.fields.length >= VIEW_FIELD_LIMIT,
|
|
2532
|
-
classNames: "
|
|
2980
|
+
classNames: "w-full"
|
|
2533
2981
|
}))));
|
|
2534
2982
|
};
|
|
2535
2983
|
var customFields = ({ types, tags }) => ({
|
|
2536
2984
|
query: ({ type, readonly, label, getValue, onValueChange }) => {
|
|
2537
|
-
const handleChange =
|
|
2985
|
+
const handleChange = useCallback18((query) => onValueChange(type, query.ast), [
|
|
2538
2986
|
onValueChange
|
|
2539
2987
|
]);
|
|
2540
|
-
return /* @__PURE__ */
|
|
2988
|
+
return /* @__PURE__ */ React24.createElement(Input14.Root, null, /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2541
2989
|
readonly,
|
|
2542
2990
|
label
|
|
2543
|
-
}), /* @__PURE__ */
|
|
2991
|
+
}), /* @__PURE__ */ React24.createElement(QueryForm, {
|
|
2544
2992
|
initialQuery: getValue(),
|
|
2545
2993
|
types,
|
|
2546
2994
|
tags,
|
|
@@ -2559,7 +3007,9 @@ export {
|
|
|
2559
3007
|
GeoPointField,
|
|
2560
3008
|
MarkdownField,
|
|
2561
3009
|
NumberField,
|
|
3010
|
+
ObjectForm,
|
|
2562
3011
|
ObjectPicker,
|
|
3012
|
+
ObjectProperties,
|
|
2563
3013
|
RefField,
|
|
2564
3014
|
SelectField,
|
|
2565
3015
|
SelectOptionField,
|
|
@@ -2569,16 +3019,18 @@ export {
|
|
|
2569
3019
|
TupleField,
|
|
2570
3020
|
ViewEditor,
|
|
2571
3021
|
cellClassesForFieldType,
|
|
3022
|
+
createSelectField,
|
|
3023
|
+
detectFieldType,
|
|
2572
3024
|
formatForDisplay,
|
|
2573
3025
|
formatForEditing,
|
|
2574
3026
|
getDefaultValue,
|
|
2575
3027
|
getFormProperties,
|
|
2576
3028
|
getRefProps,
|
|
3029
|
+
getSelectOptionsFromAst,
|
|
3030
|
+
omitHiddenFormFields,
|
|
2577
3031
|
omitId,
|
|
2578
3032
|
parseValue,
|
|
2579
3033
|
pathNotUniqueError,
|
|
2580
|
-
setValueEchoAware,
|
|
2581
|
-
translations,
|
|
2582
3034
|
useFormContext,
|
|
2583
3035
|
useFormFieldState,
|
|
2584
3036
|
useFormHandler,
|