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