@dxos/react-ui-form 0.8.4-main.1068cf700f → 0.8.4-main.1c7ec43d41
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 +1135 -663
- 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 +1135 -663
- 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 +102 -54
- package/src/components/Form/FormField.tsx +39 -19
- package/src/components/Form/FormFieldComponent.stories.tsx +4 -4
- package/src/components/Form/FormFieldComponent.tsx +10 -10
- package/src/components/Form/FormFieldSet.tsx +121 -104
- package/src/components/Form/fields/ArrayField.tsx +14 -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 +84 -44
- 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 +12 -12
- 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 +35 -187
- package/src/components/Settings/SettingsFieldSet.tsx +257 -0
- package/src/components/Settings/SettingsItem.tsx +62 -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 -49
- 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,22 @@ 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
|
+
role: "none",
|
|
646
|
+
className: "flex items-center justify-between"
|
|
647
|
+
}, /* @__PURE__ */ React.createElement(Label, {
|
|
648
|
+
className: inputTextLabel
|
|
649
|
+
}, label), error && /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
|
|
678
650
|
asChild: true,
|
|
679
651
|
content: error,
|
|
680
652
|
side: "bottom"
|
|
681
653
|
}, /* @__PURE__ */ React.createElement(Icon, {
|
|
682
654
|
icon: "ph--warning--regular",
|
|
683
655
|
size: 4,
|
|
684
|
-
classNames:
|
|
656
|
+
classNames: "text-error-text"
|
|
685
657
|
})));
|
|
686
658
|
};
|
|
687
659
|
FormFieldLabel.displayName = "Form.FieldLabel";
|
|
@@ -723,9 +695,9 @@ var FormFieldErrorBoundary = class extends Component {
|
|
|
723
695
|
render() {
|
|
724
696
|
if (this.state.error) {
|
|
725
697
|
return /* @__PURE__ */ React.createElement("div", {
|
|
726
|
-
className: "flex gap-2 border border-
|
|
698
|
+
className: "flex gap-2 border border-rose-fill font-mono text-sm"
|
|
727
699
|
}, /* @__PURE__ */ React.createElement("span", {
|
|
728
|
-
className: "bg-
|
|
700
|
+
className: "bg-rose-fill text-surface-text px-1 font-thin"
|
|
729
701
|
}, "ERROR"), String(this.props.path?.join(".")));
|
|
730
702
|
}
|
|
731
703
|
return this.props.children;
|
|
@@ -738,20 +710,19 @@ var FormFieldErrorBoundary = class extends Component {
|
|
|
738
710
|
};
|
|
739
711
|
|
|
740
712
|
// src/components/Form/FormFieldSet.tsx
|
|
741
|
-
import React3, {
|
|
742
|
-
import { mx } from "@dxos/ui-theme";
|
|
743
|
-
import { isTruthy } from "@dxos/util";
|
|
713
|
+
import React3, { useMemo as useMemo3 } from "react";
|
|
744
714
|
|
|
745
715
|
// src/components/Form/FormField.tsx
|
|
746
716
|
import * as Match from "effect/Match";
|
|
747
717
|
import * as Option2 from "effect/Option";
|
|
748
718
|
import * as Schema from "effect/Schema";
|
|
749
|
-
import * as
|
|
719
|
+
import * as SchemaAST2 from "effect/SchemaAST";
|
|
750
720
|
import * as String2 from "effect/String";
|
|
751
721
|
import React2, { useMemo as useMemo2 } from "react";
|
|
752
722
|
import { Format as Format3 } from "@dxos/echo";
|
|
753
|
-
import { createJsonPath as createJsonPath2, findNode, getAnnotation, getDiscriminatedType, isArrayType as isArrayType2, isDiscriminatedUnion, isLiteralUnion, isNestedType } from "@dxos/effect";
|
|
723
|
+
import { createJsonPath as createJsonPath2, findNode, getAnnotation as getAnnotation2, getDiscriminatedType, isArrayType as isArrayType2, isDiscriminatedUnion, isLiteralUnion as isLiteralUnion2, isNestedType } from "@dxos/effect";
|
|
754
724
|
import { useTranslation } from "@dxos/react-ui";
|
|
725
|
+
import { translationKey } from "#translations";
|
|
755
726
|
var FormField = (props) => {
|
|
756
727
|
const {
|
|
757
728
|
type,
|
|
@@ -763,23 +734,25 @@ var FormField = (props) => {
|
|
|
763
734
|
readonly,
|
|
764
735
|
layout,
|
|
765
736
|
// RefFieldProps
|
|
737
|
+
createTypename,
|
|
766
738
|
createOptionLabel,
|
|
767
739
|
createOptionIcon,
|
|
768
740
|
createInitialValuePath,
|
|
741
|
+
createFieldMap: createFieldMap3,
|
|
769
742
|
db,
|
|
770
|
-
schemaHook,
|
|
771
|
-
getOptions
|
|
743
|
+
useSchema: schemaHook,
|
|
744
|
+
getOptions,
|
|
772
745
|
onCreate
|
|
773
746
|
} = props;
|
|
774
747
|
const { t } = useTranslation(translationKey);
|
|
775
|
-
const title =
|
|
776
|
-
const description =
|
|
777
|
-
const examples =
|
|
748
|
+
const title = getAnnotation2(SchemaAST2.TitleAnnotationId)(type);
|
|
749
|
+
const description = getAnnotation2(SchemaAST2.DescriptionAnnotationId)(type);
|
|
750
|
+
const examples = getAnnotation2(SchemaAST2.ExamplesAnnotationId)(type);
|
|
778
751
|
const label = useMemo2(() => title ?? String2.capitalize(name), [
|
|
779
752
|
title,
|
|
780
753
|
name
|
|
781
754
|
]);
|
|
782
|
-
const placeholder = useMemo2(() => examples?.length ? `${t("example
|
|
755
|
+
const placeholder = useMemo2(() => examples?.length ? `${t("example.placeholder")}: ${examples[0]}` : description ?? label, [
|
|
783
756
|
examples,
|
|
784
757
|
description,
|
|
785
758
|
label
|
|
@@ -792,6 +765,7 @@ var FormField = (props) => {
|
|
|
792
765
|
label,
|
|
793
766
|
placeholder,
|
|
794
767
|
layout,
|
|
768
|
+
db,
|
|
795
769
|
...fieldState
|
|
796
770
|
};
|
|
797
771
|
const jsonPath = createJsonPath2(path ?? []);
|
|
@@ -818,33 +792,41 @@ var FormField = (props) => {
|
|
|
818
792
|
if (Field) {
|
|
819
793
|
return /* @__PURE__ */ React2.createElement(Field, fieldProps);
|
|
820
794
|
}
|
|
821
|
-
const options =
|
|
795
|
+
const options = getSelectOptions(type);
|
|
822
796
|
if (options) {
|
|
797
|
+
const fieldProjections = projection?.getFieldProjections();
|
|
798
|
+
const fieldProjection = fieldProjections?.find((fp) => fp.field.path === name);
|
|
799
|
+
const selectOptions = fieldProjection?.props.options;
|
|
823
800
|
return /* @__PURE__ */ React2.createElement(SelectField, {
|
|
824
801
|
...fieldProps,
|
|
825
|
-
options: options.map((option) =>
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
802
|
+
options: options.map((option) => {
|
|
803
|
+
const selectOption = selectOptions?.find((so) => so.id === globalThis.String(option));
|
|
804
|
+
return {
|
|
805
|
+
value: option,
|
|
806
|
+
label: selectOption?.title ?? option.toString()
|
|
807
|
+
};
|
|
808
|
+
})
|
|
829
809
|
});
|
|
830
810
|
}
|
|
831
811
|
const refProps = getRefProps(type);
|
|
832
812
|
if (refProps) {
|
|
813
|
+
const isCreateTarget = !createTypename || refProps.typename === createTypename;
|
|
833
814
|
return /* @__PURE__ */ React2.createElement(RefField, {
|
|
834
815
|
...fieldProps,
|
|
835
816
|
...refProps,
|
|
836
|
-
createOptionLabel,
|
|
837
|
-
createOptionIcon,
|
|
838
|
-
createInitialValuePath,
|
|
817
|
+
createOptionLabel: isCreateTarget ? createOptionLabel : void 0,
|
|
818
|
+
createOptionIcon: isCreateTarget ? createOptionIcon : void 0,
|
|
819
|
+
createInitialValuePath: isCreateTarget ? createInitialValuePath : void 0,
|
|
820
|
+
createFieldMap: isCreateTarget ? createFieldMap3 : void 0,
|
|
839
821
|
db,
|
|
840
|
-
schemaHook,
|
|
841
|
-
getOptions
|
|
822
|
+
useSchema: schemaHook,
|
|
823
|
+
getOptions,
|
|
842
824
|
onCreate
|
|
843
825
|
});
|
|
844
826
|
}
|
|
845
827
|
if (isNestedType(type)) {
|
|
846
828
|
const baseNode = findNode(type, isDiscriminatedUnion);
|
|
847
|
-
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type,
|
|
829
|
+
const typeLiteral = baseNode ? getDiscriminatedType(baseNode, fieldState.getValue()) : findNode(type, SchemaAST2.isTypeLiteral);
|
|
848
830
|
if (typeLiteral) {
|
|
849
831
|
const schema = Schema.make(typeLiteral);
|
|
850
832
|
return /* @__PURE__ */ React2.createElement(FormFieldSet, {
|
|
@@ -860,8 +842,8 @@ var FormField = (props) => {
|
|
|
860
842
|
createOptionIcon,
|
|
861
843
|
createInitialValuePath,
|
|
862
844
|
db,
|
|
863
|
-
schemaHook,
|
|
864
|
-
getOptions
|
|
845
|
+
useSchema: schemaHook,
|
|
846
|
+
getOptions,
|
|
865
847
|
onCreate
|
|
866
848
|
});
|
|
867
849
|
}
|
|
@@ -885,8 +867,8 @@ var getFormField = ({ type, format }) => {
|
|
|
885
867
|
return BooleanField;
|
|
886
868
|
}
|
|
887
869
|
};
|
|
888
|
-
var
|
|
889
|
-
if (
|
|
870
|
+
var getSelectOptions = (ast) => {
|
|
871
|
+
if (isLiteralUnion2(ast)) {
|
|
890
872
|
return ast.types.map((type) => type.literal).filter((v) => v !== null);
|
|
891
873
|
}
|
|
892
874
|
return Format3.OptionsAnnotation.getFromAst(ast).pipe((annotation) => Option2.getOrUndefined(annotation));
|
|
@@ -894,47 +876,19 @@ var getOptions = (ast) => {
|
|
|
894
876
|
|
|
895
877
|
// src/components/Form/FormFieldSet.tsx
|
|
896
878
|
var FORM_FIELDSET_NAME = "Form.FieldSet";
|
|
897
|
-
var FormFieldSet =
|
|
879
|
+
var FormFieldSet = ({ label, schema, readonly, path, sort, exclude, projection, layout, ...props }) => {
|
|
898
880
|
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
|
-
}, [
|
|
881
|
+
const properties = useFormFieldSetProperties({
|
|
924
882
|
schema,
|
|
925
883
|
values,
|
|
926
884
|
exclude,
|
|
927
885
|
sort,
|
|
928
|
-
projection
|
|
929
|
-
|
|
886
|
+
projection
|
|
887
|
+
});
|
|
930
888
|
if ((readonly || layout === "static") && values == null) {
|
|
931
889
|
return null;
|
|
932
890
|
}
|
|
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, {
|
|
891
|
+
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, layout !== "inline" && label && /* @__PURE__ */ React3.createElement(FormFieldLabel, {
|
|
938
892
|
label,
|
|
939
893
|
asChild: true
|
|
940
894
|
}), properties.map((property) => {
|
|
@@ -957,24 +911,72 @@ var FormFieldSet = /* @__PURE__ */ forwardRef(({ classNames, label, schema, read
|
|
|
957
911
|
projection,
|
|
958
912
|
...props
|
|
959
913
|
}));
|
|
960
|
-
})
|
|
961
|
-
}
|
|
914
|
+
}));
|
|
915
|
+
};
|
|
962
916
|
FormFieldSet.displayName = FORM_FIELDSET_NAME;
|
|
917
|
+
var useFormFieldSetProperties = ({ schema, exclude, projection, values, sort }) => {
|
|
918
|
+
return useMemo3(() => {
|
|
919
|
+
if (!schema) {
|
|
920
|
+
return [];
|
|
921
|
+
}
|
|
922
|
+
const schemaProps = getFormProperties(schema.ast);
|
|
923
|
+
const filteredProps = exclude ? exclude(schemaProps) : schemaProps;
|
|
924
|
+
if (projection) {
|
|
925
|
+
const fieldProjections = projection.getFieldProjections();
|
|
926
|
+
const hiddenProperties = new Set(projection.getHiddenProperties());
|
|
927
|
+
const visibleProps = filteredProps.filter((prop) => !hiddenProperties.has(prop.name.toString()));
|
|
928
|
+
const orderedProps = [];
|
|
929
|
+
for (const fieldProjection of fieldProjections) {
|
|
930
|
+
const fieldPath = String(fieldProjection.field.path);
|
|
931
|
+
const prop = visibleProps.find((prop2) => prop2.name === fieldPath);
|
|
932
|
+
if (prop) {
|
|
933
|
+
orderedProps.push(prop);
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
const projectionPaths = new Set(fieldProjections.map((projection2) => String(projection2.field.path)));
|
|
937
|
+
const remainingProps = visibleProps.filter((prop) => !projectionPaths.has(prop.name.toString()));
|
|
938
|
+
orderedProps.push(...remainingProps);
|
|
939
|
+
return orderedProps;
|
|
940
|
+
}
|
|
941
|
+
return sort ? [
|
|
942
|
+
...filteredProps
|
|
943
|
+
].sort(({ name: a }, { name: b }) => sort.indexOf(a.toString()) - sort.indexOf(b.toString())) : filteredProps;
|
|
944
|
+
}, [
|
|
945
|
+
schema,
|
|
946
|
+
values,
|
|
947
|
+
exclude,
|
|
948
|
+
sort,
|
|
949
|
+
projection
|
|
950
|
+
]);
|
|
951
|
+
};
|
|
963
952
|
|
|
964
953
|
// src/components/Form/Form.tsx
|
|
965
954
|
var omitId = (schema) => schema.pipe(Schema2.omit("id"));
|
|
955
|
+
var omitHiddenFormFields = (schema) => {
|
|
956
|
+
const properties = SchemaAST3.getPropertySignatures(schema.ast);
|
|
957
|
+
const hidden = properties.filter((prop) => Option3.getOrElse(EchoAnnotation.FormInputAnnotation.getFromAst(prop.type), () => true) === false).map((prop) => prop.name);
|
|
958
|
+
return hidden.length === 0 ? schema : schema.pipe(Schema2.omit(...hidden));
|
|
959
|
+
};
|
|
966
960
|
var [FormContextProvider, useFormContext] = createContext("Form");
|
|
967
|
-
var useFormValues = (componentName, path
|
|
968
|
-
const
|
|
969
|
-
|
|
961
|
+
var useFormValues = (componentName, path, defaultValue) => {
|
|
962
|
+
const stablePath = useMemo4(() => path ?? [], [
|
|
963
|
+
path ? path.join(".") : void 0
|
|
964
|
+
]);
|
|
965
|
+
const jsonPath = createJsonPath3(stablePath);
|
|
966
|
+
const { form: { values, onValueChange } } = useFormContext(componentName);
|
|
970
967
|
const value3 = getValue$2(values, jsonPath);
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
968
|
+
const lastAppliedPathRef = useRef(null);
|
|
969
|
+
useEffect2(() => {
|
|
970
|
+
if (value3 == null && defaultValue && lastAppliedPathRef.current !== jsonPath) {
|
|
971
|
+
lastAppliedPathRef.current = jsonPath;
|
|
972
|
+
onValueChange(stablePath, SchemaAST3.stringKeyword, defaultValue());
|
|
974
973
|
}
|
|
975
974
|
}, [
|
|
976
975
|
value3,
|
|
977
|
-
defaultValue
|
|
976
|
+
defaultValue,
|
|
977
|
+
onValueChange,
|
|
978
|
+
stablePath,
|
|
979
|
+
jsonPath
|
|
978
980
|
]);
|
|
979
981
|
return value3;
|
|
980
982
|
};
|
|
@@ -1011,49 +1013,60 @@ var FormRoot = ({ children, schema, values, onSave, onCancel, ...props }) => {
|
|
|
1011
1013
|
};
|
|
1012
1014
|
FormRoot.displayName = "Form.Root";
|
|
1013
1015
|
var FORM_VIEWPORT_NAME = "Form.Viewport";
|
|
1014
|
-
var FormViewport = ({ children }) => {
|
|
1016
|
+
var FormViewport = composable(({ children, ...props }, forwardedRef) => {
|
|
1015
1017
|
return /* @__PURE__ */ React4.createElement(ScrollArea.Root, {
|
|
1016
|
-
|
|
1018
|
+
...composableProps(props),
|
|
1019
|
+
orientation: "vertical",
|
|
1020
|
+
centered: true,
|
|
1021
|
+
padding: true,
|
|
1022
|
+
thin: true,
|
|
1023
|
+
ref: forwardedRef
|
|
1017
1024
|
}, /* @__PURE__ */ React4.createElement(ScrollArea.Viewport, null, children));
|
|
1018
|
-
};
|
|
1025
|
+
});
|
|
1019
1026
|
FormViewport.displayName = FORM_VIEWPORT_NAME;
|
|
1020
1027
|
var FORM_CONTENT_NAME = "Form.Content";
|
|
1021
|
-
var FormContent = ({
|
|
1028
|
+
var FormContent = composable(({ children, ...props }, forwardedRef) => {
|
|
1022
1029
|
const { form, testId } = useFormContext(FORM_CONTENT_NAME);
|
|
1023
|
-
const
|
|
1024
|
-
|
|
1030
|
+
const localRef = useRef(null);
|
|
1031
|
+
const mergedRef = useMergeRefs([
|
|
1032
|
+
forwardedRef,
|
|
1033
|
+
localRef
|
|
1034
|
+
]);
|
|
1035
|
+
useKeyHandler(localRef, form);
|
|
1025
1036
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1037
|
+
...composableProps(props, {
|
|
1038
|
+
role: "form",
|
|
1039
|
+
classNames: mx(withColumn.center(), "flex flex-col w-full pb-form-gap")
|
|
1040
|
+
}),
|
|
1041
|
+
"data-testid": testId,
|
|
1042
|
+
ref: mergedRef
|
|
1030
1043
|
}, children);
|
|
1031
|
-
};
|
|
1044
|
+
});
|
|
1032
1045
|
FormContent.displayName = FORM_CONTENT_NAME;
|
|
1033
1046
|
var FORM_FIELDSET_NAME2 = "Form.FieldSet";
|
|
1034
|
-
var FormFieldSet2 = (
|
|
1035
|
-
const { form, ...
|
|
1047
|
+
var FormFieldSet2 = (props) => {
|
|
1048
|
+
const { form, ...contextProps } = useFormContext(FORM_FIELDSET_NAME2);
|
|
1036
1049
|
return /* @__PURE__ */ React4.createElement(FormFieldSet, {
|
|
1037
|
-
classNames,
|
|
1038
1050
|
schema: form.schema,
|
|
1051
|
+
...contextProps,
|
|
1039
1052
|
...props
|
|
1040
1053
|
});
|
|
1041
1054
|
};
|
|
1042
1055
|
FormFieldSet2.displayName = FORM_FIELDSET_NAME2;
|
|
1043
1056
|
var FORM_ACTIONS_NAME = "Form.Actions";
|
|
1044
1057
|
var FormActions = ({ classNames }) => {
|
|
1045
|
-
const { t } = useTranslation2(
|
|
1058
|
+
const { t } = useTranslation2(translationKey2);
|
|
1046
1059
|
const { form: { canSave, onSave, onCancel }, readonly, layout } = useFormContext(FORM_ACTIONS_NAME);
|
|
1047
1060
|
if (readonly || layout === "static") {
|
|
1048
1061
|
return null;
|
|
1049
1062
|
}
|
|
1050
1063
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1051
1064
|
role: "none",
|
|
1052
|
-
className:
|
|
1065
|
+
className: mx(withColumn.center(), "grid grid-flow-col gap-form-gap auto-cols-fr py-form-padding", classNames)
|
|
1053
1066
|
}, onCancel && /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1054
1067
|
icon: "ph--x--regular",
|
|
1055
1068
|
iconEnd: true,
|
|
1056
|
-
label: t("cancel
|
|
1069
|
+
label: t("cancel-button.label"),
|
|
1057
1070
|
onClick: onCancel,
|
|
1058
1071
|
"data-testid": "cancel-button"
|
|
1059
1072
|
}), onSave && /* @__PURE__ */ React4.createElement(IconButton, {
|
|
@@ -1062,29 +1075,43 @@ var FormActions = ({ classNames }) => {
|
|
|
1062
1075
|
disabled: !canSave,
|
|
1063
1076
|
icon: "ph--check--regular",
|
|
1064
1077
|
iconEnd: true,
|
|
1065
|
-
label: t("save
|
|
1078
|
+
label: t("save-button.label"),
|
|
1066
1079
|
onClick: onSave,
|
|
1067
1080
|
"data-testid": "save-button"
|
|
1068
1081
|
}));
|
|
1069
1082
|
};
|
|
1070
1083
|
FormActions.displayName = FORM_ACTIONS_NAME;
|
|
1084
|
+
var FORM_SECTION_NAME = "Form.Section";
|
|
1085
|
+
var FormSection = composable(({ children, label, description, ...props }, forwardedRef) => {
|
|
1086
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
1087
|
+
...composableProps(props, {
|
|
1088
|
+
classNames: "flex flex-col pt-form-section-gap first:pt-0"
|
|
1089
|
+
}),
|
|
1090
|
+
ref: forwardedRef
|
|
1091
|
+
}, /* @__PURE__ */ React4.createElement("h2", {
|
|
1092
|
+
className: "text-lg"
|
|
1093
|
+
}, label), description && /* @__PURE__ */ React4.createElement("p", {
|
|
1094
|
+
className: "text-description"
|
|
1095
|
+
}, description), children);
|
|
1096
|
+
});
|
|
1097
|
+
FormSection.displayName = FORM_SECTION_NAME;
|
|
1071
1098
|
var FORM_SUBMIT_NAME = "Form.Submit";
|
|
1072
1099
|
var FormSubmit = ({ classNames, label, icon, disabled }) => {
|
|
1073
|
-
const { t } = useTranslation2(
|
|
1100
|
+
const { t } = useTranslation2(translationKey2);
|
|
1074
1101
|
const { form: { canSave, onSave }, readonly, layout } = useFormContext(FORM_SUBMIT_NAME);
|
|
1075
1102
|
if (readonly || layout === "static") {
|
|
1076
1103
|
return null;
|
|
1077
1104
|
}
|
|
1078
1105
|
return /* @__PURE__ */ React4.createElement("div", {
|
|
1079
1106
|
role: "none",
|
|
1080
|
-
className:
|
|
1107
|
+
className: mx("flex w-full pt-form-padding", classNames)
|
|
1081
1108
|
}, /* @__PURE__ */ React4.createElement(IconButton, {
|
|
1082
|
-
classNames: "
|
|
1109
|
+
classNames: "w-full",
|
|
1083
1110
|
type: "submit",
|
|
1084
1111
|
variant: "primary",
|
|
1085
1112
|
disabled: disabled ?? !canSave,
|
|
1086
1113
|
icon: icon ?? "ph--check--regular",
|
|
1087
|
-
label: label ?? t("save
|
|
1114
|
+
label: label ?? t("save-button.label"),
|
|
1088
1115
|
onClick: onSave,
|
|
1089
1116
|
"data-testid": "save-button"
|
|
1090
1117
|
}));
|
|
@@ -1094,26 +1121,27 @@ var Form = {
|
|
|
1094
1121
|
Root: FormRoot,
|
|
1095
1122
|
Viewport: FormViewport,
|
|
1096
1123
|
Content: FormContent,
|
|
1124
|
+
Section: FormSection,
|
|
1097
1125
|
FieldSet: FormFieldSet2,
|
|
1126
|
+
Label: FormFieldLabel,
|
|
1098
1127
|
Actions: FormActions,
|
|
1099
|
-
Submit: FormSubmit
|
|
1100
|
-
Label: FormFieldLabel
|
|
1128
|
+
Submit: FormSubmit
|
|
1101
1129
|
};
|
|
1102
1130
|
|
|
1103
1131
|
// src/components/Form/fields/ArrayField.tsx
|
|
1104
1132
|
var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps, ...props }) => {
|
|
1105
|
-
const { t } = useTranslation3(
|
|
1133
|
+
const { t } = useTranslation3(translationKey3);
|
|
1106
1134
|
const elementType = getArrayElementType2(type);
|
|
1107
1135
|
const { onValueChange } = inputProps;
|
|
1108
1136
|
const values = useFormValues(ArrayField.displayName, path, () => []);
|
|
1109
1137
|
const getDefaultObjectValue = (typeNode) => {
|
|
1110
1138
|
const baseNode = findNode2(typeNode, isDiscriminatedUnion2);
|
|
1111
|
-
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode,
|
|
1139
|
+
const typeLiteral = baseNode ? getDiscriminatedType2(baseNode, {}) : findNode2(typeNode, SchemaAST4.isTypeLiteral);
|
|
1112
1140
|
if (!typeLiteral) {
|
|
1113
1141
|
return {};
|
|
1114
1142
|
}
|
|
1115
1143
|
return Object.fromEntries(getFormProperties(typeLiteral).map((prop) => {
|
|
1116
|
-
const defaultValue =
|
|
1144
|
+
const defaultValue = SchemaAST4.getDefaultAnnotation(prop.type).pipe((annotation) => Option4.getOrUndefined(annotation));
|
|
1117
1145
|
return [
|
|
1118
1146
|
prop.name,
|
|
1119
1147
|
defaultValue
|
|
@@ -1148,12 +1176,12 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1148
1176
|
asChild: true
|
|
1149
1177
|
}), /* @__PURE__ */ React5.createElement("div", {
|
|
1150
1178
|
role: "none",
|
|
1151
|
-
className: "flex flex-col gap-
|
|
1179
|
+
className: "flex flex-col gap-form-gap"
|
|
1152
1180
|
}, values?.map((_, index) => {
|
|
1153
1181
|
return /* @__PURE__ */ React5.createElement("div", {
|
|
1154
1182
|
role: "none",
|
|
1155
1183
|
key: index,
|
|
1156
|
-
className: "grid grid-cols-[1fr_min-content] gap-
|
|
1184
|
+
className: "grid grid-cols-[1fr_min-content] gap-form-gap last:mb-form-gap items-center"
|
|
1157
1185
|
}, /* @__PURE__ */ React5.createElement(FormField, {
|
|
1158
1186
|
autoFocus: index === values.length - 1,
|
|
1159
1187
|
type: elementType,
|
|
@@ -1166,21 +1194,21 @@ var ArrayField = ({ type, path, label, readonly, layout, fieldProps: inputProps,
|
|
|
1166
1194
|
...props
|
|
1167
1195
|
}), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement("div", {
|
|
1168
1196
|
role: "none",
|
|
1169
|
-
className: "flex flex-col
|
|
1197
|
+
className: "flex flex-col h-full justify-end"
|
|
1170
1198
|
}, /* @__PURE__ */ React5.createElement("div", {
|
|
1171
1199
|
role: "none",
|
|
1172
|
-
className: "flex items-center
|
|
1200
|
+
className: "flex items-center h-[2rem]"
|
|
1173
1201
|
}, /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1174
1202
|
icon: "ph--x--regular",
|
|
1175
1203
|
iconOnly: true,
|
|
1176
|
-
label: t("button
|
|
1204
|
+
label: t("remove.button"),
|
|
1177
1205
|
onClick: () => handleDelete(index),
|
|
1178
1206
|
classNames: "self-center"
|
|
1179
1207
|
}))));
|
|
1180
1208
|
})), !readonly && layout !== "static" && /* @__PURE__ */ React5.createElement(IconButton2, {
|
|
1181
|
-
classNames: "flex
|
|
1209
|
+
classNames: "flex w-full",
|
|
1182
1210
|
icon: "ph--plus--regular",
|
|
1183
|
-
label: t("add
|
|
1211
|
+
label: t("add-item.button"),
|
|
1184
1212
|
onClick: handleAdd
|
|
1185
1213
|
}));
|
|
1186
1214
|
};
|
|
@@ -1228,12 +1256,13 @@ var BooleanField = ({ type, readonly, onValueChange, ...props }) => {
|
|
|
1228
1256
|
};
|
|
1229
1257
|
|
|
1230
1258
|
// src/components/Form/fields/GeoPointField.tsx
|
|
1231
|
-
import React7, { useCallback as useCallback5, useEffect as
|
|
1259
|
+
import React7, { useCallback as useCallback5, useEffect as useEffect3, useMemo as useMemo5, useState as useState2 } from "react";
|
|
1232
1260
|
import { GeoLocation as GeoLocation3 } from "@dxos/echo/internal";
|
|
1233
1261
|
import { Input as Input3, useTranslation as useTranslation4 } from "@dxos/react-ui";
|
|
1234
1262
|
import { safeParseFloat } from "@dxos/util";
|
|
1263
|
+
import { translationKey as translationKey4 } from "#translations";
|
|
1235
1264
|
var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onValueChange, onBlur }) => {
|
|
1236
|
-
const { t } = useTranslation4(
|
|
1265
|
+
const { t } = useTranslation4(translationKey4);
|
|
1237
1266
|
const { status, error } = getStatus();
|
|
1238
1267
|
const geoPoint = useMemo5(() => getValue() ?? [
|
|
1239
1268
|
0,
|
|
@@ -1246,7 +1275,7 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
|
|
|
1246
1275
|
]);
|
|
1247
1276
|
const [longitudeText, setLongitudeText] = useState2(value3.longitude?.toString());
|
|
1248
1277
|
const [latitudeText, setLatitudeText] = useState2(value3.latitude?.toString());
|
|
1249
|
-
|
|
1278
|
+
useEffect3(() => {
|
|
1250
1279
|
const location = GeoLocation3.fromGeoPoint(geoPoint);
|
|
1251
1280
|
setLongitudeText(location.longitude?.toString());
|
|
1252
1281
|
setLatitudeText(location.latitude?.toString());
|
|
@@ -1288,24 +1317,24 @@ var GeoPointField = ({ type, label, readonly, layout, getStatus, getValue, onVal
|
|
|
1288
1317
|
asChild: true
|
|
1289
1318
|
}), layout === "static" ? /* @__PURE__ */ React7.createElement(LatLng, value3) : /* @__PURE__ */ React7.createElement("div", {
|
|
1290
1319
|
role: "none",
|
|
1291
|
-
className: "grid grid-cols-2 gap-
|
|
1292
|
-
}, /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement(Input3.Root, null, layout !== "inline" && /* @__PURE__ */ React7.createElement(Input3.Label, null, t("latitude
|
|
1320
|
+
className: "grid grid-cols-2 gap-form-gap"
|
|
1321
|
+
}, /* @__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
1322
|
type: "number",
|
|
1294
1323
|
step: "0.00001",
|
|
1295
1324
|
min: "-90",
|
|
1296
1325
|
max: "90",
|
|
1297
1326
|
disabled: !!readonly,
|
|
1298
|
-
placeholder: t("latitude
|
|
1327
|
+
placeholder: t("latitude.placeholder"),
|
|
1299
1328
|
value: latitudeText ?? "",
|
|
1300
1329
|
onChange: handleChange("latitude", setLatitudeText),
|
|
1301
1330
|
onBlur
|
|
1302
|
-
}))), /* @__PURE__ */ React7.createElement("div", null, /* @__PURE__ */ React7.createElement(Input3.Root, null, layout !== "inline" && /* @__PURE__ */ React7.createElement(Input3.Label, null, t("longitude
|
|
1331
|
+
}))), /* @__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
1332
|
type: "number",
|
|
1304
1333
|
step: "0.00001",
|
|
1305
1334
|
min: "-180",
|
|
1306
1335
|
max: "180",
|
|
1307
1336
|
disabled: !!readonly,
|
|
1308
|
-
placeholder: t("longitude
|
|
1337
|
+
placeholder: t("longitude.placeholder"),
|
|
1309
1338
|
value: longitudeText ?? "",
|
|
1310
1339
|
onChange: handleChange("longitude", setLongitudeText),
|
|
1311
1340
|
onBlur
|
|
@@ -1315,7 +1344,7 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
|
|
|
1315
1344
|
const latHem = latitude >= 0 ? "N" : "S";
|
|
1316
1345
|
const lngHem = longitude >= 0 ? "E" : "W";
|
|
1317
1346
|
return /* @__PURE__ */ React7.createElement("span", {
|
|
1318
|
-
className: "inline-flex items-center gap-
|
|
1347
|
+
className: "inline-flex items-center gap-form-gap"
|
|
1319
1348
|
}, /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(latitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
|
|
1320
1349
|
className: "text-subdued"
|
|
1321
1350
|
}, "\xB0", latHem)), /* @__PURE__ */ React7.createElement("span", null, /* @__PURE__ */ React7.createElement("span", null, Math.abs(longitude).toFixed(5)), /* @__PURE__ */ React7.createElement("span", {
|
|
@@ -1324,56 +1353,141 @@ var LatLng = ({ latitude = 0, longitude = 0 }) => {
|
|
|
1324
1353
|
};
|
|
1325
1354
|
|
|
1326
1355
|
// src/components/Form/fields/MarkdownField.tsx
|
|
1327
|
-
import
|
|
1328
|
-
import {
|
|
1329
|
-
|
|
1356
|
+
import { useAtomValue } from "@effect-atom/atom-react";
|
|
1357
|
+
import React8, { useCallback as useCallback6, useMemo as useMemo6 } from "react";
|
|
1358
|
+
import { Obj, Ref as Ref2 } from "@dxos/echo";
|
|
1359
|
+
import { AtomRef } from "@dxos/echo-atom";
|
|
1360
|
+
import { createDocAccessor } from "@dxos/echo-db";
|
|
1361
|
+
import { Button, Icon as Icon2, Input as Input4, useTranslation as useTranslation5 } from "@dxos/react-ui";
|
|
1362
|
+
import { Editor, useBasicMarkdownExtensions } from "@dxos/react-ui-editor";
|
|
1363
|
+
import { Text } from "@dxos/schema";
|
|
1364
|
+
import { createDataExtensions } from "@dxos/ui-editor";
|
|
1365
|
+
import { translationKey as translationKey5 } from "#translations";
|
|
1366
|
+
var editorClassNames = "transition-colors bg-input-surface focus-within:bg-focus-surface border border-separator rounded-xs p-1 px-2";
|
|
1367
|
+
var MarkdownField = ({ type, readonly, label, placeholder, layout, db, getStatus, getValue, onValueChange }) => {
|
|
1330
1368
|
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
|
-
]);
|
|
1369
|
+
const isRef = Ref2.isRefType(type);
|
|
1354
1370
|
const value3 = getValue();
|
|
1355
|
-
if ((readonly || layout === "static") &&
|
|
1371
|
+
if ((readonly || layout === "static") && value3 == null) {
|
|
1356
1372
|
return null;
|
|
1357
1373
|
}
|
|
1374
|
+
const renderEditor = () => {
|
|
1375
|
+
if (isRef) {
|
|
1376
|
+
const reference = value3;
|
|
1377
|
+
if (reference) {
|
|
1378
|
+
return /* @__PURE__ */ React8.createElement(RefMarkdownEditor, {
|
|
1379
|
+
reference,
|
|
1380
|
+
placeholder
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
1383
|
+
if (readonly) {
|
|
1384
|
+
return null;
|
|
1385
|
+
}
|
|
1386
|
+
return /* @__PURE__ */ React8.createElement(CreateTextButton, {
|
|
1387
|
+
db,
|
|
1388
|
+
disabled: !db,
|
|
1389
|
+
onCreate: (ref) => onValueChange(type, ref)
|
|
1390
|
+
});
|
|
1391
|
+
}
|
|
1392
|
+
return /* @__PURE__ */ React8.createElement(StringMarkdownEditor, {
|
|
1393
|
+
value: value3 ?? "",
|
|
1394
|
+
placeholder,
|
|
1395
|
+
readonly: !!readonly,
|
|
1396
|
+
onChange: (next) => onValueChange(type, next)
|
|
1397
|
+
});
|
|
1398
|
+
};
|
|
1399
|
+
const renderStatic = () => {
|
|
1400
|
+
if (isRef) {
|
|
1401
|
+
const reference = value3;
|
|
1402
|
+
return reference ? /* @__PURE__ */ React8.createElement(RefStaticText, {
|
|
1403
|
+
reference
|
|
1404
|
+
}) : null;
|
|
1405
|
+
}
|
|
1406
|
+
return /* @__PURE__ */ React8.createElement("p", {
|
|
1407
|
+
className: "whitespace-pre-wrap"
|
|
1408
|
+
}, value3 ?? "");
|
|
1409
|
+
};
|
|
1358
1410
|
return /* @__PURE__ */ React8.createElement(Input4.Root, {
|
|
1359
1411
|
validationValence: status
|
|
1360
1412
|
}, layout !== "inline" && /* @__PURE__ */ React8.createElement(FormFieldLabel, {
|
|
1361
1413
|
error,
|
|
1362
1414
|
readonly,
|
|
1363
1415
|
label
|
|
1364
|
-
}), layout === "static" ?
|
|
1365
|
-
|
|
1366
|
-
|
|
1416
|
+
}), layout === "static" ? renderStatic() : renderEditor(), layout === "full" && /* @__PURE__ */ React8.createElement(Input4.Validation, null, error));
|
|
1417
|
+
};
|
|
1418
|
+
var RefStaticText = ({ reference }) => {
|
|
1419
|
+
const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
|
|
1420
|
+
reference
|
|
1421
|
+
]));
|
|
1422
|
+
if (!text?.content) {
|
|
1423
|
+
return null;
|
|
1424
|
+
}
|
|
1425
|
+
return /* @__PURE__ */ React8.createElement("p", {
|
|
1426
|
+
className: "whitespace-pre-wrap"
|
|
1427
|
+
}, text.content);
|
|
1428
|
+
};
|
|
1429
|
+
var RefMarkdownEditor = ({ reference, placeholder }) => {
|
|
1430
|
+
const text = useAtomValue(useMemo6(() => AtomRef.make(reference), [
|
|
1431
|
+
reference
|
|
1432
|
+
]));
|
|
1433
|
+
const dataExtensions = useMemo6(() => text ? [
|
|
1434
|
+
createDataExtensions({
|
|
1435
|
+
id: reference.dxn.toString(),
|
|
1436
|
+
text: createDocAccessor(text, [
|
|
1437
|
+
"content"
|
|
1438
|
+
])
|
|
1439
|
+
})
|
|
1440
|
+
] : [], [
|
|
1441
|
+
text,
|
|
1442
|
+
reference
|
|
1443
|
+
]);
|
|
1444
|
+
const extensions = useBasicMarkdownExtensions({
|
|
1367
1445
|
placeholder,
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
})
|
|
1446
|
+
extensions: dataExtensions
|
|
1447
|
+
});
|
|
1448
|
+
if (!text) {
|
|
1449
|
+
return null;
|
|
1450
|
+
}
|
|
1451
|
+
return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
|
|
1452
|
+
classNames: editorClassNames,
|
|
1453
|
+
extensions
|
|
1454
|
+
}));
|
|
1455
|
+
};
|
|
1456
|
+
var StringMarkdownEditor = ({ value: value3, placeholder, readonly, onChange }) => {
|
|
1457
|
+
const extensions = useBasicMarkdownExtensions({
|
|
1458
|
+
placeholder
|
|
1459
|
+
});
|
|
1460
|
+
const handleChange = useCallback6((next) => onChange(next), [
|
|
1461
|
+
onChange
|
|
1462
|
+
]);
|
|
1463
|
+
return /* @__PURE__ */ React8.createElement(Editor.Root, null, /* @__PURE__ */ React8.createElement(Editor.View, {
|
|
1464
|
+
classNames: editorClassNames,
|
|
1465
|
+
extensions,
|
|
1466
|
+
value: value3,
|
|
1467
|
+
onChange: readonly ? void 0 : handleChange
|
|
1468
|
+
}));
|
|
1469
|
+
};
|
|
1470
|
+
var CreateTextButton = ({ db, disabled, onCreate }) => {
|
|
1471
|
+
const { t } = useTranslation5(translationKey5);
|
|
1472
|
+
const handleClick = useCallback6(() => {
|
|
1473
|
+
if (!db) {
|
|
1474
|
+
return;
|
|
1475
|
+
}
|
|
1476
|
+
const text = db.add(Obj.make(Text.Text, {
|
|
1477
|
+
content: ""
|
|
1478
|
+
}));
|
|
1479
|
+
onCreate(Ref2.make(text));
|
|
1480
|
+
}, [
|
|
1481
|
+
db,
|
|
1482
|
+
onCreate
|
|
1483
|
+
]);
|
|
1484
|
+
return /* @__PURE__ */ React8.createElement(Button, {
|
|
1485
|
+
onClick: handleClick,
|
|
1486
|
+
disabled
|
|
1487
|
+
}, /* @__PURE__ */ React8.createElement(Icon2, {
|
|
1488
|
+
icon: "ph--plus--regular",
|
|
1489
|
+
size: 4
|
|
1490
|
+
}), /* @__PURE__ */ React8.createElement("span", null, t("create-text.label")));
|
|
1377
1491
|
};
|
|
1378
1492
|
|
|
1379
1493
|
// src/components/Form/fields/NumberField.tsx
|
|
@@ -1399,47 +1513,33 @@ var NumberField = ({ type, readonly, placeholder, onValueChange, onBlur, ...prop
|
|
|
1399
1513
|
};
|
|
1400
1514
|
|
|
1401
1515
|
// src/components/Form/fields/RefField.tsx
|
|
1516
|
+
import React11, { useCallback as useCallback9, useMemo as useMemo7, useState as useState4 } from "react";
|
|
1402
1517
|
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";
|
|
1518
|
+
import { Entity, Filter, Obj as Obj2, Ref as Ref3, Type } from "@dxos/echo";
|
|
1519
|
+
import { useQuery, useSchema as defaultUseSchema } from "@dxos/echo-react";
|
|
1520
|
+
import { ReferenceAnnotationId as ReferenceAnnotationId2 } from "@dxos/echo/internal";
|
|
1521
|
+
import { findAnnotation as findAnnotation2 } from "@dxos/effect";
|
|
1408
1522
|
import { DXN } from "@dxos/keys";
|
|
1409
1523
|
import { DxAnchor } from "@dxos/lit-ui/react";
|
|
1410
|
-
import { Button, Icon as
|
|
1411
|
-
import {
|
|
1524
|
+
import { Button as Button2, Icon as Icon3, Input as Input6, useTranslation as useTranslation7 } from "@dxos/react-ui";
|
|
1525
|
+
import { ParentLabelAnnotationId } from "@dxos/schema";
|
|
1526
|
+
import { translationKey as translationKey7 } from "#translations";
|
|
1412
1527
|
|
|
1413
1528
|
// 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);
|
|
1529
|
+
import React10, { forwardRef, useCallback as useCallback8, useState as useState3 } from "react";
|
|
1530
|
+
import { Popover, useTranslation as useTranslation6 } from "@dxos/react-ui";
|
|
1531
|
+
import { Combobox } from "@dxos/react-ui-list";
|
|
1532
|
+
import { useSearchListResults } from "@dxos/react-ui-search";
|
|
1533
|
+
import { translationKey as translationKey6 } from "#translations";
|
|
1534
|
+
var ObjectPickerContent = /* @__PURE__ */ forwardRef(({ options, selectedIds, createSchema, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, onSelect, onCreate, ...props }, forwardedRef) => {
|
|
1535
|
+
const { t } = useTranslation6(translationKey6);
|
|
1436
1536
|
const [showForm, setShowForm] = useState3(false);
|
|
1437
1537
|
const [formInitialValue, setFormInitialValue] = useState3("");
|
|
1438
|
-
const { results, handleSearch } = useSearchListResults({
|
|
1538
|
+
const { results, query, handleSearch } = useSearchListResults({
|
|
1439
1539
|
items: options
|
|
1440
1540
|
});
|
|
1441
|
-
const handleFormSave = useCallback8((values) => {
|
|
1442
|
-
onCreate?.(values);
|
|
1541
|
+
const handleFormSave = useCallback8(async (values) => {
|
|
1542
|
+
await onCreate?.(values);
|
|
1443
1543
|
setShowForm(false);
|
|
1444
1544
|
setFormInitialValue("");
|
|
1445
1545
|
}, [
|
|
@@ -1461,22 +1561,31 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
|
|
|
1461
1561
|
}, [
|
|
1462
1562
|
createSchema
|
|
1463
1563
|
]);
|
|
1564
|
+
if (showForm && createSchema) {
|
|
1565
|
+
return /* @__PURE__ */ React10.createElement(Combobox.Content, {
|
|
1566
|
+
...props,
|
|
1567
|
+
onKeyDownCapture: handleKeyDown,
|
|
1568
|
+
ref: forwardedRef
|
|
1569
|
+
}, /* @__PURE__ */ React10.createElement(Popover.Viewport, null, /* @__PURE__ */ React10.createElement(Form.Root, {
|
|
1570
|
+
testId: "create-referenced-object-form",
|
|
1571
|
+
schema: createSchema,
|
|
1572
|
+
defaultValues: createInitialValuePath ? {
|
|
1573
|
+
[createInitialValuePath]: formInitialValue
|
|
1574
|
+
} : {},
|
|
1575
|
+
fieldMap: createFieldMap3,
|
|
1576
|
+
onSave: handleFormSave,
|
|
1577
|
+
onCancel: handleFormCancel
|
|
1578
|
+
}, /* @__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));
|
|
1579
|
+
}
|
|
1464
1580
|
return /* @__PURE__ */ React10.createElement(Combobox.Content, {
|
|
1465
1581
|
...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
|
|
1582
|
+
onKeyDownCapture: handleKeyDown,
|
|
1583
|
+
ref: forwardedRef
|
|
1584
|
+
}, /* @__PURE__ */ React10.createElement(Combobox.Input, {
|
|
1585
|
+
placeholder: t("ref-field-combobox-input.placeholder"),
|
|
1586
|
+
autoFocus: true,
|
|
1587
|
+
value: query,
|
|
1588
|
+
onValueChange: handleSearch
|
|
1480
1589
|
}), /* @__PURE__ */ React10.createElement(Combobox.List, null, results.map((option) => /* @__PURE__ */ React10.createElement(Combobox.Item, {
|
|
1481
1590
|
key: option.id,
|
|
1482
1591
|
value: option.id,
|
|
@@ -1484,16 +1593,34 @@ var ObjectPickerContent = /* @__PURE__ */ forwardRef2(({ options, selectedIds, c
|
|
|
1484
1593
|
checked: selectedIds?.includes(option.id),
|
|
1485
1594
|
onSelect: () => onSelect(option.id),
|
|
1486
1595
|
classNames: "flex items-center gap-2"
|
|
1487
|
-
})),
|
|
1596
|
+
})), createSchema && onCreate && /* @__PURE__ */ React10.createElement(CreateItem, {
|
|
1597
|
+
query,
|
|
1488
1598
|
createOptionLabel,
|
|
1489
|
-
createOptionIcon,
|
|
1490
|
-
onCreateItemSelect: (
|
|
1491
|
-
setFormInitialValue(
|
|
1599
|
+
createOptionIcon: createOptionIcon ?? "ph--plus--regular",
|
|
1600
|
+
onCreateItemSelect: (currentQuery) => {
|
|
1601
|
+
setFormInitialValue(currentQuery);
|
|
1492
1602
|
setShowForm(true);
|
|
1493
1603
|
}
|
|
1494
|
-
}))
|
|
1604
|
+
})), /* @__PURE__ */ React10.createElement(Combobox.Arrow, null));
|
|
1495
1605
|
});
|
|
1496
|
-
|
|
1606
|
+
var CreateItem = ({ query, createOptionLabel, createOptionIcon, onCreateItemSelect }) => {
|
|
1607
|
+
const { t } = useTranslation6(translationKey6);
|
|
1608
|
+
const label = createOptionLabel ? t(createOptionLabel[0], {
|
|
1609
|
+
ns: createOptionLabel[1].ns,
|
|
1610
|
+
text: query
|
|
1611
|
+
}) : t("create-option.label");
|
|
1612
|
+
return /* @__PURE__ */ React10.createElement(Combobox.Item, {
|
|
1613
|
+
value: "__create__",
|
|
1614
|
+
label,
|
|
1615
|
+
icon: createOptionIcon,
|
|
1616
|
+
classNames: "flex items-center gap-2",
|
|
1617
|
+
closeOnSelect: false,
|
|
1618
|
+
onSelect: () => {
|
|
1619
|
+
onCreateItemSelect(query);
|
|
1620
|
+
}
|
|
1621
|
+
});
|
|
1622
|
+
};
|
|
1623
|
+
ObjectPickerContent.displayName = "ObjectPicker.Content";
|
|
1497
1624
|
var ObjectPicker = {
|
|
1498
1625
|
Root: Combobox.Root,
|
|
1499
1626
|
Portal: Combobox.Portal,
|
|
@@ -1506,34 +1633,43 @@ var ObjectPicker = {
|
|
|
1506
1633
|
var isRefSnapshot = (val) => {
|
|
1507
1634
|
return typeof val === "object" && typeof val?.["/"] === "string";
|
|
1508
1635
|
};
|
|
1509
|
-
var defaultGetOptions = (results) => results.map((result) => {
|
|
1636
|
+
var defaultGetOptions = (results, { parentLabel } = {}) => results.map((result) => {
|
|
1510
1637
|
const id = Entity.getDXN(result).toString();
|
|
1511
|
-
const
|
|
1638
|
+
const parent = parentLabel ? Obj2.getParent(result) : void 0;
|
|
1639
|
+
const label = parent ? Entity.getLabel(parent) : Entity.getLabel(result);
|
|
1512
1640
|
return {
|
|
1513
1641
|
id,
|
|
1514
1642
|
label: label ?? id
|
|
1515
1643
|
};
|
|
1516
1644
|
});
|
|
1517
|
-
var
|
|
1645
|
+
var defaultUseResults = (db, typename) => useQuery(db, typename ? typename === Type.getTypename(Obj2.Unknown) ? Filter.everything() : Filter.typename(typename) : Filter.nothing());
|
|
1518
1646
|
var RefField = (props) => {
|
|
1519
|
-
const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, db,
|
|
1520
|
-
const { t } =
|
|
1647
|
+
const { type, readonly, label, placeholder, layout, getStatus, getValue, createOptionLabel, createOptionIcon, createInitialValuePath, createFieldMap: createFieldMap3, db, useSchema = defaultUseSchema, useResults = defaultUseResults, getOptions = defaultGetOptions, onCreate, onValueChange } = props;
|
|
1648
|
+
const { t } = useTranslation7(translationKey7);
|
|
1521
1649
|
const { status, error } = getStatus();
|
|
1522
|
-
const typename =
|
|
1650
|
+
const typename = useMemo7(() => type ? findAnnotation2(type, ReferenceAnnotationId2)?.typename : void 0, [
|
|
1523
1651
|
type
|
|
1524
1652
|
]);
|
|
1525
1653
|
const results = useResults(db, typename);
|
|
1526
|
-
const options =
|
|
1654
|
+
const options = useMemo7(() => {
|
|
1655
|
+
const parentLabel = type ? findAnnotation2(type, ParentLabelAnnotationId) === true : false;
|
|
1656
|
+
return getOptions(results, {
|
|
1657
|
+
parentLabel
|
|
1658
|
+
});
|
|
1659
|
+
}, [
|
|
1527
1660
|
results,
|
|
1528
|
-
|
|
1661
|
+
getOptions,
|
|
1662
|
+
type
|
|
1529
1663
|
]);
|
|
1530
1664
|
const handleGetValue = useCallback9(() => {
|
|
1531
1665
|
const formValue = getValue();
|
|
1666
|
+
const dxnToObjectId = (dxn) => dxn.split(":").pop() ?? dxn;
|
|
1532
1667
|
const unknownToRefOption = (value3) => {
|
|
1533
|
-
const isRef =
|
|
1668
|
+
const isRef = Ref3.isRef(value3);
|
|
1534
1669
|
if (isRef || isRefSnapshot(value3)) {
|
|
1535
1670
|
const dxnString = isRef ? value3.dxn.toString() : value3["/"];
|
|
1536
|
-
const
|
|
1671
|
+
const objectId = dxnToObjectId(dxnString);
|
|
1672
|
+
const matchingOption = options.find((option) => dxnToObjectId(option.id) === objectId);
|
|
1537
1673
|
if (matchingOption) {
|
|
1538
1674
|
return matchingOption;
|
|
1539
1675
|
}
|
|
@@ -1545,29 +1681,37 @@ var RefField = (props) => {
|
|
|
1545
1681
|
options,
|
|
1546
1682
|
getValue
|
|
1547
1683
|
]);
|
|
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
1684
|
const item = handleGetValue();
|
|
1558
|
-
const selectedIds =
|
|
1685
|
+
const selectedIds = useMemo7(() => item ? [
|
|
1559
1686
|
item.id
|
|
1560
1687
|
] : [], [
|
|
1561
1688
|
item
|
|
1562
1689
|
]);
|
|
1563
1690
|
const createSchema = useSchema(db, typename);
|
|
1564
|
-
const
|
|
1565
|
-
|
|
1566
|
-
|
|
1691
|
+
const [open, setOpen] = useState4(false);
|
|
1692
|
+
const handleCreate = useCallback9(async (values) => {
|
|
1693
|
+
if (!createSchema || !onCreate) {
|
|
1694
|
+
return;
|
|
1695
|
+
}
|
|
1696
|
+
const newObject = await onCreate(createSchema, values);
|
|
1697
|
+
if (newObject) {
|
|
1698
|
+
onValueChange(type, Ref3.make(newObject));
|
|
1567
1699
|
}
|
|
1700
|
+
setOpen(false);
|
|
1568
1701
|
}, [
|
|
1569
1702
|
createSchema,
|
|
1570
|
-
onCreate
|
|
1703
|
+
onCreate,
|
|
1704
|
+
type,
|
|
1705
|
+
onValueChange
|
|
1706
|
+
]);
|
|
1707
|
+
const handleUpdate = useCallback9((id) => {
|
|
1708
|
+
const item2 = options.find((option) => option.id === id);
|
|
1709
|
+
const ref = item2 ? Ref3.fromDXN(DXN.parse(item2.id)) : void 0;
|
|
1710
|
+
onValueChange(type, ref);
|
|
1711
|
+
}, [
|
|
1712
|
+
options,
|
|
1713
|
+
type,
|
|
1714
|
+
onValueChange
|
|
1571
1715
|
]);
|
|
1572
1716
|
const handleSelect = useCallback9((id) => {
|
|
1573
1717
|
if (item?.id === id) {
|
|
@@ -1589,40 +1733,48 @@ var RefField = (props) => {
|
|
|
1589
1733
|
readonly,
|
|
1590
1734
|
label
|
|
1591
1735
|
}), /* @__PURE__ */ React11.createElement("div", null, readonly ? !item ? /* @__PURE__ */ React11.createElement("p", {
|
|
1592
|
-
className:
|
|
1593
|
-
}, t("empty
|
|
1736
|
+
className: "text-description mb-2"
|
|
1737
|
+
}, t("empty-readonly-ref-field.label")) : /* @__PURE__ */ React11.createElement(DxAnchor, {
|
|
1594
1738
|
key: item.id,
|
|
1595
1739
|
dxn: item.id,
|
|
1596
|
-
rootclassname: "
|
|
1597
|
-
}, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root,
|
|
1740
|
+
rootclassname: "me-1"
|
|
1741
|
+
}, item.label) : /* @__PURE__ */ React11.createElement(ObjectPicker.Root, {
|
|
1742
|
+
open,
|
|
1743
|
+
onOpenChange: setOpen
|
|
1744
|
+
}, /* @__PURE__ */ React11.createElement(ObjectPicker.Trigger, {
|
|
1598
1745
|
asChild: true,
|
|
1599
1746
|
classNames: "p-0"
|
|
1600
1747
|
}, item ? /* @__PURE__ */ React11.createElement("div", {
|
|
1601
|
-
|
|
1748
|
+
role: "none",
|
|
1749
|
+
className: "flex gap-form-gap w-full"
|
|
1602
1750
|
}, /* @__PURE__ */ React11.createElement(Input6.Root, {
|
|
1603
1751
|
key: item.id
|
|
1604
1752
|
}, /* @__PURE__ */ React11.createElement(Input6.TextInput, {
|
|
1605
1753
|
value: item.label,
|
|
1606
1754
|
readOnly: true,
|
|
1607
|
-
classNames: "
|
|
1608
|
-
}))) : /* @__PURE__ */ React11.createElement(
|
|
1609
|
-
classNames: "
|
|
1755
|
+
classNames: "w-full"
|
|
1756
|
+
}))) : /* @__PURE__ */ React11.createElement(Button2, {
|
|
1757
|
+
classNames: "w-full text-start gap-form-gap"
|
|
1610
1758
|
}, /* @__PURE__ */ React11.createElement("div", {
|
|
1611
1759
|
role: "none",
|
|
1612
1760
|
className: "grow overflow-hidden"
|
|
1613
1761
|
}, /* @__PURE__ */ React11.createElement("span", {
|
|
1614
|
-
className: "
|
|
1615
|
-
}, placeholder ?? t("ref
|
|
1762
|
+
className: "truncate text-description"
|
|
1763
|
+
}, placeholder ?? t("ref-field.placeholder"))), /* @__PURE__ */ React11.createElement(Icon3, {
|
|
1616
1764
|
size: 3,
|
|
1617
1765
|
icon: "ph--caret-down--bold"
|
|
1618
1766
|
}))), /* @__PURE__ */ React11.createElement(ObjectPicker.Portal, null, /* @__PURE__ */ React11.createElement(ObjectPicker.Content, {
|
|
1619
|
-
classNames: "
|
|
1767
|
+
classNames: "dx-card-popover-width",
|
|
1620
1768
|
options,
|
|
1621
1769
|
selectedIds,
|
|
1622
|
-
|
|
1770
|
+
// Strip hidden (`FormInputAnnotation.set(false)`) fields so the
|
|
1771
|
+
// form's validator doesn't reject required-but-hidden fields
|
|
1772
|
+
// such as backing-object refs supplied by a `FactoryAnnotation`.
|
|
1773
|
+
createSchema: createSchema && omitHiddenFormFields(omitId(createSchema)),
|
|
1623
1774
|
createOptionLabel,
|
|
1624
1775
|
createOptionIcon,
|
|
1625
1776
|
createInitialValuePath,
|
|
1777
|
+
createFieldMap: createFieldMap3,
|
|
1626
1778
|
onCreate: handleCreate,
|
|
1627
1779
|
onSelect: handleSelect
|
|
1628
1780
|
})))), layout === "full" && /* @__PURE__ */ React11.createElement(Input6.DescriptionAndValidation, null, error));
|
|
@@ -1651,7 +1803,7 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
|
|
|
1651
1803
|
value: value3,
|
|
1652
1804
|
onValueChange: handleValueChange
|
|
1653
1805
|
}, /* @__PURE__ */ React12.createElement(Select.TriggerButton, {
|
|
1654
|
-
classNames: "
|
|
1806
|
+
classNames: "w-full",
|
|
1655
1807
|
disabled: !!readonly,
|
|
1656
1808
|
placeholder
|
|
1657
1809
|
}), /* @__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 +1816,21 @@ var SelectField = ({ type, readonly, label, layout, placeholder, options, getSta
|
|
|
1664
1816
|
};
|
|
1665
1817
|
|
|
1666
1818
|
// src/components/Form/fields/SelectOptionField.tsx
|
|
1667
|
-
import React13, { useCallback as useCallback11, useEffect as
|
|
1819
|
+
import React13, { useCallback as useCallback11, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
|
|
1668
1820
|
import { PublicKey } from "@dxos/keys";
|
|
1669
|
-
import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as
|
|
1821
|
+
import { IconButton as IconButton3, Input as Input8, Tag, useTranslation as useTranslation8 } from "@dxos/react-ui";
|
|
1670
1822
|
import { List } from "@dxos/react-ui-list";
|
|
1671
1823
|
import { HuePicker } from "@dxos/react-ui-pickers";
|
|
1672
1824
|
import { hues, osTranslations, subtleHover } from "@dxos/ui-theme";
|
|
1825
|
+
import { translationKey as translationKey8 } from "#translations";
|
|
1673
1826
|
var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueChange }) => {
|
|
1674
|
-
const { t } =
|
|
1827
|
+
const { t } = useTranslation8(translationKey8);
|
|
1675
1828
|
const { status, error } = getStatus();
|
|
1676
|
-
const [selected, setSelectedId] =
|
|
1677
|
-
const [isNewOption, setIsNewOption] =
|
|
1678
|
-
const inputRef =
|
|
1829
|
+
const [selected, setSelectedId] = useState5(null);
|
|
1830
|
+
const [isNewOption, setIsNewOption] = useState5(false);
|
|
1831
|
+
const inputRef = useRef2(null);
|
|
1679
1832
|
const options = getValue();
|
|
1680
|
-
|
|
1833
|
+
useEffect4(() => {
|
|
1681
1834
|
if (options === void 0) {
|
|
1682
1835
|
onValueChange(type, []);
|
|
1683
1836
|
}
|
|
@@ -1768,7 +1921,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1768
1921
|
type,
|
|
1769
1922
|
onValueChange
|
|
1770
1923
|
]);
|
|
1771
|
-
|
|
1924
|
+
useEffect4(() => {
|
|
1772
1925
|
if (selected && isNewOption && inputRef.current) {
|
|
1773
1926
|
inputRef.current.focus();
|
|
1774
1927
|
setIsNewOption(false);
|
|
@@ -1792,7 +1945,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1792
1945
|
readonly: !!readonly
|
|
1793
1946
|
}, ({ items }) => /* @__PURE__ */ React13.createElement("div", {
|
|
1794
1947
|
role: "list",
|
|
1795
|
-
className: "
|
|
1948
|
+
className: "w-full overflow-auto"
|
|
1796
1949
|
}, items?.map((item) => /* @__PURE__ */ React13.createElement("div", {
|
|
1797
1950
|
key: item.id
|
|
1798
1951
|
}, /* @__PURE__ */ React13.createElement(List.Item, {
|
|
@@ -1800,7 +1953,7 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1800
1953
|
item,
|
|
1801
1954
|
classNames: [
|
|
1802
1955
|
subtleHover,
|
|
1803
|
-
"flex flex-col cursor-pointer rounded-
|
|
1956
|
+
"flex flex-col cursor-pointer rounded-xs"
|
|
1804
1957
|
],
|
|
1805
1958
|
"aria-expanded": selected === item.id
|
|
1806
1959
|
}, /* @__PURE__ */ React13.createElement("div", {
|
|
@@ -1815,20 +1968,20 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1815
1968
|
}, item.title || "\u200B")), /* @__PURE__ */ React13.createElement(IconButton3, {
|
|
1816
1969
|
iconOnly: true,
|
|
1817
1970
|
variant: "ghost",
|
|
1818
|
-
label: t(selected === item.id ? "collapse
|
|
1971
|
+
label: t(selected === item.id ? "collapse.label" : "expand.label", {
|
|
1819
1972
|
ns: osTranslations
|
|
1820
1973
|
}),
|
|
1821
1974
|
icon: selected === item.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
1822
1975
|
onClick: () => handleClick(item.id)
|
|
1823
1976
|
})), selected === item.id && /* @__PURE__ */ React13.createElement("div", {
|
|
1824
|
-
className: "
|
|
1977
|
+
className: "flex flex-col p-form-padding gap-form-gap dx-density-fine"
|
|
1825
1978
|
}, /* @__PURE__ */ React13.createElement(Input8.Label, {
|
|
1826
1979
|
classNames: "text-xs"
|
|
1827
|
-
}, t("select
|
|
1828
|
-
className: "grid grid-cols-[1fr_min-content_min-content] gap-
|
|
1980
|
+
}, t("select-option.label")), /* @__PURE__ */ React13.createElement("div", {
|
|
1981
|
+
className: "grid grid-cols-[1fr_min-content_min-content] gap-form-gap"
|
|
1829
1982
|
}, /* @__PURE__ */ React13.createElement(Input8.TextInput, {
|
|
1830
1983
|
disabled: !!readonly,
|
|
1831
|
-
placeholder: t("select
|
|
1984
|
+
placeholder: t("select-option-label.placeholder"),
|
|
1832
1985
|
ref: selected === item.id ? inputRef : void 0,
|
|
1833
1986
|
value: item.title,
|
|
1834
1987
|
onChange: handleTitleChange(item.id),
|
|
@@ -1842,22 +1995,22 @@ var SelectOptionField = ({ type, readonly, label, getStatus, getValue, onValueCh
|
|
|
1842
1995
|
disabled: !!readonly,
|
|
1843
1996
|
icon: "ph--trash--fill",
|
|
1844
1997
|
iconOnly: true,
|
|
1845
|
-
label: t("select
|
|
1998
|
+
label: t("select-option-delete.button"),
|
|
1846
1999
|
onClick: () => handleDelete(item.id)
|
|
1847
2000
|
})))))), /* @__PURE__ */ React13.createElement(IconButton3, {
|
|
1848
2001
|
variant: "ghost",
|
|
1849
2002
|
icon: "ph--plus--regular",
|
|
1850
|
-
label: t("select
|
|
2003
|
+
label: t("select-option-add.button"),
|
|
1851
2004
|
onClick: handleAdd,
|
|
1852
2005
|
disabled: !!readonly,
|
|
1853
|
-
classNames: "
|
|
2006
|
+
classNames: "w-full"
|
|
1854
2007
|
})))));
|
|
1855
2008
|
};
|
|
1856
2009
|
|
|
1857
2010
|
// src/components/Form/fields/TextField.tsx
|
|
1858
2011
|
import React14, { useCallback as useCallback12 } from "react";
|
|
1859
2012
|
import { Input as Input9 } from "@dxos/react-ui";
|
|
1860
|
-
var TextField = ({ type, readonly, placeholder,
|
|
2013
|
+
var TextField = ({ type, readonly, placeholder, onBlur, onValueChange, ...props }) => {
|
|
1861
2014
|
const handleChange = useCallback12((event) => onValueChange(type, event.target.value), [
|
|
1862
2015
|
type,
|
|
1863
2016
|
onValueChange
|
|
@@ -1870,8 +2023,8 @@ var TextField = ({ type, readonly, placeholder, onValueChange, onBlur, ...props
|
|
|
1870
2023
|
disabled: !!readonly,
|
|
1871
2024
|
placeholder,
|
|
1872
2025
|
value: value3,
|
|
1873
|
-
|
|
1874
|
-
|
|
2026
|
+
onBlur,
|
|
2027
|
+
onChange: handleChange
|
|
1875
2028
|
}));
|
|
1876
2029
|
};
|
|
1877
2030
|
|
|
@@ -1899,7 +2052,7 @@ var TextAreaField = ({ type, readonly, placeholder, onValueChange, onBlur, ...pr
|
|
|
1899
2052
|
// src/components/Form/fields/TupleField.tsx
|
|
1900
2053
|
import React16 from "react";
|
|
1901
2054
|
import { Input as Input11 } from "@dxos/react-ui";
|
|
1902
|
-
import { mx as
|
|
2055
|
+
import { mx as mx2 } from "@dxos/ui-theme";
|
|
1903
2056
|
import { safeParseFloat as safeParseFloat3 } from "@dxos/util";
|
|
1904
2057
|
var gridCols = [
|
|
1905
2058
|
"grid-cols-1",
|
|
@@ -1917,7 +2070,7 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1917
2070
|
readonly,
|
|
1918
2071
|
label
|
|
1919
2072
|
}), /* @__PURE__ */ React16.createElement("div", {
|
|
1920
|
-
className:
|
|
2073
|
+
className: mx2("grid gap-form-gap", gridCols[binding.length - 1])
|
|
1921
2074
|
}, binding.map((prop) => /* @__PURE__ */ React16.createElement(Input11.TextInput, {
|
|
1922
2075
|
key: prop,
|
|
1923
2076
|
type: "number",
|
|
@@ -1936,13 +2089,13 @@ var TupleField = ({ binding, type, readonly, label, getStatus, getValue, onValue
|
|
|
1936
2089
|
// src/components/FieldEditor/FieldEditor.tsx
|
|
1937
2090
|
var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/FieldEditor/FieldEditor.tsx";
|
|
1938
2091
|
var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCancel }) => {
|
|
1939
|
-
const { t } =
|
|
1940
|
-
const [props, setProps] =
|
|
1941
|
-
|
|
2092
|
+
const { t } = useTranslation9(translationKey9);
|
|
2093
|
+
const [props, setProps] = useState6(projection.getFieldProjection(field.id).props);
|
|
2094
|
+
useEffect5(() => setProps(projection.getFieldProjection(field.id).props), [
|
|
1942
2095
|
field,
|
|
1943
2096
|
projection
|
|
1944
2097
|
]);
|
|
1945
|
-
const [schemas, setSchemas] =
|
|
2098
|
+
const [schemas, setSchemas] = useState6([]);
|
|
1946
2099
|
useAsyncEffect(async () => {
|
|
1947
2100
|
if (!registry) {
|
|
1948
2101
|
return;
|
|
@@ -1956,22 +2109,22 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
1956
2109
|
}, [
|
|
1957
2110
|
registry
|
|
1958
2111
|
]);
|
|
1959
|
-
const [referenceSchema, setReferenceSchema] =
|
|
1960
|
-
|
|
2112
|
+
const [referenceSchema, setReferenceSchema] = useState6();
|
|
2113
|
+
useEffect5(() => {
|
|
1961
2114
|
setReferenceSchema(schemas.find((schema) => schema.typename === props?.referenceSchema));
|
|
1962
2115
|
}, [
|
|
1963
2116
|
schemas,
|
|
1964
2117
|
props?.referenceSchema
|
|
1965
2118
|
]);
|
|
1966
|
-
const [{ fieldSchema }, setFieldSchema] =
|
|
2119
|
+
const [{ fieldSchema }, setFieldSchema] = useState6({
|
|
1967
2120
|
fieldSchema: getFormatSchema(props?.format)
|
|
1968
2121
|
});
|
|
1969
|
-
const fieldMap =
|
|
2122
|
+
const fieldMap = useMemo8(() => ({
|
|
1970
2123
|
["format"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
|
|
1971
2124
|
...props2,
|
|
1972
2125
|
options: FormatEnums.filter((value3) => value3 !== Format4.TypeFormat.None).map((value3) => ({
|
|
1973
2126
|
value: value3,
|
|
1974
|
-
label: t(`format
|
|
2127
|
+
label: t(`format.${value3}.label`)
|
|
1975
2128
|
}))
|
|
1976
2129
|
}),
|
|
1977
2130
|
["referenceSchema"]: (props2) => /* @__PURE__ */ React17.createElement(SelectField, {
|
|
@@ -2045,7 +2198,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2045
2198
|
]);
|
|
2046
2199
|
const handleSave = useCallback14((props2) => {
|
|
2047
2200
|
if (view) {
|
|
2048
|
-
Obj3.
|
|
2201
|
+
Obj3.update(view, () => {
|
|
2049
2202
|
projection.setFieldProjection({
|
|
2050
2203
|
field,
|
|
2051
2204
|
props: props2
|
|
@@ -2073,12 +2226,7 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2073
2226
|
if (!fieldSchema) {
|
|
2074
2227
|
log2.warn("invalid format", {
|
|
2075
2228
|
props
|
|
2076
|
-
}, {
|
|
2077
|
-
F: __dxlog_file2,
|
|
2078
|
-
L: 173,
|
|
2079
|
-
S: void 0,
|
|
2080
|
-
C: (f, a) => f(...a)
|
|
2081
|
-
});
|
|
2229
|
+
}, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 156, S: void 0 });
|
|
2082
2230
|
return null;
|
|
2083
2231
|
}
|
|
2084
2232
|
return /* @__PURE__ */ React17.createElement(Form.Root, {
|
|
@@ -2100,160 +2248,491 @@ var FieldEditor = ({ readonly, projection, field, registry, view, onSave, onCanc
|
|
|
2100
2248
|
}, /* @__PURE__ */ React17.createElement(Form.Content, null, /* @__PURE__ */ React17.createElement(Form.FieldSet, null), /* @__PURE__ */ React17.createElement(Form.Actions, null)));
|
|
2101
2249
|
};
|
|
2102
2250
|
|
|
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)));
|
|
2251
|
+
// src/components/ObjectForm/ObjectForm.tsx
|
|
2252
|
+
import * as Schema3 from "effect/Schema";
|
|
2253
|
+
import React18, { useCallback as useCallback15, useMemo as useMemo9 } from "react";
|
|
2254
|
+
import { DXN as DXN2, Obj as Obj4, Ref as Ref4, Tag as Tag2, Type as Type2 } from "@dxos/echo";
|
|
2255
|
+
import { splitJsonPath } from "@dxos/echo/internal";
|
|
2256
|
+
import { invariant } from "@dxos/invariant";
|
|
2257
|
+
import { HuePicker as HuePicker2 } from "@dxos/react-ui-pickers";
|
|
2258
|
+
import { isNonNullable } from "@dxos/util";
|
|
2259
|
+
import { translationKey as translationKey10 } from "#translations";
|
|
2260
|
+
var __dxlog_file3 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectForm/ObjectForm.tsx";
|
|
2261
|
+
var createFieldMap = {
|
|
2262
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
2263
|
+
const handleChange = useCallback15((nextHue) => onValueChange(type, nextHue), [
|
|
2264
|
+
onValueChange,
|
|
2265
|
+
type
|
|
2266
|
+
]);
|
|
2267
|
+
const handleReset = useCallback15(() => onValueChange(type, void 0), [
|
|
2268
|
+
onValueChange,
|
|
2269
|
+
type
|
|
2270
|
+
]);
|
|
2271
|
+
return /* @__PURE__ */ React18.createElement(React18.Fragment, null, layout !== "inline" && /* @__PURE__ */ React18.createElement(Form.Label, {
|
|
2272
|
+
label
|
|
2273
|
+
}), /* @__PURE__ */ React18.createElement(HuePicker2, {
|
|
2274
|
+
value: getValue(),
|
|
2275
|
+
onChange: handleChange,
|
|
2276
|
+
onReset: handleReset
|
|
2277
|
+
}));
|
|
2278
|
+
}
|
|
2146
2279
|
};
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2280
|
+
var ObjectForm = ({ object, schema }) => {
|
|
2281
|
+
const db = Obj4.getDatabase(object);
|
|
2282
|
+
const meta = Obj4.getMeta(object);
|
|
2283
|
+
const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN2.parse(tag))).filter(isNonNullable);
|
|
2284
|
+
const values = useMemo9(() => ({
|
|
2285
|
+
tags,
|
|
2286
|
+
...object
|
|
2287
|
+
}), [
|
|
2288
|
+
object,
|
|
2289
|
+
tags
|
|
2290
|
+
]);
|
|
2291
|
+
const formSchema = useMemo9(() => omitId(Schema3.Struct({
|
|
2292
|
+
tags: Schema3.Array(Ref4.Ref(Tag2.Tag)).pipe(Schema3.optional)
|
|
2293
|
+
}).pipe(Schema3.extend(schema))), [
|
|
2294
|
+
schema
|
|
2295
|
+
]);
|
|
2296
|
+
const handleCreate = useCallback15((schema2, values2) => {
|
|
2297
|
+
invariant(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 49, S: void 0, A: ["db", ""] });
|
|
2298
|
+
invariant(Type2.isObjectSchema(schema2), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file3, L: 50, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
|
|
2299
|
+
const newObject = db.add(Obj4.make(schema2, values2));
|
|
2300
|
+
if (Obj4.instanceOf(Tag2.Tag, newObject)) {
|
|
2301
|
+
Obj4.update(object, (object2) => {
|
|
2302
|
+
Obj4.getMeta(object2).tags = [
|
|
2303
|
+
...Obj4.getMeta(object2).tags ?? [],
|
|
2304
|
+
Obj4.getDXN(newObject).toString()
|
|
2305
|
+
];
|
|
2306
|
+
});
|
|
2307
|
+
}
|
|
2308
|
+
}, []);
|
|
2309
|
+
const handleChange = useCallback15(({ tags: tags2, ...values2 }, { isValid, changed }) => {
|
|
2310
|
+
if (!isValid) {
|
|
2311
|
+
return;
|
|
2312
|
+
}
|
|
2313
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
2314
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath(path)[0] === "tags");
|
|
2315
|
+
if (hasTagsChange) {
|
|
2316
|
+
Obj4.update(object, (object2) => {
|
|
2317
|
+
Obj4.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
|
|
2318
|
+
});
|
|
2319
|
+
}
|
|
2320
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath(path)[0] !== "tags");
|
|
2321
|
+
if (nonTagPaths.length > 0) {
|
|
2322
|
+
Obj4.update(object, () => {
|
|
2323
|
+
for (const path of nonTagPaths) {
|
|
2324
|
+
const parts = splitJsonPath(path);
|
|
2325
|
+
const value3 = Obj4.getValue(values2, parts);
|
|
2326
|
+
Obj4.setValue(object, parts, value3);
|
|
2327
|
+
}
|
|
2328
|
+
});
|
|
2329
|
+
}
|
|
2330
|
+
}, [
|
|
2331
|
+
object
|
|
2332
|
+
]);
|
|
2333
|
+
return /* @__PURE__ */ React18.createElement(Form.Root, {
|
|
2334
|
+
schema: formSchema,
|
|
2335
|
+
defaultValues: values,
|
|
2336
|
+
createTypename: Type2.getTypename(Tag2.Tag),
|
|
2337
|
+
createOptionIcon: "ph--plus--regular",
|
|
2338
|
+
createOptionLabel: [
|
|
2339
|
+
"add-tag.label",
|
|
2340
|
+
{
|
|
2341
|
+
ns: translationKey10
|
|
2342
|
+
}
|
|
2343
|
+
],
|
|
2344
|
+
createInitialValuePath: "label",
|
|
2345
|
+
createFieldMap,
|
|
2346
|
+
db,
|
|
2347
|
+
onValuesChanged: handleChange,
|
|
2348
|
+
onCreate: handleCreate
|
|
2349
|
+
}, /* @__PURE__ */ React18.createElement(Form.Viewport, null, /* @__PURE__ */ React18.createElement(Form.Content, null, /* @__PURE__ */ React18.createElement(Form.FieldSet, null))));
|
|
2156
2350
|
};
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
}
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2351
|
+
|
|
2352
|
+
// src/components/ObjectProperties/ObjectProperties.tsx
|
|
2353
|
+
import * as Function from "effect/Function";
|
|
2354
|
+
import * as Option5 from "effect/Option";
|
|
2355
|
+
import * as Schema4 from "effect/Schema";
|
|
2356
|
+
import React19, { useCallback as useCallback16, useMemo as useMemo10 } from "react";
|
|
2357
|
+
import { DXN as DXN3, Obj as Obj5, Ref as Ref5, Tag as Tag3, Type as Type3 } from "@dxos/echo";
|
|
2358
|
+
import { splitJsonPath as splitJsonPath2 } from "@dxos/echo/internal";
|
|
2359
|
+
import { invariant as invariant2 } from "@dxos/invariant";
|
|
2360
|
+
import { HuePicker as HuePicker3 } from "@dxos/react-ui-pickers";
|
|
2361
|
+
import { FactoryAnnotation } from "@dxos/schema";
|
|
2362
|
+
import { composable as composable2, composableProps as composableProps2 } from "@dxos/ui-theme";
|
|
2363
|
+
import { isNonNullable as isNonNullable2 } from "@dxos/util";
|
|
2364
|
+
import { translationKey as translationKey11 } from "#translations";
|
|
2365
|
+
var __dxlog_file4 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ObjectProperties/ObjectProperties.tsx";
|
|
2366
|
+
var ObjectProperties = composable2(({ children, object, ...props }, forwardedRef) => {
|
|
2367
|
+
const db = Obj5.getDatabase(object);
|
|
2368
|
+
const meta = Obj5.getMeta(object);
|
|
2369
|
+
const tags = (meta.tags ?? []).map((tag) => db?.makeRef(DXN3.parse(tag))).filter(isNonNullable2);
|
|
2370
|
+
const values = useMemo10(() => ({
|
|
2371
|
+
tags,
|
|
2372
|
+
...object
|
|
2373
|
+
}), [
|
|
2374
|
+
object,
|
|
2375
|
+
tags
|
|
2376
|
+
]);
|
|
2377
|
+
const formSchema = useMemo10(() => {
|
|
2378
|
+
return Function.pipe(Obj5.getSchema(object), Option5.fromNullable, Option5.map((schema) => omitId(BaseSchema.pipe(Schema4.extend(schema)))), Option5.getOrUndefined);
|
|
2379
|
+
}, [
|
|
2380
|
+
object
|
|
2381
|
+
]);
|
|
2382
|
+
const handleCreate = useCallback16((schema, values2) => {
|
|
2383
|
+
invariant2(db, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 45, S: void 0, A: ["db", ""] });
|
|
2384
|
+
invariant2(Type3.isObjectSchema(schema), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file4, L: 46, S: void 0, A: ["Type.isObjectSchema(schema)", ""] });
|
|
2385
|
+
const factory = Option5.getOrUndefined(FactoryAnnotation.get(schema));
|
|
2386
|
+
const newObject = factory ? factory(values2) : Obj5.make(schema, values2);
|
|
2387
|
+
return db.add(newObject);
|
|
2388
|
+
}, [
|
|
2389
|
+
db
|
|
2390
|
+
]);
|
|
2391
|
+
const handleChange = useCallback16(({ tags: tags2, ...values2 }, { isValid, changed }) => {
|
|
2392
|
+
if (!isValid) {
|
|
2393
|
+
return;
|
|
2394
|
+
}
|
|
2395
|
+
const changedPaths = Object.keys(changed).filter((path) => changed[path]);
|
|
2396
|
+
const hasTagsChange = changedPaths.some((path) => splitJsonPath2(path)[0] === "tags");
|
|
2397
|
+
if (hasTagsChange) {
|
|
2398
|
+
Obj5.update(object, (object2) => {
|
|
2399
|
+
Obj5.getMeta(object2).tags = tags2?.map((tag) => tag.dxn.toString()) ?? [];
|
|
2400
|
+
});
|
|
2401
|
+
}
|
|
2402
|
+
const nonTagPaths = changedPaths.filter((path) => splitJsonPath2(path)[0] !== "tags");
|
|
2403
|
+
if (nonTagPaths.length > 0) {
|
|
2404
|
+
Obj5.update(object, () => {
|
|
2405
|
+
for (const path of nonTagPaths) {
|
|
2406
|
+
const parts = splitJsonPath2(path);
|
|
2407
|
+
const value3 = Obj5.getValue(values2, parts);
|
|
2408
|
+
Obj5.setValue(object, parts, value3);
|
|
2409
|
+
}
|
|
2410
|
+
});
|
|
2411
|
+
}
|
|
2412
|
+
}, [
|
|
2413
|
+
object
|
|
2414
|
+
]);
|
|
2415
|
+
if (!formSchema) {
|
|
2416
|
+
return null;
|
|
2417
|
+
}
|
|
2418
|
+
return /* @__PURE__ */ React19.createElement(Form.Root, {
|
|
2419
|
+
schema: formSchema,
|
|
2420
|
+
defaultValues: values,
|
|
2421
|
+
createTypename: Type3.getTypename(Tag3.Tag),
|
|
2422
|
+
createOptionIcon: "ph--plus--regular",
|
|
2423
|
+
createOptionLabel: [
|
|
2424
|
+
"add-tag.label",
|
|
2425
|
+
{
|
|
2426
|
+
ns: translationKey11
|
|
2427
|
+
}
|
|
2428
|
+
],
|
|
2429
|
+
createInitialValuePath: "label",
|
|
2430
|
+
createFieldMap: createFieldMap2,
|
|
2431
|
+
db,
|
|
2432
|
+
onValuesChanged: handleChange,
|
|
2433
|
+
onCreate: handleCreate
|
|
2434
|
+
}, /* @__PURE__ */ React19.createElement(Form.Viewport, {
|
|
2435
|
+
...composableProps2(props),
|
|
2436
|
+
ref: forwardedRef
|
|
2437
|
+
}, /* @__PURE__ */ React19.createElement(Form.Content, null, /* @__PURE__ */ React19.createElement(Form.FieldSet, null), children)));
|
|
2438
|
+
});
|
|
2439
|
+
var createFieldMap2 = {
|
|
2440
|
+
hue: ({ type, label, layout, getValue, onValueChange }) => {
|
|
2441
|
+
const handleChange = useCallback16((nextHue) => onValueChange(type, nextHue), [
|
|
2442
|
+
onValueChange,
|
|
2443
|
+
type
|
|
2444
|
+
]);
|
|
2445
|
+
const handleReset = useCallback16(() => onValueChange(type, void 0), [
|
|
2446
|
+
onValueChange,
|
|
2447
|
+
type
|
|
2448
|
+
]);
|
|
2449
|
+
return /* @__PURE__ */ React19.createElement(React19.Fragment, null, layout !== "inline" && /* @__PURE__ */ React19.createElement(Form.Label, {
|
|
2450
|
+
label
|
|
2451
|
+
}), /* @__PURE__ */ React19.createElement(HuePicker3, {
|
|
2452
|
+
value: getValue(),
|
|
2453
|
+
onChange: handleChange,
|
|
2454
|
+
onReset: handleReset
|
|
2455
|
+
}));
|
|
2456
|
+
}
|
|
2178
2457
|
};
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2458
|
+
var BaseSchema = Schema4.Struct({
|
|
2459
|
+
tags: Schema4.Array(Ref5.Ref(Tag3.Tag)).pipe(Schema4.optional)
|
|
2460
|
+
});
|
|
2461
|
+
|
|
2462
|
+
// src/components/Settings/Settings.tsx
|
|
2463
|
+
import React22 from "react";
|
|
2464
|
+
import { ScrollArea as ScrollArea2, toLocalizedString as toLocalizedString2, useTranslation as useTranslation11 } from "@dxos/react-ui";
|
|
2465
|
+
import { composable as composable3, composableProps as composableProps3, mx as mx4 } from "@dxos/ui-theme";
|
|
2466
|
+
import { translationKey as translationKey13 } from "#translations";
|
|
2467
|
+
|
|
2468
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
2469
|
+
import * as SchemaAST5 from "effect/SchemaAST";
|
|
2470
|
+
import * as String3 from "effect/String";
|
|
2471
|
+
import React21, { useCallback as useCallback17, useMemo as useMemo11 } from "react";
|
|
2472
|
+
import { getAnnotation as getAnnotation3 } from "@dxos/effect";
|
|
2473
|
+
import { Input as Input13, Select as Select2 } from "@dxos/react-ui";
|
|
2474
|
+
|
|
2475
|
+
// src/components/Settings/SettingsItem.tsx
|
|
2476
|
+
import React20 from "react";
|
|
2477
|
+
import { Input as Input12, toLocalizedString, useTranslation as useTranslation10 } from "@dxos/react-ui";
|
|
2478
|
+
import { mx as mx3 } from "@dxos/ui-theme";
|
|
2479
|
+
import { translationKey as translationKey12 } from "#translations";
|
|
2480
|
+
var SETTINGS_PANEL_NAME = "Settings.Panel";
|
|
2481
|
+
var SETTINGS_ITEM_NAME = "Settings.Item";
|
|
2482
|
+
var SettingsPanel = ({ classNames, children }) => {
|
|
2483
|
+
return /* @__PURE__ */ React20.createElement("div", {
|
|
2182
2484
|
role: "none",
|
|
2183
|
-
className:
|
|
2184
|
-
"container-max-width",
|
|
2185
|
-
"*:first:!mbs-0 *:last:!mbe-0 pli-trimMd plb-trimMd",
|
|
2186
|
-
"border border-separator rounded-md",
|
|
2187
|
-
classNames
|
|
2188
|
-
])
|
|
2485
|
+
className: mx3("flex flex-col gap-3 p-trim-md border border-separator rounded-sm", classNames)
|
|
2189
2486
|
}, children);
|
|
2190
2487
|
};
|
|
2191
|
-
|
|
2488
|
+
SettingsPanel.displayName = SETTINGS_PANEL_NAME;
|
|
2192
2489
|
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__ */
|
|
2490
|
+
const { t } = useTranslation10(translationKey12);
|
|
2491
|
+
return /* @__PURE__ */ React20.createElement(Input12.Root, null, /* @__PURE__ */ React20.createElement(SettingsPanel, {
|
|
2492
|
+
classNames: "grid grid-cols-1 md:grid-cols-[1fr_1fr] gap-x-trim-lg gap-y-0"
|
|
2493
|
+
}, /* @__PURE__ */ React20.createElement(Input12.Label, {
|
|
2494
|
+
classNames: "pb-trim-md text-base-surface-text text-lg md:col-span-2"
|
|
2495
|
+
}, toLocalizedString(title, t)), /* @__PURE__ */ React20.createElement(Input12.DescriptionAndValidation, null, /* @__PURE__ */ React20.createElement(Input12.Description, {
|
|
2496
|
+
classNames: "text-base text-description"
|
|
2497
|
+
}, toLocalizedString(description, t))), /* @__PURE__ */ React20.createElement("div", {
|
|
2201
2498
|
role: "none",
|
|
2202
|
-
className: "text-end
|
|
2203
|
-
}, children));
|
|
2499
|
+
className: "text-end py-1"
|
|
2500
|
+
}, children)));
|
|
2204
2501
|
};
|
|
2205
2502
|
SettingsItem.displayName = SETTINGS_ITEM_NAME;
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2503
|
+
|
|
2504
|
+
// src/components/Settings/SettingsFieldSet.tsx
|
|
2505
|
+
var SettingsFieldSet = ({ schema, values, onValuesChanged, readonly, fieldMap, visible, sort, pathPrefix = "" }) => {
|
|
2506
|
+
const properties = useMemo11(() => {
|
|
2507
|
+
const props = getFormProperties(schema.ast);
|
|
2508
|
+
if (!sort) {
|
|
2509
|
+
return props;
|
|
2510
|
+
}
|
|
2511
|
+
const rank = (name) => {
|
|
2512
|
+
const idx = sort.indexOf(name);
|
|
2513
|
+
return idx === -1 ? Number.POSITIVE_INFINITY : idx;
|
|
2514
|
+
};
|
|
2515
|
+
return [
|
|
2516
|
+
...props
|
|
2517
|
+
].sort(({ name: a }, { name: b }) => rank(a.toString()) - rank(b.toString()));
|
|
2518
|
+
}, [
|
|
2519
|
+
schema,
|
|
2520
|
+
sort
|
|
2521
|
+
]);
|
|
2522
|
+
const handleChange = useCallback17((name, value3) => {
|
|
2523
|
+
onValuesChanged?.({
|
|
2524
|
+
...values,
|
|
2525
|
+
[name]: value3
|
|
2526
|
+
});
|
|
2527
|
+
}, [
|
|
2528
|
+
values,
|
|
2529
|
+
onValuesChanged
|
|
2530
|
+
]);
|
|
2531
|
+
return /* @__PURE__ */ React21.createElement(React21.Fragment, null, properties.map((property) => {
|
|
2532
|
+
const name = property.name.toString();
|
|
2533
|
+
const path = pathPrefix ? `${pathPrefix}.${name}` : name;
|
|
2534
|
+
if (visible && !visible(path, values)) {
|
|
2535
|
+
return null;
|
|
2536
|
+
}
|
|
2537
|
+
const entry = fieldMap?.[name];
|
|
2538
|
+
return /* @__PURE__ */ React21.createElement(SettingsFieldItem, {
|
|
2539
|
+
key: name,
|
|
2540
|
+
path,
|
|
2541
|
+
property,
|
|
2542
|
+
value: values[name],
|
|
2543
|
+
onChange: (value3) => handleChange(name, value3),
|
|
2544
|
+
readonly,
|
|
2545
|
+
customField: typeof entry === "function" ? entry : void 0,
|
|
2546
|
+
nestedFieldMap: typeof entry === "object" ? entry : void 0,
|
|
2547
|
+
visible,
|
|
2548
|
+
sort
|
|
2549
|
+
});
|
|
2550
|
+
}));
|
|
2551
|
+
};
|
|
2552
|
+
SettingsFieldSet.displayName = "Settings.FieldSet";
|
|
2553
|
+
var SettingsFieldItem = ({ property, path, value: value3, onChange, readonly, customField, nestedFieldMap, visible, sort }) => {
|
|
2554
|
+
const { type } = property;
|
|
2555
|
+
const name = property.name.toString();
|
|
2556
|
+
const title = getAnnotation3(SchemaAST5.TitleAnnotationId)(type) ?? String3.capitalize(name);
|
|
2557
|
+
const description = getAnnotation3(SchemaAST5.DescriptionAnnotationId)(type);
|
|
2558
|
+
if (customField) {
|
|
2559
|
+
const CustomField = customField;
|
|
2560
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2561
|
+
title,
|
|
2562
|
+
description
|
|
2563
|
+
}, /* @__PURE__ */ React21.createElement(CustomField, {
|
|
2564
|
+
value: value3,
|
|
2565
|
+
onChange,
|
|
2566
|
+
readonly
|
|
2567
|
+
}));
|
|
2568
|
+
}
|
|
2569
|
+
const fieldType = detectFieldType(type);
|
|
2570
|
+
switch (fieldType) {
|
|
2571
|
+
case "struct":
|
|
2572
|
+
return /* @__PURE__ */ React21.createElement(SettingsFieldSet, {
|
|
2573
|
+
schema: {
|
|
2574
|
+
ast: type
|
|
2575
|
+
},
|
|
2576
|
+
values: value3 ?? {},
|
|
2577
|
+
onValuesChanged: onChange,
|
|
2578
|
+
readonly,
|
|
2579
|
+
fieldMap: nestedFieldMap,
|
|
2580
|
+
visible,
|
|
2581
|
+
sort,
|
|
2582
|
+
pathPrefix: path
|
|
2583
|
+
});
|
|
2584
|
+
case "boolean":
|
|
2585
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2586
|
+
title,
|
|
2587
|
+
description
|
|
2588
|
+
}, /* @__PURE__ */ React21.createElement(Input13.Switch, {
|
|
2589
|
+
disabled: readonly,
|
|
2590
|
+
checked: !!value3,
|
|
2591
|
+
onCheckedChange: (checked) => onChange(!!checked)
|
|
2592
|
+
}));
|
|
2593
|
+
case "select": {
|
|
2594
|
+
const options = getSelectOptionsFromAst(type) ?? [];
|
|
2595
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2596
|
+
title,
|
|
2597
|
+
description
|
|
2598
|
+
}, /* @__PURE__ */ React21.createElement(Select2.Root, {
|
|
2599
|
+
disabled: readonly,
|
|
2600
|
+
value: value3 == null ? "" : globalThis.String(value3),
|
|
2601
|
+
onValueChange: (selected) => {
|
|
2602
|
+
const matched = options.find((option) => globalThis.String(option.value) === selected);
|
|
2603
|
+
onChange(matched?.value ?? selected);
|
|
2604
|
+
}
|
|
2605
|
+
}, /* @__PURE__ */ React21.createElement(Select2.TriggerButton, {
|
|
2606
|
+
disabled: readonly
|
|
2607
|
+
}), /* @__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, {
|
|
2608
|
+
key: globalThis.String(option.value),
|
|
2609
|
+
value: globalThis.String(option.value)
|
|
2610
|
+
}, option.label ?? globalThis.String(option.value)))), /* @__PURE__ */ React21.createElement(Select2.Arrow, null)))));
|
|
2611
|
+
}
|
|
2612
|
+
case "string":
|
|
2613
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2614
|
+
title,
|
|
2615
|
+
description
|
|
2616
|
+
}, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
|
|
2617
|
+
disabled: readonly,
|
|
2618
|
+
value: value3 ?? "",
|
|
2619
|
+
onChange: (event) => onChange(event.target.value)
|
|
2620
|
+
}));
|
|
2621
|
+
case "number":
|
|
2622
|
+
return /* @__PURE__ */ React21.createElement(SettingsItem, {
|
|
2623
|
+
title,
|
|
2624
|
+
description
|
|
2625
|
+
}, /* @__PURE__ */ React21.createElement(Input13.TextInput, {
|
|
2626
|
+
disabled: readonly,
|
|
2627
|
+
type: "number",
|
|
2628
|
+
value: value3 ?? "",
|
|
2629
|
+
onChange: (event) => {
|
|
2630
|
+
if (event.target.value === "") {
|
|
2631
|
+
onChange(void 0);
|
|
2632
|
+
return;
|
|
2633
|
+
}
|
|
2634
|
+
const parsed = Number(event.target.value);
|
|
2635
|
+
onChange(Number.isNaN(parsed) ? void 0 : parsed);
|
|
2636
|
+
}
|
|
2637
|
+
}));
|
|
2638
|
+
default:
|
|
2639
|
+
return null;
|
|
2640
|
+
}
|
|
2641
|
+
};
|
|
2642
|
+
|
|
2643
|
+
// src/components/Settings/Settings.tsx
|
|
2644
|
+
var SETTINGS_ROOT_NAME = "Settings.Root";
|
|
2645
|
+
var SETTINGS_VIEWPORT_NAME = "Settings.Viewport";
|
|
2646
|
+
var SETTINGS_SECTION_NAME = "Settings.Section";
|
|
2647
|
+
var SettingsRoot = ({ children, classNames }) => {
|
|
2648
|
+
return /* @__PURE__ */ React22.createElement("div", {
|
|
2649
|
+
className: mx4("flex flex-col gap-2", classNames)
|
|
2650
|
+
}, children);
|
|
2651
|
+
};
|
|
2652
|
+
SettingsRoot.displayName = SETTINGS_ROOT_NAME;
|
|
2653
|
+
var SettingsViewport = composable3(({ children, ...props }, forwardedRef) => {
|
|
2654
|
+
return /* @__PURE__ */ React22.createElement(ScrollArea2.Root, {
|
|
2655
|
+
...composableProps3(props),
|
|
2656
|
+
orientation: "vertical",
|
|
2657
|
+
centered: true,
|
|
2658
|
+
thin: true,
|
|
2659
|
+
ref: forwardedRef
|
|
2660
|
+
}, /* @__PURE__ */ React22.createElement(ScrollArea2.Viewport, {
|
|
2661
|
+
classNames: "px-4 pointer-coarse:px-2"
|
|
2662
|
+
}, /* @__PURE__ */ React22.createElement("div", {
|
|
2215
2663
|
role: "none",
|
|
2216
|
-
className: "
|
|
2664
|
+
className: "dx-document flex flex-col gap-2 py-4"
|
|
2217
2665
|
}, children)));
|
|
2666
|
+
});
|
|
2667
|
+
SettingsViewport.displayName = SETTINGS_VIEWPORT_NAME;
|
|
2668
|
+
var SettingsSection = ({ title, description, children }) => {
|
|
2669
|
+
const { t } = useTranslation11(translationKey13);
|
|
2670
|
+
return /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement("h2", {
|
|
2671
|
+
className: "px-trim-md mt-trim-md text-xl"
|
|
2672
|
+
}, toLocalizedString2(title, t)), description && /* @__PURE__ */ React22.createElement("p", {
|
|
2673
|
+
className: "px-trim-md text-description"
|
|
2674
|
+
}, toLocalizedString2(description, t)), /* @__PURE__ */ React22.createElement("div", {
|
|
2675
|
+
className: "w-full pt-trim-md space-y-trim-md"
|
|
2676
|
+
}, children));
|
|
2218
2677
|
};
|
|
2219
|
-
|
|
2678
|
+
SettingsSection.displayName = SETTINGS_SECTION_NAME;
|
|
2220
2679
|
var Settings = {
|
|
2221
2680
|
Root: SettingsRoot,
|
|
2681
|
+
Viewport: SettingsViewport,
|
|
2222
2682
|
Section: SettingsSection,
|
|
2223
|
-
|
|
2224
|
-
Group: SettingsGroup,
|
|
2225
|
-
GroupButton: SettingsGroupButton,
|
|
2226
|
-
Container: SettingsContainer,
|
|
2227
|
-
Frame: SettingsFrame,
|
|
2228
|
-
FrameItem: SettingsFrameItem,
|
|
2683
|
+
Panel: SettingsPanel,
|
|
2229
2684
|
Item: SettingsItem,
|
|
2230
|
-
|
|
2685
|
+
FieldSet: SettingsFieldSet
|
|
2686
|
+
};
|
|
2687
|
+
|
|
2688
|
+
// src/components/Settings/SettingsSelectField.tsx
|
|
2689
|
+
import React23 from "react";
|
|
2690
|
+
import { Select as Select3 } from "@dxos/react-ui";
|
|
2691
|
+
var createSelectField = ({ options, defaultLabel = "Default" }) => {
|
|
2692
|
+
const normalized = options.map((option) => typeof option === "string" ? {
|
|
2693
|
+
value: option,
|
|
2694
|
+
label: option
|
|
2695
|
+
} : option);
|
|
2696
|
+
const hasDefault = defaultLabel !== null;
|
|
2697
|
+
const sentinel = hasDefault ? `__default__${Math.random().toString(36).slice(2)}` : "";
|
|
2698
|
+
return ({ value: value3, onChange, readonly }) => /* @__PURE__ */ React23.createElement(Select3.Root, {
|
|
2699
|
+
disabled: readonly,
|
|
2700
|
+
value: value3 ?? sentinel,
|
|
2701
|
+
onValueChange: (next) => onChange(hasDefault && next === sentinel ? void 0 : next)
|
|
2702
|
+
}, /* @__PURE__ */ React23.createElement(Select3.TriggerButton, {
|
|
2703
|
+
disabled: readonly
|
|
2704
|
+
}), /* @__PURE__ */ React23.createElement(Select3.Portal, null, /* @__PURE__ */ React23.createElement(Select3.Content, null, /* @__PURE__ */ React23.createElement(Select3.Viewport, null, hasDefault && /* @__PURE__ */ React23.createElement(Select3.Option, {
|
|
2705
|
+
value: sentinel
|
|
2706
|
+
}, defaultLabel), normalized.map((option) => /* @__PURE__ */ React23.createElement(Select3.Option, {
|
|
2707
|
+
key: option.value,
|
|
2708
|
+
value: option.value
|
|
2709
|
+
}, option.label ?? option.value))), /* @__PURE__ */ React23.createElement(Select3.Arrow, null))));
|
|
2231
2710
|
};
|
|
2232
2711
|
|
|
2233
2712
|
// src/components/ViewEditor/ViewEditor.tsx
|
|
2234
2713
|
import { RegistryContext } from "@effect-atom/atom-react";
|
|
2235
|
-
import * as
|
|
2714
|
+
import * as Array4 from "effect/Array";
|
|
2236
2715
|
import * as Match2 from "effect/Match";
|
|
2237
|
-
import * as
|
|
2238
|
-
import * as
|
|
2239
|
-
import
|
|
2240
|
-
import { Filter as Filter2, Format as Format5, Obj as
|
|
2716
|
+
import * as Option6 from "effect/Option";
|
|
2717
|
+
import * as Schema5 from "effect/Schema";
|
|
2718
|
+
import React24, { forwardRef as forwardRef2, useCallback as useCallback18, useContext, useImperativeHandle, useMemo as useMemo12, useState as useState7 } from "react";
|
|
2719
|
+
import { Entity as Entity2, Feed, Filter as Filter2, Format as Format5, Obj as Obj6, Query, QueryAST, Ref as Ref6 } from "@dxos/echo";
|
|
2720
|
+
import { View } from "@dxos/echo";
|
|
2241
2721
|
import { EchoSchema, isMutable, toJsonSchema } from "@dxos/echo/internal";
|
|
2242
|
-
import { invariant } from "@dxos/invariant";
|
|
2243
|
-
import { useObject } from "@dxos/react-client/echo";
|
|
2244
|
-
import {
|
|
2722
|
+
import { invariant as invariant3 } from "@dxos/invariant";
|
|
2723
|
+
import { useObject, useQuery as useQuery2 } from "@dxos/react-client/echo";
|
|
2724
|
+
import { IconButton as IconButton4, Input as Input14, Message, useTranslation as useTranslation12 } from "@dxos/react-ui";
|
|
2245
2725
|
import { QueryForm } from "@dxos/react-ui-components";
|
|
2246
2726
|
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) => {
|
|
2727
|
+
import { ParentLabelAnnotation, ProjectionModel, VIEW_FIELD_LIMIT, createEchoChangeCallback, getTypenameFromQuery } from "@dxos/schema";
|
|
2728
|
+
import { mx as mx5, osTranslations as osTranslations2, subtleHover as subtleHover2 } from "@dxos/ui-theme";
|
|
2729
|
+
import { translationKey as translationKey14 } from "#translations";
|
|
2730
|
+
var __dxlog_file5 = "/__w/dxos/dxos/packages/ui/react-ui-form/src/components/ViewEditor/ViewEditor.tsx";
|
|
2731
|
+
var ViewEditor = /* @__PURE__ */ forwardRef2(({ classNames, schema, view, mode = "schema", registry, db, readonly, showHeading = false, types, tags, onQueryChanged, onDelete }, forwardedRef) => {
|
|
2253
2732
|
const atomRegistry = useContext(RegistryContext);
|
|
2254
2733
|
const schemaReadonly = !isMutable(schema);
|
|
2255
|
-
const { t } =
|
|
2256
|
-
const projectionModel =
|
|
2734
|
+
const { t } = useTranslation12(translationKey14);
|
|
2735
|
+
const projectionModel = useMemo12(() => {
|
|
2257
2736
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2258
2737
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2259
2738
|
const model = new ProjectionModel({
|
|
@@ -2272,12 +2751,26 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2272
2751
|
projectionModel
|
|
2273
2752
|
]);
|
|
2274
2753
|
const queueTarget = Match2.value(view.query.ast).pipe(Match2.when({
|
|
2275
|
-
type: "
|
|
2276
|
-
}, ({
|
|
2277
|
-
|
|
2754
|
+
type: "from"
|
|
2755
|
+
}, ({ from }) => {
|
|
2756
|
+
if (from._tag !== "scope") {
|
|
2757
|
+
return void 0;
|
|
2758
|
+
}
|
|
2759
|
+
return Option6.fromNullable(from.scope.queues).pipe(Option6.flatMap((queues) => Array4.head(queues)), Option6.map(String), Option6.getOrUndefined);
|
|
2278
2760
|
}), Match2.orElse(() => void 0));
|
|
2279
|
-
const
|
|
2280
|
-
|
|
2761
|
+
const feeds = useQuery2(db, Filter2.type(Feed.Feed));
|
|
2762
|
+
const targetRef = useMemo12(() => {
|
|
2763
|
+
if (!queueTarget) {
|
|
2764
|
+
return void 0;
|
|
2765
|
+
}
|
|
2766
|
+
const feed = feeds.find((feed2) => Feed.getQueueDxn(feed2)?.toString() === queueTarget);
|
|
2767
|
+
return feed ? Ref6.fromDXN(Entity2.getDXN(feed)) : void 0;
|
|
2768
|
+
}, [
|
|
2769
|
+
queueTarget,
|
|
2770
|
+
feeds
|
|
2771
|
+
]);
|
|
2772
|
+
const viewSchema = useMemo12(() => {
|
|
2773
|
+
const base = Schema5.Struct({
|
|
2281
2774
|
query: mode === "schema" ? Format5.URL.annotations({
|
|
2282
2775
|
title: "Record type"
|
|
2283
2776
|
}) : QueryAST.Query.annotations({
|
|
@@ -2285,26 +2778,27 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2285
2778
|
})
|
|
2286
2779
|
});
|
|
2287
2780
|
if (mode === "tag") {
|
|
2288
|
-
return
|
|
2781
|
+
return Schema5.Struct({
|
|
2289
2782
|
...base.fields,
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2783
|
+
// TODO(wittjosiah): Replace Type.Feed with Dataset.Dataset when Ref.Ref supports unions.
|
|
2784
|
+
target: Ref6.Ref(Feed.Feed).pipe(Schema5.annotations({
|
|
2785
|
+
title: "Target Feed"
|
|
2786
|
+
}), ParentLabelAnnotation.set(true), Schema5.optional)
|
|
2787
|
+
}).pipe(Schema5.mutable);
|
|
2294
2788
|
}
|
|
2295
|
-
return base.pipe(
|
|
2789
|
+
return base.pipe(Schema5.mutable);
|
|
2296
2790
|
}, [
|
|
2297
2791
|
mode
|
|
2298
2792
|
]);
|
|
2299
|
-
const viewValues =
|
|
2793
|
+
const viewValues = useMemo12(() => ({
|
|
2300
2794
|
query: mode === "schema" ? getTypenameFromQuery(view.query.ast) : view.query.ast,
|
|
2301
|
-
target:
|
|
2795
|
+
target: targetRef
|
|
2302
2796
|
}), [
|
|
2303
2797
|
mode,
|
|
2304
2798
|
view.query.ast,
|
|
2305
|
-
|
|
2799
|
+
targetRef
|
|
2306
2800
|
]);
|
|
2307
|
-
const fieldMap =
|
|
2801
|
+
const fieldMap = useMemo12(() => mode === "tag" ? customFields({
|
|
2308
2802
|
types,
|
|
2309
2803
|
tags
|
|
2310
2804
|
}) : void 0, [
|
|
@@ -2312,48 +2806,46 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2312
2806
|
types,
|
|
2313
2807
|
tags
|
|
2314
2808
|
]);
|
|
2315
|
-
const handleUpdate =
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2809
|
+
const handleUpdate = useCallback18((values) => {
|
|
2810
|
+
const targetValue = values.target;
|
|
2811
|
+
let queueDxn;
|
|
2812
|
+
if (Ref6.isRef(targetValue)) {
|
|
2813
|
+
const feedDxn = targetValue.dxn.toString();
|
|
2814
|
+
const feed = feeds.find((feed2) => Obj6.getDXN(feed2).toString() === feedDxn);
|
|
2815
|
+
if (feed) {
|
|
2816
|
+
queueDxn = Feed.getQueueDxn(feed)?.toString();
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
const query = mode === "schema" ? Query.select(Filter2.typename(values.query)).ast : JSON.parse(JSON.stringify(values.query));
|
|
2820
|
+
onQueryChanged?.(query, queueDxn);
|
|
2320
2821
|
}, [
|
|
2321
2822
|
onQueryChanged,
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
mode
|
|
2823
|
+
mode,
|
|
2824
|
+
feeds
|
|
2325
2825
|
]);
|
|
2326
|
-
const handleDelete =
|
|
2327
|
-
|
|
2328
|
-
F: __dxlog_file3,
|
|
2329
|
-
L: 155,
|
|
2330
|
-
S: void 0,
|
|
2331
|
-
A: [
|
|
2332
|
-
"!readonly",
|
|
2333
|
-
""
|
|
2334
|
-
]
|
|
2335
|
-
});
|
|
2826
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2827
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 127, S: void 0, A: ["!readonly", ""] });
|
|
2336
2828
|
onDelete?.(fieldId);
|
|
2337
2829
|
}, [
|
|
2338
2830
|
onDelete,
|
|
2339
2831
|
readonly
|
|
2340
2832
|
]);
|
|
2341
|
-
return /* @__PURE__ */
|
|
2833
|
+
return /* @__PURE__ */ React24.createElement("div", {
|
|
2342
2834
|
role: "none",
|
|
2343
|
-
className:
|
|
2344
|
-
}, schemaReadonly && !readonly && /* @__PURE__ */
|
|
2835
|
+
className: mx5(classNames)
|
|
2836
|
+
}, schemaReadonly && !readonly && /* @__PURE__ */ React24.createElement(Message.Root, {
|
|
2345
2837
|
valence: "info",
|
|
2346
|
-
classNames: "
|
|
2347
|
-
}, /* @__PURE__ */
|
|
2838
|
+
classNames: "my-form-padding"
|
|
2839
|
+
}, /* @__PURE__ */ React24.createElement(Message.Title, null, t("system-schema.description"))), /* @__PURE__ */ React24.createElement(Form.Root, {
|
|
2348
2840
|
schema: viewSchema,
|
|
2349
2841
|
values: viewValues,
|
|
2350
2842
|
fieldMap,
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
}, /* @__PURE__ */
|
|
2354
|
-
label: t("fields
|
|
2843
|
+
db,
|
|
2844
|
+
onValuesChanged: handleUpdate
|
|
2845
|
+
}, /* @__PURE__ */ React24.createElement(Form.FieldSet, null), /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2846
|
+
label: t("fields.label"),
|
|
2355
2847
|
asChild: true
|
|
2356
|
-
}), /* @__PURE__ */
|
|
2848
|
+
}), /* @__PURE__ */ React24.createElement(FieldList, {
|
|
2357
2849
|
schema,
|
|
2358
2850
|
view,
|
|
2359
2851
|
registry,
|
|
@@ -2365,9 +2857,9 @@ var ViewEditor = /* @__PURE__ */ forwardRef3(({ classNames, schema, view, mode =
|
|
|
2365
2857
|
var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDelete }) => {
|
|
2366
2858
|
const atomRegistry = useContext(RegistryContext);
|
|
2367
2859
|
const schemaReadonly = !isMutable(schema);
|
|
2368
|
-
const { t } =
|
|
2860
|
+
const { t } = useTranslation12(translationKey14);
|
|
2369
2861
|
const [viewSnapshot] = useObject(view);
|
|
2370
|
-
const projectionModel =
|
|
2862
|
+
const projectionModel = useMemo12(() => {
|
|
2371
2863
|
const jsonSchema = schema instanceof EchoSchema ? schema.jsonSchema : toJsonSchema(schema);
|
|
2372
2864
|
const change = createEchoChangeCallback(view, schema instanceof EchoSchema ? schema : void 0);
|
|
2373
2865
|
const model = new ProjectionModel({
|
|
@@ -2382,38 +2874,22 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2382
2874
|
schema,
|
|
2383
2875
|
view
|
|
2384
2876
|
]);
|
|
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
|
-
});
|
|
2877
|
+
const [expandedField, setExpandedField] = useState7();
|
|
2878
|
+
const handleAdd = useCallback18(() => {
|
|
2879
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 183, S: void 0, A: ["!readonly", ""] });
|
|
2396
2880
|
const field = projectionModel.createFieldProjection();
|
|
2397
2881
|
setExpandedField(field.id);
|
|
2398
2882
|
}, [
|
|
2399
2883
|
projectionModel,
|
|
2400
2884
|
readonly
|
|
2401
2885
|
]);
|
|
2402
|
-
const handleToggleField =
|
|
2886
|
+
const handleToggleField = useCallback18((field) => {
|
|
2403
2887
|
setExpandedField((prevExpandedFieldId) => prevExpandedFieldId === field.id ? void 0 : field.id);
|
|
2404
2888
|
}, [
|
|
2405
2889
|
readonly
|
|
2406
2890
|
]);
|
|
2407
|
-
const handleDelete =
|
|
2408
|
-
|
|
2409
|
-
F: __dxlog_file3,
|
|
2410
|
-
L: 234,
|
|
2411
|
-
S: void 0,
|
|
2412
|
-
A: [
|
|
2413
|
-
"!readonly",
|
|
2414
|
-
""
|
|
2415
|
-
]
|
|
2416
|
-
});
|
|
2891
|
+
const handleDelete = useCallback18((fieldId) => {
|
|
2892
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 196, S: void 0, A: ["!readonly", ""] });
|
|
2417
2893
|
if (fieldId === expandedField) {
|
|
2418
2894
|
setExpandedField(void 0);
|
|
2419
2895
|
}
|
|
@@ -2423,36 +2899,28 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2423
2899
|
onDelete,
|
|
2424
2900
|
readonly
|
|
2425
2901
|
]);
|
|
2426
|
-
const handleMove =
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
L: 246,
|
|
2430
|
-
S: void 0,
|
|
2431
|
-
A: [
|
|
2432
|
-
"!readonly",
|
|
2433
|
-
""
|
|
2434
|
-
]
|
|
2435
|
-
});
|
|
2436
|
-
Obj4.change(view, (v) => {
|
|
2902
|
+
const handleMove = useCallback18((fromIndex, toIndex) => {
|
|
2903
|
+
invariant3(!readonly, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file5, L: 207, S: void 0, A: ["!readonly", ""] });
|
|
2904
|
+
Obj6.update(view, (view2) => {
|
|
2437
2905
|
const fields = [
|
|
2438
|
-
...
|
|
2906
|
+
...view2.projection.fields
|
|
2439
2907
|
];
|
|
2440
2908
|
const [moved] = fields.splice(fromIndex, 1);
|
|
2441
2909
|
fields.splice(toIndex, 0, moved);
|
|
2442
|
-
|
|
2910
|
+
view2.projection.fields = fields;
|
|
2443
2911
|
});
|
|
2444
2912
|
}, [
|
|
2445
2913
|
view,
|
|
2446
2914
|
readonly
|
|
2447
2915
|
]);
|
|
2448
|
-
const handleClose =
|
|
2449
|
-
const handleHide =
|
|
2916
|
+
const handleClose = useCallback18(() => setExpandedField(void 0), []);
|
|
2917
|
+
const handleHide = useCallback18((fieldId) => {
|
|
2450
2918
|
setExpandedField(void 0);
|
|
2451
2919
|
projectionModel.hideFieldProjection(fieldId);
|
|
2452
2920
|
}, [
|
|
2453
2921
|
projectionModel
|
|
2454
2922
|
]);
|
|
2455
|
-
const handleShow =
|
|
2923
|
+
const handleShow = useCallback18((property) => {
|
|
2456
2924
|
setExpandedField(void 0);
|
|
2457
2925
|
projectionModel.showFieldProjection(property);
|
|
2458
2926
|
}, [
|
|
@@ -2461,84 +2929,84 @@ var FieldList = ({ schema, view, registry, readonly, showHeading = false, onDele
|
|
|
2461
2929
|
if (!viewSnapshot) {
|
|
2462
2930
|
return null;
|
|
2463
2931
|
}
|
|
2464
|
-
return /* @__PURE__ */
|
|
2932
|
+
return /* @__PURE__ */ React24.createElement(List2.Root, {
|
|
2465
2933
|
items: viewSnapshot.projection.fields,
|
|
2466
|
-
isItem:
|
|
2934
|
+
isItem: Schema5.is(View.FieldSchema),
|
|
2467
2935
|
getId: (field) => field.id,
|
|
2468
2936
|
onMove: readonly ? void 0 : handleMove,
|
|
2469
2937
|
readonly
|
|
2470
|
-
}, ({ items: fields }) => /* @__PURE__ */
|
|
2938
|
+
}, ({ items: fields }) => /* @__PURE__ */ React24.createElement(React24.Fragment, null, showHeading && /* @__PURE__ */ React24.createElement("h3", {
|
|
2471
2939
|
className: "text-sm"
|
|
2472
|
-
}, t("field
|
|
2940
|
+
}, t("field-path.label")), /* @__PURE__ */ React24.createElement("div", {
|
|
2473
2941
|
role: "list",
|
|
2474
|
-
className:
|
|
2942
|
+
className: "grid grid-cols-[min-content_1fr_min-content_min-content_min-content]"
|
|
2475
2943
|
}, fields?.map((field) => {
|
|
2476
2944
|
const hidden = field.visible === false;
|
|
2477
|
-
return /* @__PURE__ */
|
|
2945
|
+
return /* @__PURE__ */ React24.createElement(List2.Item, {
|
|
2478
2946
|
key: field.id,
|
|
2479
2947
|
item: field,
|
|
2480
|
-
classNames:
|
|
2948
|
+
classNames: "grid grid-cols-subgrid col-span-5",
|
|
2481
2949
|
"aria-expanded": expandedField === field.id
|
|
2482
|
-
}, /* @__PURE__ */
|
|
2950
|
+
}, /* @__PURE__ */ React24.createElement("div", {
|
|
2483
2951
|
role: "none",
|
|
2484
|
-
className:
|
|
2485
|
-
}, /* @__PURE__ */
|
|
2952
|
+
className: mx5(subtleHover2, "grid grid-cols-subgrid col-span-5", "rounded-xs cursor-pointer min-h-10")
|
|
2953
|
+
}, /* @__PURE__ */ React24.createElement(List2.ItemDragHandle, {
|
|
2486
2954
|
disabled: readonly || schemaReadonly
|
|
2487
|
-
}), /* @__PURE__ */
|
|
2955
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemTitle, {
|
|
2488
2956
|
classNames: hidden && "text-subdued",
|
|
2489
2957
|
onClick: () => handleToggleField(field)
|
|
2490
|
-
}, field.path), /* @__PURE__ */
|
|
2491
|
-
label: t(hidden ? "show
|
|
2958
|
+
}, field.path), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2959
|
+
label: t(hidden ? "show-field.label" : "hide-field.label"),
|
|
2492
2960
|
"data-testid": hidden ? "show-field-button" : "hide-field-button",
|
|
2493
2961
|
icon: hidden ? "ph--eye-closed--regular" : "ph--eye--regular",
|
|
2494
2962
|
autoHide: false,
|
|
2495
2963
|
disabled: readonly || !hidden && projectionModel.getFields().length <= 1,
|
|
2496
2964
|
onClick: () => hidden ? handleShow(field.path) : handleHide(field.id)
|
|
2497
|
-
}), !readonly && /* @__PURE__ */
|
|
2498
|
-
label: t("delete
|
|
2965
|
+
}), !readonly && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(List2.ItemDeleteButton, {
|
|
2966
|
+
label: t("delete-field.label"),
|
|
2499
2967
|
autoHide: false,
|
|
2500
2968
|
disabled: readonly || schemaReadonly || viewSnapshot.projection.fields.length <= 1,
|
|
2501
2969
|
onClick: () => handleDelete(field.id),
|
|
2502
2970
|
"data-testid": "field.delete"
|
|
2503
|
-
}), /* @__PURE__ */
|
|
2971
|
+
}), /* @__PURE__ */ React24.createElement(List2.ItemIconButton, {
|
|
2504
2972
|
iconOnly: true,
|
|
2505
2973
|
variant: "ghost",
|
|
2506
|
-
label: t("toggle
|
|
2974
|
+
label: t("toggle-expand.label", {
|
|
2507
2975
|
ns: osTranslations2
|
|
2508
2976
|
}),
|
|
2509
2977
|
icon: expandedField === field.id ? "ph--caret-down--regular" : "ph--caret-right--regular",
|
|
2510
2978
|
onClick: () => handleToggleField(field),
|
|
2511
2979
|
"data-testid": "field.toggle"
|
|
2512
|
-
}))), expandedField === field.id && !readonly && /* @__PURE__ */
|
|
2980
|
+
}))), expandedField === field.id && !readonly && /* @__PURE__ */ React24.createElement("div", {
|
|
2513
2981
|
role: "none",
|
|
2514
|
-
className: "col-span-
|
|
2515
|
-
}, /* @__PURE__ */
|
|
2982
|
+
className: "col-span-full mt-1 mb-1 border border-separator rounded-md"
|
|
2983
|
+
}, /* @__PURE__ */ React24.createElement(FieldEditor, {
|
|
2516
2984
|
readonly: readonly || schemaReadonly,
|
|
2517
2985
|
registry,
|
|
2518
2986
|
projection: projectionModel,
|
|
2519
2987
|
field,
|
|
2520
2988
|
onSave: handleClose
|
|
2521
2989
|
})));
|
|
2522
|
-
})), !readonly && !expandedField && /* @__PURE__ */
|
|
2990
|
+
})), !readonly && !expandedField && /* @__PURE__ */ React24.createElement("div", {
|
|
2523
2991
|
role: "none",
|
|
2524
|
-
className: "
|
|
2525
|
-
}, /* @__PURE__ */
|
|
2992
|
+
className: "my-form-padding"
|
|
2993
|
+
}, /* @__PURE__ */ React24.createElement(IconButton4, {
|
|
2526
2994
|
icon: "ph--plus--regular",
|
|
2527
|
-
label: t("add
|
|
2995
|
+
label: t("add-property-button.label"),
|
|
2528
2996
|
onClick: handleAdd,
|
|
2529
2997
|
disabled: viewSnapshot.projection.fields.length >= VIEW_FIELD_LIMIT,
|
|
2530
|
-
classNames: "
|
|
2998
|
+
classNames: "w-full"
|
|
2531
2999
|
}))));
|
|
2532
3000
|
};
|
|
2533
3001
|
var customFields = ({ types, tags }) => ({
|
|
2534
3002
|
query: ({ type, readonly, label, getValue, onValueChange }) => {
|
|
2535
|
-
const handleChange =
|
|
3003
|
+
const handleChange = useCallback18((query) => onValueChange(type, query.ast), [
|
|
2536
3004
|
onValueChange
|
|
2537
3005
|
]);
|
|
2538
|
-
return /* @__PURE__ */
|
|
3006
|
+
return /* @__PURE__ */ React24.createElement(Input14.Root, null, /* @__PURE__ */ React24.createElement(FormFieldLabel, {
|
|
2539
3007
|
readonly,
|
|
2540
3008
|
label
|
|
2541
|
-
}), /* @__PURE__ */
|
|
3009
|
+
}), /* @__PURE__ */ React24.createElement(QueryForm, {
|
|
2542
3010
|
initialQuery: getValue(),
|
|
2543
3011
|
types,
|
|
2544
3012
|
tags,
|
|
@@ -2557,7 +3025,9 @@ export {
|
|
|
2557
3025
|
GeoPointField,
|
|
2558
3026
|
MarkdownField,
|
|
2559
3027
|
NumberField,
|
|
3028
|
+
ObjectForm,
|
|
2560
3029
|
ObjectPicker,
|
|
3030
|
+
ObjectProperties,
|
|
2561
3031
|
RefField,
|
|
2562
3032
|
SelectField,
|
|
2563
3033
|
SelectOptionField,
|
|
@@ -2567,16 +3037,18 @@ export {
|
|
|
2567
3037
|
TupleField,
|
|
2568
3038
|
ViewEditor,
|
|
2569
3039
|
cellClassesForFieldType,
|
|
3040
|
+
createSelectField,
|
|
3041
|
+
detectFieldType,
|
|
2570
3042
|
formatForDisplay,
|
|
2571
3043
|
formatForEditing,
|
|
2572
3044
|
getDefaultValue,
|
|
2573
3045
|
getFormProperties,
|
|
2574
3046
|
getRefProps,
|
|
3047
|
+
getSelectOptionsFromAst,
|
|
3048
|
+
omitHiddenFormFields,
|
|
2575
3049
|
omitId,
|
|
2576
3050
|
parseValue,
|
|
2577
3051
|
pathNotUniqueError,
|
|
2578
|
-
setValueEchoAware,
|
|
2579
|
-
translations,
|
|
2580
3052
|
useFormContext,
|
|
2581
3053
|
useFormFieldState,
|
|
2582
3054
|
useFormHandler,
|